Skip to content

docs: Expand EIP-7702 #428

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 64 additions & 3 deletions docs/wiki/research/account-abstraction/eip-7702.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,76 @@
The primary goal of EIP-7702 is to introduce a standardized framework that allows developers to create custom transaction validation logic. A new transaction type (Type 4) is introduced to secure and allow user-friendly wallet solutions, as well as innovative use cases that were previously not possible with the traditional account model. By abstracting the account logic, EIP-7702 aims to reduce the complexity of smart contract interactions and lower the barrier to entry for new users.

With this feature, users can set their address to be represented by a code of an existing smart contract. Type 4 transaction allows address owners to sign an authorization that sets their address to mimic a chosen smart contract.
With this EIP, users can opt in to programmable wallets that allow new features like transaction bundling, gasless transacting and custom asset access for alternative recovery schemes. It's another step towards [account abstraction](https://ethereum.org/roadmap/account-abstraction/) that improves user experience and security when interacting with Ethereum.
With this EIP, users can opt in to programmable wallets that allow new features like transaction bundling, gasless transacting and custom asset access for alternative recovery schemes. It's another step towards [account abstraction](https://ethereum.org/en/roadmap/account-abstraction/) that improves user experience and security when interacting with Ethereum.

Review `@lightclient's` technical deep dive:

<!-- markdownlint-disable-next-line MD033 -->
<iframe width="560" height="315" src="https://www.youtube.com/embed/_k5fKlKBWV4?si=Y4DehqLu5fpT7-a3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

other resources:
Although ERC-4337 introduces account abstraction, EIP-7702 serves a different purpose by providing externally owned accounts (EOAs) with temporary programmability. The benefits of introducing programmability to externally owned accounts (EOAs) include transaction batching, transaction sponsorship, privilege de-escalation and session keys, and social recovery.

Historically, EIP-7702 was introduced as a simpler alternative to the proposed EIP-3074, which would have added two new EVM instructions, AUTH and AUTHCALL. The primary motivation behind this "limited" proposal is to encourage users to transition towards Smart Wallets, as described in [ERC-4337](https://eips.ethereum.org/EIPS/eip-4337), and to create a unified interface from the dApp perspective. EIP-7702 represents a step toward native Account Abstraction and is fully compatible with existing Account Abstraction infrastructure, allowing components such as paymasters and bundlers to work seamlessly.

## Technical Details

In the Ethereum account model, the primary difference between contract accounts and externally owned accounts (EOAs) is that EOAs do not contain executable on-chain code; their code field is effectively set to null.
EIP-7702 proposes adding a new [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)-compatible transaction type that allows temporarily setting the code field for an EOA.
The new `TransactionType` is defined as `SET_CODE_TX_TYPE` (`0x04`).
The associated `TransactionPayload` is an RLP-serialized tuple containing the following fields:
`chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, value, data, access_list, authorization_list, signature_y_parity, signature_r, signature_s`, where the authorization must be a non-empty list of `chain_id, address, nonce, y_parity, r, s` tuples.
Here, the `address` refers to the address of the delegated contract code, and `chain_id` may be either a valid chain ID or 0, the `nonce` must match the EOA's nonce to provide replay protection and the `y_parity`, `r`, and `s` values are the ECDSA signature components signed by the `authority`.
Anyone can submit a transaction containing a valid authorization list — meaning the `tx.origin` does not have to be the EOA’s address, as long as the signature is valid. Setting the `chain_id` to `0` enables resubmission of the transaction across different chains, provided the nonce values match.
The `ReceiptPayload` is defined as the `status, cumulative_transaction_gas_used, logs_bloom, logs` tuple in RLP-seralized form.
More information about RLP encoding can be found in [this section](https://epf.wiki/#/wiki/EL/RLP).

When such a transaction is submitted the following steps are performed for each tuple in the `authorization_list`:
1. Basic validations are performed, such as verifying `chain_id < 2^256`, `len(auth.address) == 20` etc.. Additionally, the `chain_id` must either match the current chain's ID or be set to `0`.
2. Verify that the `nonce` is less than `2^64 - 1`.
3. The `authority` is recovered from the signature and the payload using the `ecrecover` method:
`authority = ecrecover(msg, y_parity, r, s).` where `msg = keccak(MAGIC || rlp([chain_id, address, nonce]))` and `s` must be less than `secp256k1n/2`.
4. The recovered `authority` is marked as a warm address and is added to the `accessed_addresses` set.
5. Verify that `nonce` is equal to nonce of `authority` if the `authority` exists in the trie otherwise `nonce` has to equal `0`.
6. If `authority` exists in the trie the refund amount of `PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST` is added to the global refund mechanism.
7. In case of a non-zero `address` the code of the authority is set to `0xef0100 || address` (where `||` denotes concatenation), otherwise the EOA's code is cleared and the code hash is set to the hash of a null address (`0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470`). This serves as a revocation mechanism.
8. The nonce of `authority` is incremented by one.

### Creation by template

Due to space optimization concerns, the traditional `initCode` is replaced by a "code pointer" mechanism, with initialization occurs during a regular call.
[EIP-3607](https://eips.ethereum.org/EIPS/eip-3607) specifies that an account with deployed code cannot originate transactions.
To work around this the `code` field is populated with a 23-byte value composed of a prefix and the delegated contract’s address.
The prefix is 3 bytes long:
- The first byte (`0xef`) is a banned opcode, as defined in [EIP-3541](https://eips.ethereum.org/EIPS/eip-3541).
- The following two bytes (`0x0100`) act as a 7702-specific designator.

### Opcode changes

Some reading and execution instructions are impacted by this design, including:
- [EXTCODESIZE](https://www.evm.codes/?fork=cancun#3b) will return 2, the length of `0xef01`
- [EXTCODEHASH](https://www.evm.codes/?fork=cancun#3f) will return `keccak256` hash of `0xef01`
- [EXTCODECOPY](https://www.evm.codes/?fork=cancun#3c) will return the bytes `0xef01`
- Execution instructions (`CALL`, `CALLCODE`, `STATICCALL`, `DELEGATEACLL`) will execute the code from the delegated contract address, but within the context of the EOA

### Gas costs

Each authorization tuple incurs a gas cost of 25,000 gas, calculated using the following formula:
```21000 + 16 * non-zero calldata bytes + 4 * zero calldata bytes + 1900 * access list storage key count + 2400 * access list address count```
This approach charges the maximum gas amount upfront. A partial refund of 12,500 gas is issued if the contract already exists, which happens through the global refund mechanism.

### Wallet and UX Changes

[EIP-7821](https://eips.ethereum.org/EIPS/eip-7821) proposes the creation of a batch executor interface for delegations, aiming to reduce the number of delegations required due to the associated risks and high gas costs.
A [proposed proxy pattern](https://gist.github.com/lightclient/7742e84fde4962f32928c6177eda7523) offers a minimal contract that EOAs can delegate to. This proxy contract then points to the user's wallet implementation. With this setup, when a user wants to upgrade their wallet, they can simply modify the proxy contract without the need to sign a costly EIP-7702 transaction.

## Resources

- [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)
- [EIP-7702 Discussion](https://ethereum-magicians.org/t/eip-7702-account-abstraction/)
- [EIP-7702 Homepage](https://eip7702.io/)
- [EIP-7702 Discussion](https://ethereum-magicians.org/t/eip-7702-set-eoa-account-code/19923)
- [Decoding 7702](https://medium.com/inception-capital/decoding-vitaliks-eip-7702-507c56f9f70c)
- [EIP-7702: A Deep Dive](https://hackmd.io/@colinlyguo/SyAZWMmr1x)
- [Recommended Proxy Pattern](https://gist.github.com/lightclient/7742e84fde4962f32928c6177eda7523)
- [Awesome EIP-7702](https://github.com/fireblocks-labs/awesome-eip-7702)
- [7702 Best Practices](https://hackmd.io/@rimeissner/eip7702-best-practices)

Loading