-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add EIP: Native Account Abstraction with EOF
Merged by EIP-Bot.
- Loading branch information
Showing
1 changed file
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
--- | ||
eip: 7701 | ||
title: Native Account Abstraction with EOF | ||
description: A variant of RIP-7560 transactions relying on EOF Smart Contract Accounts | ||
author: Vitalik Buterin (@vbuterin), Yoav Weiss (@yoavw), Alex Forshtat (@forshtat), Dror Tirosh (@drortirosh), Shahaf Nacson (@shahafn) | ||
discussions-to: https://ethereum-magicians.org/t/eip-7701-native-account-abstraction-with-eof/19893 | ||
status: Draft | ||
type: Standards Track | ||
category: Core | ||
created: 2024-05-01 | ||
requires: 3540 | ||
--- | ||
|
||
## Abstract | ||
|
||
This proposal describes a slight variation of the Native Account Abstraction design fully described in RIP-7560. | ||
This version's difference compared to the original proposal is in relying on features of "EVM Object Format" to | ||
distinguish between validation and execution code sections. | ||
|
||
## Motivation | ||
|
||
Talking about Full Native Account Abstraction, the fundamental idea any solution has to address is a | ||
mechanism for a Smart Contract Account to separate its validation and execution code sections. | ||
|
||
RIP-7560 is build on the current Ethereum contract structure, and therefore has little choice but to rely | ||
on using some higher-level abstraction. | ||
|
||
In its current form, RIP-7560 transactions use Solidity method selectors in order to achieve this separation. | ||
|
||
This, however, is far from ideal as this approach "leaks" the concept from a programming language widely used | ||
in the EVM into the core design of the Ethereum protocol. | ||
|
||
While there is no purely technical reason to disallow it and there are already instances of Solidity code | ||
being "enshrined" in the Ethereum protocol, e.g. the validator deposit contract, such violation of abstraction levels | ||
often lead to unnecessary technical debt and are worth avoiding if possible. | ||
|
||
Additionally, method selectors provide very weak indication of the contract developer's decision to become a | ||
participant in Native Account Abstraction transaction flow. | ||
The chance of accidentally exposing a function with a colliding 4 byte | ||
method identifier that returns a valid 4 byte magic to indicate approval is pretty low, but a malicious developer | ||
can easily hide such a function giving it an innocent name, making it hard to spot a Native Account Abstraction entity. | ||
|
||
This issue to some extent is also present in [ERC-4337](./eip-4337.md). | ||
|
||
As an alternative, if Native Account Abstraction is to be implemented in coordination with [EIP-3540](./eip-3540), | ||
relying on the concept of "code sections" it introduces is a superior approach. | ||
|
||
## Specification | ||
|
||
### System-level code entry points | ||
|
||
Modify the EOF container format to consist of the following sections: | ||
|
||
``` | ||
container := header, body | ||
header := | ||
magic, version, | ||
kind_types, types_size, | ||
kind_entrypoints, entrypoints_size, | ||
kind_code, num_code_sections, code_size+, | ||
[kind_container, num_container_sections, container_size+,] | ||
kind_data, data_size, | ||
terminator | ||
body := types_section, entrypoints_section, code_section+, container_section*, data_section | ||
types_section := (inputs, outputs, max_stack_height)+ | ||
entrypoints_section := (entrypoints_role, target_section_index, target_section_pc_offset)+ | ||
``` | ||
|
||
For regular calls to the contract, the execution always starts at the first byte of code section 0, and pc is set to 0. | ||
|
||
Here the `entrypoints_section` defines alternative indexes of code sections to start the execution for system calls. | ||
This is reserved for execution of special roles in the `entrypoints_role` range. | ||
|
||
Note: do not confuse code execution `entrypoint` with the `EntryPoint` contract defined in ERC-4337. | ||
|
||
### Validation and PostTransaction code entry points | ||
|
||
The contract that may have a role in an Account Abstraction transaction, either as a Sender, a Paymaster or a Deployer, | ||
has to contain a section marked with one of the following `entrypoints_role` marker: | ||
|
||
``` | ||
role_sender_execution = 0x0000 | ||
role_sender_deployment = 0x0001 | ||
role_sender_validation = 0x0002 | ||
role_paymaster_validation = 0x0003 | ||
role_paymaster_posttx = 0x0004 | ||
``` | ||
|
||
This section is equivalent to a code section. | ||
|
||
Its code can be executed during a regular transaction execution and has no special effects. | ||
If it is the first code section of a contract, it can act as an entry point during regular transaction execution. | ||
|
||
Only a single section per role is allowed in a contract. | ||
This rule is validated during contract creation. | ||
|
||
### Execution entry point for Account Abstraction transaction type participant entity (Sender, Paymaster and Deployer) | ||
|
||
During a regular contract code execution, its behaviour is defined as follows by EIP-3540: | ||
|
||
``` | ||
Execution starts at the first byte of code section 0, and pc is set to 0 | ||
``` | ||
|
||
However, if a contract is referenced in an `AA_TX_TYPE` transaction as a Sender, Paymaster or a Deployer, | ||
execution starts at the first byte of code section with the `entrypoints_role` marker corresponding to the current step, | ||
and `pc` is set to the corresponding `target_section_pc_offset`. | ||
|
||
If the specified contract does not contain such a section, or is not an EOF contract, the transaction is not valid. | ||
|
||
### Encoding inputs for different execution frames | ||
|
||
#### Sender Deployment | ||
|
||
Inputs to the `deployer` contract are not defined by the protocol and are controlled by the `deployerData` parameter. | ||
|
||
The sender deployment frame MUST result in the `sender` address becoming initialized with contract code. | ||
|
||
This step is performed with the `role_sender_validation` code section. | ||
|
||
#### Sender Validation | ||
|
||
Inputs to the `Sender` validation section are defined by the protocol as an SSZ encoding of the transaction data, | ||
excluding the `chainId` and `accessList` fields and with an extra field of the `txHash`: | ||
|
||
``` | ||
ssz([ | ||
subtype, | ||
sender, nonce, builderFee, | ||
callData, | ||
paymaster, paymasterData, | ||
deployer, deployerData, | ||
maxPriorityFeePerGas, maxFeePerGas, | ||
validationGasLimit, paymasterValidationGasLimit, | ||
callGasLimit, paymasterPostOpGasLimit | ||
signature, txHash | ||
] | ||
``` | ||
|
||
This step is performed with the `role_sender_deployment` code section. | ||
|
||
In order for the transaction to be considered valid the | ||
sender validation frame MUST return two 64-bit values: | ||
|
||
``` | ||
ssz(bool success, uint64 validUntil, uint64 validAfter) | ||
``` | ||
|
||
#### Paymaster Validation | ||
|
||
Inputs to the `Paymaster` validation section are same as the ones in the [Sender Validation](#sender-validation) step. | ||
|
||
This step is performed with the `role_paymaster_validation` code section. | ||
|
||
In order for the transaction to be considered valid the | ||
paymaster validation frame MUST return the following values: | ||
|
||
``` | ||
ssz(uint64 validUntil, uint64 validAfter, bytes context) | ||
``` | ||
|
||
#### Sender Execution | ||
|
||
This step is performed with the `role_sender_execution` code section. | ||
|
||
Inputs to the `Sender` contract are not defined by the protocol and are controlled by the `callData` parameter. | ||
|
||
#### Paymaster post-transaction frame | ||
|
||
Inputs to the `Paymaster` post-transaction are defined by the protocol as an SSZ encoding of the following data: | ||
|
||
``` | ||
ssz([uint256 actualGasCost, bool success, bytes context]) | ||
``` | ||
|
||
This step is performed with the `role_paymaster_posttx` code section. | ||
|
||
## Rationale | ||
|
||
### SSZ encoding for system frames' input and output data | ||
|
||
Using an SSZ encoding format for data provided by the protocol itself does represent an abstraction levels violation, | ||
however it is a relatively safe and any alternative solution would require some trade-offs. | ||
|
||
The validation section of a Smart Contract Account code needs to have full access to the majority of transaction | ||
details in order to be able to make an informed decision about either accepting or rejecting the transaction. | ||
|
||
A small subset of this data is available with the existing opcodes, however creating an opcode for every transaction | ||
parameter is not feasible. | ||
|
||
Allowing wallets to specify their own encoding for this data is also not feasible as Smart Contract Accounts must | ||
avoid any ambiguity about the meaning of the received data. | ||
|
||
## Backwards Compatibility | ||
|
||
An EOF contract with `kind_entrypoints` section is not valid according to EIP-3540 and cannot exist on-chain | ||
before this proposal is implemented. | ||
|
||
The introduction of `kind_entrypoints` will break an assumption that a contract code can only have a single | ||
execution starting point, which might confuse some developer tooling that relies on this assumption. | ||
|
||
## Security Considerations | ||
|
||
A contract with a `kind_entrypoints` section explicitly indicates its role as a Native Account Abstraction entity. | ||
This is a significant improvement over ERC-4337 and RIP-7560 where entities are not explicitly marked. | ||
|
||
As the `kind_entrypoints` code sections represent a generic way to authorize any action on behalf of the contract, | ||
correct and secure implementation of this code is critical. | ||
We expect compilers targeting EVM will play a major role in enabling and ensuring Smart Contract Accounts' security. | ||
|
||
## Copyright | ||
|
||
Copyright and related rights waived via [CC0](../LICENSE.md). |