Frames are all you need
Devcon 8 · 4 Nov 2026 · 23:48
Lightclient, a go-ethereum developer, explains what to expect from EIP-8141 frame transactions, selected for the Hegóta hardfork. The talk walks through the general structure of a frame transaction, how the protocol processes it, and what new functionality the change brings to the protocol, with account abstraction and user experience in view.
Speakers
Topics
From Devcon 8, hosted by Ethereum Foundation.
Transcript
So, after the over the last 10 years in Ethereum, we've made a lot of significant changes to the transaction format. Starting even in 2016, we added the optional chain ID mechanism to prevent replay attacks across chains. In 2021, we added the access list to help unstuck funds that were affected by the storage cost increases. Later that year, we got rid of first-price auctions by adding the 1559 transaction object. In 2024, we added blobs to bring scaling to Ethereum. And then last year in 2025, we introduced 7702, which gives EOAs more you know, ability to execute code.
With each of these transaction changes that we made in Ethereum, we have to ship a hard fork that deliver the the these changes. And every time we deliver a hard fork, we have to spend endless amounts of time debating on the absolute perfect specification, implementing the transaction objects, and testing these transaction objects. And so with each hard fork, we ask ourselves this question, could this transaction type be the final transaction type for Ethereum? In parallel to all of these transaction objects that we've introduced into the protocol, in parallel, we've also been thinking a lot about what that ultimate transaction type could look like. And in the past 10 years, there's been four
pretty concrete proposals on what the ultimate Ethereum transaction might be. With each of these transaction proposals, we've learned new things, and we've come away understanding more, but none of them have been the complete solution. So, with 7701, one of the latest proposals for this, there was a lot of surface area of disagreement. And if you've been part of all core dev us for any time, or listen to any of the allcore devs meetings, you know that as if there's ever any surface area to disagree, the core devs will absolutely find places to disagree on.
And we also found that with the you know, with the envelope that 7701 provided, even if we wanted to add more features to it in the future, many times we would still have to deliver a new hard fork to add that specific feature to the transaction object. So earlier this year there was this idea that maybe instead of decide instead of defining this static enshrined life cycle up front in the protocol, what if we instead allow the users to define that life cycle?
That's the spirit of Ethereum, programmability. And so what we did was we created a set of building blocks that are simple and allow the user to define the life cycle themselves. And we found that you could actually replicate the flow of 7701 with these basic building blocks, as well as creating your own interesting flows. And the nice thing is that if you're doing something simple, you don't need to bring the entire enshrined flow with you. You can bring just a couple frames to do basic operations.
And whenever you give people the ability to program and innovate, then we find that there's a lot of different things that people can create. And we were surprised to see like all of the types of things that you can build on top of these basic building blocks, such as adding expiry to your transactions without needing further changes to the transaction object. And so that's really the origin story of EIP 8141, the frame transaction object. So if you're not familiar with 8141 at all, it's the scheduled headliner for Bogota, which is going to be the Ethereum upgrade for next year.
Uh if you look at the upper part of the frame transaction, it It a lot of different uh fields that you might be familiar with if you've looked at the Ethereum transaction objects a lot. You have your chain ID, your nonce, the signatures, fees, blobs, all stuff that looks pretty familiar. But the bottom half is where the innovation really comes through. And this is where we introduce the concept of frames, which is a list of EVM calls. If we dig into the frame object itself, it consists of six different values. The mode, the flags, the targets, the limits, the value, and the data.
Because each frame instantiates the EVM, the modes dictate what type of EVM environment you're executing. If you execute a default mode frame, then you have a pretty basic EVM call frame. The origin is set to some sentinel value, but otherwise it's a pretty standard execution. The verify frame mode is used to actually validate your transaction. This is where the sender is able to execute code to determine whether or not they actually approve of the execution that the transaction is going to do.
Then the sender frame is a permission frame where we allow the sender of the transaction to actually originate calls from their account to transfer tokens or make trades. Then we have the flags, which are an extension point adding special per mode behaviors to be used in combination with the frame modes. The target kind of mapping to your typical concept of a transaction.to value. And then the limits, which is the list of gas limits consumed by the frame transaction. A couple other things that frames provide are per frame receipts. This is a commonly requested feature that we've gotten from many of the different batching standards that have been proposed in the past.
And maybe one final point is that the frame object finally gives us great introspection over what the user is trying to do in their transaction. And if you know anything about account abstraction, you probably know that implementing account abstraction in the protocol isn't always the most complicated part. Typically, the most complicated part is safely propagating these transactions through a public mempool. And one thing that's made it difficult in the past for doing this is we've always had trouble from the protocol's perspective understanding what is the user doing, and can we safely propagate these transactions?
So, I think that this is one of the missing keys that help us make AAs safe and flexible enough for layer layer one. So, now I'll quickly walk through a simple example. Uh say we want to make a basic transfer, transferring ETH or ERC-20 tokens. The way that this would look like look in frames is that you would have two frames. First, you have the verify mode frame, which does the validation of the transaction. It's basically determining did the user sign a message saying that they want to transfer a token? Does this transaction fit within their access policies that they might have installed into their account?
If the policies pass and the transaction appears valid from the perspective of the user's account, then they can move on to the execution, and that's the sender frame, which allows the user to originate the call from their account. And so, that will execute in this case the transfer of the ETH or the ERC-20 tokens. The way I think about these two different frames is I think of them as two different phases of the transaction. First, you have the validation phase. This is the phase of the transaction where we're still validating if the transaction is going to even be considered valid or not.
Um this is what gets executed when you're propagating a transaction across the mempool. And both of these phases can have more than one frame in it. We're looking at like a very simple example now, but you could imagine a prefix of frames in this validation phase. At some point, the validation phase concludes, and the transaction decides whether or not it's valid or not. And then they invoke this operation called approve, and then you move into the execution phase. The execution phase is kind of your standard EVM execution. That's where you make your your trades, you transfer your tokens, you make your deposits. And again, the execution phase can also consist of multiple different frames.
So, the primary goal of this talk is to try to convince you that frames are really a powerful mechanism and they're flexible enough to continue meeting our needs for years to come. The combination of this like list and list construction, the modes and flags that make adding new items in the future easier, uh you know, ability to arrange frames and however the user wants, these are things that we believe can lead us into the future, uh you know, all the future goals that we have of Ethereum without always needing to make hard forks for every single change.
So, to try and make this concrete, I want to walk through four different examples using different techniques to extend the frame transaction. Some of these will require in protocol changes, others can be done outside the protocol. So, the first one we'll look at is transaction expiry. If we start again with our basic two-frame transfer that we looked at a second ago, uh we basically want to add some functionality to say whether or not this transaction should be considered valid at some point in time. And so, we can say that at some timestamp, after some timestamp, the transaction will no longer be considered valid. So, naively the solution most people would probably jump to is that well, we can just change the code that
this verify frame is calling. That's the user's account code, the user controls their account code. It would be pretty straightforward for us just to add an extra hook into the user account to check the timestamp. With frames, it's actually even simpler. You don't need to change the user accounts at all. All you need to do is append a frame onto the beginning of the transaction, and the target of that frame would go to some expiry contract, and the data for that frame would just be the expiry time. So, this is nice in the sense that the user doesn't need to change any code in their wallets, and the protocol has great introspection about the validity constraints of that transaction. We can now reason about is this transaction going to be valid in the next five minutes or not? Is it safe for me to propagate to my peers?
So this actually already exists in EIP-8141 as it is specified today and we expect this feature to go live with EIP-8141 in the Hegota hard fork sometime next year. So the next example I want to talk about is batching. Obviously, we can't have an account abstraction standard unless we talk about how batching works. So going back to our list of frames that we've constructed, suppose that the sender wants to do more than just transfer some tokens. Say they want to add some trades on there or some deposits with some tokens they got out of a trade.
We can do that simply by just appending more frames onto the end of our list of frames. Now, if you are familiar with batching, you might say, "Well, what if I want one of my frames to depend on the other frames being successful?" This is what we would call atomicity and we can also have this just as easily. Using this flag mechanism that exists in the frames object, we have the ability at the protocol level to say whether or not this transaction whether or not these frames in this transaction should be part of an atomic batch or not. And so then the protocol can reason about knowing if one of the frames fails, none of the frames none of the effects of the other frames in the batch should be recorded.
And this too is currently implemented in the specification for EIP-8141 and we also expect that this functionality to go live with the EIP in Hegota. So then let's move on to transaction assertions. So transaction assertions maybe you're not the most familiar with like what this concept is, so I can quickly explain that. The goal of the transaction assertions comes from a lot of user interviews that we did trying to understand how can we make people feel more confident about using Ethereum? How can we improve the security or the least the sense of security of Ethereum? And a lot of users kept telling us that they aren't that confident when they sign a transaction that the transaction is going to do exactly what they expect it to do. And so we had this idea that it would if you
could make an assertion in the transaction and sign that assertion and execute that assertion on chain, it would be much much more confidence inspiring to the user to be certain that only the effects that they intended to happen intend happened and then no other effects happened. So to do this kind of requires a new instruction because you need to be able to introspect what's happening in the transaction. And this is kind of privileged privileged access and so we wanted to constrain the environment in which users might be able to use this this new op code.
And so the idea that we had is that looking again at our list of frames, suppose we wanted to assert that you know this batch of frames only does only has some side effects and no other side effects. What we can do is append this assert frame onto the end of our frames and this assert frame can call some assertion runtime which might process the data this like list of assertions that the user signed. And these assertions we can present at the time of signing in their hardware wallet and they can visually verify that only the certain only the tokens they wanted to transfer are transferring, only the trades that they wanted to happen are happening. And so they know with 100% certainty when this transaction ends up
on chain either what they wanted to happen will happen or the transaction will revert. And the only side effect of a reverted transaction will be the bumped nonce and paying for the gas. So this right now is it defined in the EIP 7906. It's currently considered for inclusion for Hergota and because it's such an important feature we're optimistic it's going to get included sometime next year alongside the frames transaction. So the last example I want to talk about is I want to try to give an idea about how post-quantum crypto might be integrated into the frame transaction.
So, with post-quantum crypto, uh we could probably do it fairly simply. We could just add another frame at the beginning of the transaction, and we could say, "Call some precompile and verify this proof." The proof being that the user has signed a message saying that they agree that this transaction is valid and can be originated from their account. And we could probably call this a complete end of the day. But if you know anything about post-quantum crypto, you might say, "Well, this proof is actually really big." And in this Sphinx construction, this proof is actually like 4 kilobytes. And if we're talking about hundreds, maybe thousands of transactions per block, it's a lot of proofs to be propagating
with every single block. And so, really what we want to do is we want to find a way to aggregate all of these user proofs together. So, with this proof frame, what we can do is we can say that unlike the other frame objects that exist, we can say that the data inside the proof frame is not introspectable by the EVM. And that's really the key point, because if the if the data is introspectable by the EVM at all, then we always have to propagate that data alongside the transaction, because the EVM execution actually relies on the data.
But in general, with signatures, we don't care about the actual signature data. All we care about is the signa-is the cryptographic guarantee that the pub key associated signed a certain message. And so, what we could do is we can actually take the whole proof data out of the frame, put a reference to the proof in, and then we can combine it with a whole bunch of other proofs from the block. And we can construct one single proof that that basically approves all of the different proofs that exist in the block. And so, this is kind of the idea with this uh proof frame mode, and it's basically what's defined in this EIP 8288. You might have seen Vitalik post a few tweets about this EIP in the past few weeks, and this is an idea that that
we're pretty confident is going to be the way that the execution layer will have aggregatable post quantum transactions. Right now, we're planning on proposing it for the I-star hard fork, which will be the hard fork after Hogota. So, zooming back out to the frame transaction, we've kind of been able to see how we can use, you know, modes to introduce new uh new in environments to execute and add things like transaction assertions, add these uh aggregatable proofs.
We saw how flags give us the ability to add these atomicity indicators for batches. And we saw how the target and the data give us the ability to introspect what an individual frame might be doing. And so, it's this combination of all these techniques that has led me to believe that frames are all you need. Thank you. >> All right, thank you. That was an excellent talk.
Uh let's take some questions. Uh remember to scan the QR code and add your questions or uh upvote questions that you like. So, the first question is um So, the first question is, why do L2s not want to adopt frames? Can you still man their argument and counter argue against it? >> Yeah, so if you're not familiar, there's been a lot of debates between L1 all core devs and layer two uh rollups trying to decide like what's the best way to do account abstraction. And one of the common complaints with with the frames format is that the frames format is too flexible and too abstract.
And it's difficult for these extremely high performance chains to support such an abstract transaction object. And so, what their proposal has generally been is to essentially create a white list of cryptographic schemes that they are going to support on their layer two, and then not allow or allow custom schemes in a much slower format. And for me on L1, I feel that it's best for us to offer the most abstract primitives to let users build whatever they need to build. And so for that reason, I've proposed you know, continuing along with frames rather than going with some of these more L2 focused standards.
>> Okay. Thank you. So, the next question is what's your most interesting potential use case of frames that you have imagined? >> So, I find the that a transaction assertions to me are one of the most interesting potential use cases because I also feel for the users that we interviewed trying to understand like how to make Ethereum feel more secure. So, I'd probably say transaction assertions. I did write a blog post also titled the same as this talk, frames are all unique, a couple months ago. And one idea that I had in that was that we could add a sweep mode to the transaction. And so
I'm sure everyone who sent a transaction knows you always leave way behind. It's very difficult to actually like have your transaction perfectly line up to spend all of your way. And so this sweep mode kind of allows you to send a transaction where you don't have to specify the exact value. It just calculates the remaining remaining value after all the gas costs are paid and moves it to a different account. I think that's an interesting potential future addition to frames. >> Okay. So, the next question is how does a frame transaction allow senders that are not ECDSA keys?
>> Yeah, so the nice thing about frames is that, you know, it's very it's defined very abstractly. You have your validation phase and then you have your execution phase. And in the validation phase, you can do whatever you want to do. You are given a full EVM environment to do execution. There's a constant in the EIP called max verify gas. And so that's the maximum amount of gas that we would allow you to use in that verify in that validation phase in the public mem pool. But as long as you can do your cryptographic verification inside that max verify gas, you can implement any kind of cryptographic protection for your account that you want. And in the future we hope to make this a much larger value so that we can easily support things, you know, even as
you know, exotic as ZK proofs in the public mem pool as part of the validation phase. >> Okay. The next question is how does assertions work with aggregation? If the transaction includes frames from different users, would assertions look into each other's frames? >> Yes, so there's two different parts of this question and so when we're talking when I was talking about aggregation in this presentation, I'm talking about aggregating proofs. And so when we talk about aggregating proofs, we're not actually aggregating other user operations into the same transaction. So if you're familiar with 4337, you might have maybe multiple user ops in the same
transaction. So that we're not talking about here. We're talking about just aggregating proofs. And for that, there's not really this like concern about you know, how assertions would interact with other users frames because all we're doing is you know, making the commitment that this cryptographic validation was correct without having the entire proof for it. >> Okay, the next one is about parallel execution of frames. Is it similar to BL?
>> Yeah, so the validation phase where we're looking at is with 8288, we're kind of moving into this world where these frames we can actually treat them as independent you know, pure verifications. And when you look at it from this like independent pure mode, then there's no reason that any of these transactions are running in an a linear fashion. There's no specific dependencies that they have. And so in that world, it's very easy for us to execute them in parallel or potentially prove them all and then aggregate them so that you don't have to execute them at all.
>> Okay. I guess we have few more minutes. Um so what is your opinion on alt mempool versus a canonical mempool? >> So my opinion on alt mempool versus canonical mempools is the same opinion that I have across a lot of different ideas that exist in Ethereum. I think that one of the most valuable assets that we have in Ethereum are the people who are running nodes and the node software. Being able to integrate something into these, you know, these nodes that have 10,000 users gives us a really robust back peer-to-peer backbone. And so I think that the canonical mempool is an extremely robust system that has a lot of capacity a lot of altruistic
capacity. And I think with the alt mempool and like other types of similar ideas, uh I need to see like how are you going to get equivalent numbers of users in those peer-to-peer networks.