I think we could simplify your “two” modes proposal to having the new EXECUTE mode just look at the frame sender to determine who it sends from. The ENTRY_POINT address can be used as the frame sender at any time, but using any other frame sender then follows the current SENDER frame rules.
To me a big use case for DEFAULT frames is to deploy a new account/identity, and then use that new account for authentication in the next frame. This allows account setup to happen along with a desired user action in single transaction, which is great UX.
For your group revert approach, are you requiring the groups to in only increasing order? Consider
A | 1
B | 2
C | 1
If C reverts, and reverts the state changes of A, what if B depends on A’s changes? (And even more fun, what C depends on B)
I feel like the payments part of your ideas adds too much magic. The current proposal lets the transaction be inspected to see who could be going to pay, without executing the transaction. That’s worth keeping.
just look at the frame sender to determine who it sends from
I don’t think the frame sender is specified, only the mode, target, gas_limit, data?
To me a big use case for DEFAULT frames is to deploy a new account/identity
I think you can deploy new accounts / identities with an EXECUTE frame before the sender has verified (which would come from entry point)? As you describe.
For your group revert approach, are you requiring the groups to in only increasing order?
Yep, groups must be strictly monotonic.
I feel like the payments part of your ideas adds too much magic. The current proposal lets the transaction be inspected to see who could be going to pay
The payer is still clear from the transaction data under my proposal - it’s the target of the last VERIFY frame (because as per the current spec, if a VERIFY frame doesn’t call approve, the whole transaction is invalid, and under my proposal the last VERIFY frame determines the payer)
8141 seems like we are moving towards requiring standard account implementations which has a set of validation methods defined (ie. P256 etc). This will be the only way to enable native like performance for tx validation. Reason being, when a tx comes in we have no way of knowing what the validation frame is going to do so we MUST simulate with 7562 with a gas limit. The alternative for 8141 is to have some sort of native account and check the codehash (or codehash + proxy slot) to both enable native performance and remove DoS risks.
On the revert approach for erc20 payments - 8130 defines call phases which, once they complete are “committed” + not revertible. This enables payers to lock in their payment as they dont care what occurs afterwards. I agree on grouping and have considered adding that, main thing being gas refunds. Thinking for gas however, it felt that refunds aren’t as needed, especially with scaling or L2s. This also means there is a single gas limit.
8130 can be considered the stripped down frame option + adds a layer of indirection for account validation via verifiers. It has an optional execute frame against the account configuration contract (deployment, key updates) then 1-2 validation frames against verifiers (sender + payer) then a batch of batches of calls (each batch being committed). Note that verifiers can be made native independently of wallet code as the wallet bytecode and verifier logic is decoupled.
8141 seems like we are moving towards requiring standard account implementations which has a set of validation methods defined (ie. P256 etc). This will be the only way to enable native like performance for tx validation. Reason being, when a tx comes in we have no way of knowing what the validation frame is going to do so we MUST simulate with 7562 with a gas limit. The alternative for 8141 is to have some sort of native account and check the codehash (or codehash + proxy slot) to both enable native performance and remove DoS risks.
On the revert approach for erc20 payments - 8130 defines call phases which, once they complete are “committed” + not revertible. This enables payers to lock in their payment as they dont care what occurs afterwards. I agree on grouping and have considered adding that, main thing being gas refunds. Thinking for gas however, it felt that refunds aren’t as needed, especially with scaling or L2s. This also means there is a single gas limit.
8130 can be considered the stripped down frame option + adds a layer of indirection for account validation via verifiers. It has an optional execute frame against the account configuration contract (deployment, key updates) then 1-2 validation frames against verifiers (sender + payer) then a batch of batches of calls (each batch being committed). Note that verifiers can be made native independently of wallet code as the wallet bytecode and verifier logic is decoupled.
Curious on take on standard wallet bytecode in this audience.
I expect mempools to adopt a very similar approach if 8141 is adopted:
optional default frame to standard account factory
With current Ethereum transaction types, you have two different ways of using the same ERC-7702 account. You can send to the account address (transaction to field) and execute code at that address, or you can send transactions that are from that account (transaction from field), and just use signature based transaction. It’s fine for an account to both enable extra features for a specific wallet while also being backwards compatible with EOA style signatures.
However, in the current version of EIP-8141, once an account has EIP-7702 delegated to it, the frame transaction EOA signature evaluation no longer works, since that is conditional on empty code / delegation on that account.
Perhaps it makes sense to have the frame transaction use of EOA signature handling explicitly marked in the VERIFY frame? Or some kind of VERIFYSIG frame?
An additional thing missing from porting the 8130 spec is the ability to update accepted signers in the pre verify frames. Currently 8141 only has deployment as a pre-verify frame with these rules.
This is a concern for cross chain accounts as there needs to be a replay mechanism to bring the wallet up to date in a single tx (outlined in 8130).
For 8130 the deploy/sync frame is standardized (always to the account configuration contract) - which brings us back to potentially wanting some cannonical wallet bytecode if trying to replicate this in 8141 as the sync mechanism must now be sent to a wallet address without the ability to delegate validation.
This is a big big step forwards for Frame Transactions. Clearly defining baseline mempool inclusion behavior and specifying a capped amount of gas to evaluate inclusion was critical.
It looks like EOA address are currently NOT allowed to be transaction payers if they are not also authorizating the sender? It would seem like EOA’s would be okay to pay, since they are allowed to pay if they are both paying and authorizing the transaction.
In the list of acceptance criteria for a transaction:
pay must execute in VERIFY mode, must target an account whose runtime code exactly matches the canonical paymaster implementation, and must successfully call APPROVE(0x1).
Yes, an EOA being able to pay for another EOA’s transaction is good.
Can Monad support enough of Frame Transactions to be worth supporting?
Now that EOA accounts can be used as signers in frame transactions, there’s a clear subset of the frame transaction spec that Monad could support. However, the frame transaction minimum implementation is still out of reach for a blockchain with asynchronous execution.
A core goal of frame transactions appears to be enabling transaction inclusion and authorization to be controlled from a stateful smart contract inside the blockchain, rather than only from signatures from outside the chain.
Traditional transactions gate inclusion on the payer having signed off and being able to pay (both verifiable only using account state). The actual execution of the included transaction may then revert after being included, but inclusion itself has very simple criteria. However, Monad style asynchronous execution means that smart contract state cannot be known at the time transactions are included into a block. Thus while we could indeed use the canonical paymaster contract to handle the payment authorization, the inclusion is still also gated by the authorization’s frame EVM execution which can’t be known at inclusion time.
So Monad is left with a possible spec subset that provides EOA transactions with separate payer support and batched transaction actions. Those are good features, and I’ve personally needed them for years.
As long as we think that enough wallets will end up supporting this subset without requiring the rest of frame transaction spec to be present, vs wallets supporting another transaction type, then using a frame transaction subset is worth considering for Monad.
When using built in EOA signature validation in a frame transaction the underlying smart contract should NOT be called. This ensures compatibility with the current behavior of 7702 accounts on traditional transactions, as well as identical cross chain behavior on EOA accounts when a chain can’t call into a contract to verify the transaction. It also means that the outcome clearly matches the intent of the transaction.
I still think frame transactions are a poor long-term choice for Ethereum:
Async execution allows a chain to make nearly 100% of wall clock time available for execution. This would be amazing for Ethereum’s goal of supporting high validator counts on low end hardware. It’s sad to make that future much harder to happen.
The implementation effort vs benefit tradeoff does not look favorable to me for frame transactions vs simplified tempo transactions.
Smart contracts as the authorization layer feel painful to use in practice vs having the authorization layer built into the chain.
On the positive side:
With EOA support and defined rules for mempool inclusion, I think frame transaction will be used and useful on Ethereum.
Hi Daniel, by this are you referring to the EOA default code? It’s indeed the intention that the default code isn’t real EVM code but rather just defined client behavior, so the client wouldn’t be calling any underlying smart contract.
Async execution allows a chain to unlock nearly 100% of wall clock time for execution. This would be amazing for Ethereum’s goal of supporting high validator counts on low end hardware. It’s sad to make that future much harder to happen.
Are there any EIPs or other resources where I can read more about how Ethereum might implement async execution? I’m not familiar with that line of work so I’d appreciate pointers. We certainly wouldn’t want frames to be incompatible with any important future optimizations.
The problem is that the signature handling / “default code” is currently spaced to only run if there is no delegation present on the account.
Currently with old transactions if a transaction is signed “from” the account with the 7702 delegation, then the transaction signature handling takes over, and the transaction runs “from” the 7702 account, rather than using the code. With the current frame transaction spec, once a contract is set on an account via 7702, you can no longer use the signature handling to send from that account, everything is routed to the code.
The monad version of async exection is simpler, lower latency, and gives more execution time as percentage of block time than the ethereum proposal, but that’s downstream of some other architectural choices.
I’ll also be giving a talk at EthCC on April 1st on the concept of asynchronous execution.
I have a question related to the motivation to not have a “VALUE” property for the frame. In the EIP it only says `It is not required because the account code can send value.`. We were thinking how to implement an account and got excited that frames basically allow us not to have a execute method on the account code, we would always use the `SENDER` frame (i.e. for a token transfers the target would be the token and the data the encoded transfer). But since we are lacking a value field, this is not possible. Therefore for us a VALUE field would be quite valuable.
Another question is related to the result of a frame, currently it is only possible to get the status, it would be beneficial to also allow loading the return data.
The general argument in favor is that this enables accounts to focus purely on verification and is also aligned with allowing the use of signature precompiles as account code.