EIP-7701: Native Account Abstraction with EOF

One of the issues that arises from enshrining an ERC-4337: Account Abstraction Using Alt Mempool design in Ethereum is its reliance on Solidity method signatures and ABI-encoding that is not a native part of the EVM.

This EIP is a variant of RIP-7560: Native Account Abstraction that solves these issues by the means of extending the EOF format.

3 Likes

A bit late reviewing this, but itā€™s been because EOF v1 has been solidifying. With that in mind I have some comments and suggestions with the EOF portions of the PR.

  • Remove target_section_pc_offset and require all sections to start at PC=0 within the code section

My reasoning for this relates to the code validaiton within EOF, itā€™s only intended to start with a single entry point at zero. If code can enter at multiple entry points significant portions of stack validation need to be reconsidered, and that feels like too much for this EIP, in addition to needing a separate skill set to evaluate.

  • Reconsider specifying ssz encoding of data

Clients are not yet mandated to implement, but more importantly robust solidity libraries handling SSZ do not exist yet, and the efficiency of SSZ in the EVM is an open question. This is an issue that may be overcome in time, but I donā€™t think Native AA is the correct place to find out. Right now the Solidity ABI is much better ingrained in the ecosystem and will result in less friction when it comes to adoption.

The following 2 suggestions are to allow Native AA to use the EOF features without embedding the AA aspects into the EOF spec, and provide a generic reusable facility for other uses.

  • Consider 4 bytes for entrypoint_role, and assign names based on ABI selectors

Expanding this to 4 bytes makes arbitrary mappings a bit less arbitrary, and preserves two future design spaces: multiple possible signatures for entry point actions, and secondarily possibly expanding it to a general case ā€œselectorā€ mode that EOF can deploy, where solidity can dispense with the occasionally large switching logic for function dispatch. This also helps decouple AA logic from the EVM.

  • Consider adding a ā€œflagsā€ field in entrypoints_section entries.

Some drafts of various AA proposals have imposed more restrictions on the kinds of operations that a function may perform, such as prohibiting all block info access in sender validation calls. An extra flags field will provide signaling into the EVM so that EOF can perform that validation as part of EOF validation. This further decouples AA logic from the EVM otherwise specific validations would be tied to specific types which would then require EVM updates when new or different validations are requested.

2 Likes

Thank you for your review! Sorry on my part for a late response. We have made significant progress implementing RIP-7560 and, hopefully, it will have some production use by the time EOF is merged and EIP-7701 becomes our main focus.

I have made changes to EIP-7701, mostly implementing your suggestions.
You can see the PR with the recent changes here:

However, I do have a couple of questions about them:

  1. You have mentioned the ā€œselectorā€ mode for EOF.
    Is this something that is currently on a roadmap for EOF? I could not find this feature described anywhere, and native AA could greatly benefit from using a standard EVM-level dispatch.
    I assume EIP-7701 would have little chance of getting accepted with its own dispatch logic when there are plans to introduce a system-wide solution. Do you think it makes sense for us to propose a general EVM ā€œselectorā€, for instance, as a separate EIP that is a prerequisite to EIP-7701?

  2. Regarding the flags field for entrypoints_section entries, would we have to define the full set of possible flags as part of this EIP? Currently, I am not sure I know what are the flags we may need in the future, so I assumed we would need a new EIP for each new flag, right?

  3. Regarding the ABI encoding for the data necessary during the transaction validation, one alternative we discussed and are still considering is creating one or a small number of ā€œtransaction getterā€ opcodes that would provide the missing EIP-7701 transaction fields. Would you consider such a direction to be more or less consistent with the direction of the EOF?

2 Likes
  1. Selector mode. I havenā€™t published any of my ideas for post EOF right now to keep focus on 1.0. I have a talk at devcon where I will disuss some of my ideas. It would be a general EVM selector. It would basically switch out what the entry code section is.
    If the section is presentā€¦
  • Input data less than 4 bytes enters at section zero
  • if there is an entry in the table matching the first 4 bytes of input data, that index + 1 is the entry section
  • If non match, section zero is the entry
  • the table must be sorted, so you can do a binary search.
  • 4 byte selectors are meant to match solidity function selectors.
  1. Iā€™m not sure if we need flags. There are bytes we can use in the type section if needed. A new EIP for each flag.

  2. I would prefer system contracts (precompiles) to peek data out from the transaciton. Opcode space is getting crowded with opcodes that sometimes lose meaning in rollups and other applications such as off-chain compute.

Iā€™d like to better understand the main goal of this proposal. Is it to:

  1. have account validation and execution code sections be inaccessible from within the EVM,
  2. dispatch AA methods in-protocol (direct jump into code section) rather than with EVM code, or
  3. avoid enshrining Solidity ABI encoding in the protocol?

The last point is the one that the EIP highlights the most in Motivation but it actually seems secondary.

Separately, is SSZ easy/efficient to decode in EVM?

I think there are two related proposals.

  1. The 7701 proposal proposes a means where the native AA entry points would be inaccessible unless explicitly exposed.
  2. The other proposal is to enshrine 4 byte function dispatch into the EVM, which is typical of all solidity compiled contracts.

These two proposals occupy a lot of the same design space, which is why I am trying to get them combined. Unless the AA entrypoints need to have the option of being inaccessible I see a lot of value in making them look, act, and smell like regular solidity function calls.

There is a lot of backwards compatibility gained when using non-EOF Smart Contract Account Wallets by keeping the functionality accessible via a standard call (in addition to enshrined calls). The question is whether we want to enable AA accounts to fail when not being used with enshrined abstraction.

My question was mainly about the current EIP-7701 proposal. I wanted to make sure I understood the main problems this EIP is addressing. I think that can also help to understand if it makes sense to combine those two proposals. At least from the current text in the EIP it seems like avoiding Solidity ABI encoding is a main goal.

I hadnā€™t read the previous discussion until now.

I see we brought up a similar point, though I think Iā€™m more open to considering SSZ. Even though Solidity ABI is in widespread use, itā€™s very inefficient in terms of space, so a replacement at some point or in some cases could be good.

Iā€™m not a fan of enshrining this in the EVM. Iā€™m not at all convinced that 4-byte selectors are the best ABI design. Thereā€™s been concrete proposals that go in other directions, for example using smaller selectors to optimize calldata use for common methods. With RJUMPV it might make sense to use sequential selectors since theyā€™re so easy to dispatch.

Iā€™ve been looking at the potential efficiency of SSZ in EVM. I think the main source of inefficiency is that SSZ is little-endian and needs conversion to big-endian in EVM. I think the rest can be done efficiently, but endianness may be a dealbreaker.

1 Like

Our projectā€™s high level goal is to enable full account abstraction, which includes abstracted validation, in the least opinionated way while maintaining DoS resistance.

The minimum requirement to achieve that is to separate the validation and execution steps. We also want to leave some freedom to build practical AA protocols on top of EIP-7701 by applying their choice of rules on the validation code to maintain DoS resistance.

EIP-7701 can be used for permissionless AA protocols like ERC-4337, which is our main goal.
However, it can be used to enable different models as well, both centralized and decentralized. For instance, it could also be used by permissioned intent-solvers that donā€™t apply any restrictions, but do sponsor gas for their users and handle DoS mitigation at their centralized RPC service.

So, I would not describe the main goal of EIP-7701 as a simple in-protocol dispatch mechanism to replace solidity functions.
It is a mechanism to define and assign protocol-level roles to contracts. These roles are taken by contracts who implement the appropriate methods, and calls to these methods and their effects have special meaning to the protocol.
We also define a pair of such roles: ā€œaccountā€ and ā€œpaymasterā€.

For example, a contract becomes an account if it has a validation code section.
The validation code section of an account:

  1. cannot be called or accessed externally within the EVM, but only as part of an EIP-7701 transaction type validation (it is ā€œcalledā€ and executed by a protocol)
  2. a transaction with a revert in the validation section call cannot be included in the block
  3. a successful call to the validation code means the transaction is in fact valid (and the account can be charged for its gas)

These rules can be attached to Solidity functions by name, which is what we did in RIP-7560.
However, this required a number of compromises and using EOF code sections with some AA dispatching seemed to be more suitable for Ethereum post-EOF.
Regarding the SSZ encoding, it has now been removed.

The data needed by the validation section will probably be provided as an ABI encoding, but this part is not final and we do not have any strong feelings about it.
The options we have discussed as a mechanism to deliver the transaction information are:

  1. Provided as a calldata with either ABI encoding or any other more efficient encoding
  2. An opcode or a set of opcodes to do the same (similar to ORIGIN, GASPRICE, etc.)
  3. A precompile contract that returns the details of the current EIP-7701 transaction

Each of these options has its pros and cons and any feedback is appreciated.

2 Likes

A fourth option is to use a combination of stack elements and calldata. In particular, single-word values would be provided to the entry point directly on the stack, and variable-length values provided in calldata. For sender validation, there are three variable-length values that would be concatenated in calldata, so you would need to include some extra information on the stack like the offset and length of each one, or just the two offsets where one ends and another starts.

This removes the need to do ABI encoding or decoding.

1 Like

More thoughts on the fourth option. While using the stack for inputs seems feasible (to me at least), using the stack for outputs seems incompatible with the RETURN opcode.

1 Like