Overview
EIP-7702 gives superpowers to EOAs.
Specifically, it allows any EOA to set its code based on any existing smart contract. To do so, an EOA owner would sign an authorization that could then be submitted by anyone as part of the new transaction type. The code will be valid until replaced by another authorization. The authorization could be given for a single chain, or all chains at once.
This setup allows an EOA to mimic a smart contract account, particularly allowing transaction bundling, gas sponsorships, and custom permissioning schemes.
Motivation
Flexible
EIP-7702 offers some guardrails yet it is very flexible. Users can provide both single-chain and cross-chain authorizations, as well as choose what proxy to use. While most wallets would probably not allow the most flexible behavior, it still opens up a way for different vendors to experiment and innovate.
Compatible with EIP-4337
It is easy to use EIP-7702 with EIP-4337, so most of the infrastructure (e.g. paymasters, bundlers, RPC endpoints) would just work.
Compatible with existing smart accounts
As EIP-7702 allows an EOA to set its code directly and supports writing to storage, it should be possible with little to no effort to use existing smart account implementations.
Specification
The EIP introduces a new transaction, “set code transaction”, where the TransactionType
is 0x04
and the TransactionPayload
is the RLP serialization of the following:
rlp([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])
authorization_list = [[chain_id, address, nonce, y_parity, r, s], ...]
The authorization_list
is a list of tuples that store the address to code which the signer desires to execute in the context of their EOA.
The ReceiptPayload
for this transaction is rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])
.
Behavior
At the start of executing the transaction, for each [chain_id, address, nonce, y_parity, r, s]
tuple:
- Verify the chain id is either 0 or the chain’s current ID.
- Verify the
nonce
is less than2**64 - 1
. authority = ecrecover(keccak(0x05 || rlp([chain_id, address, nonce])), y_parity, r, s]
s
value must be less or equal thansecp256k1n/2
, as specified in EIP-2.
- Add
authority
toaccessed_addresses
(as defined in EIP-2929.) - Verify the code of
authority
is either empty or already delegated. - Verify the nonce of
authority
is equal tononce
. In caseauthority
does not exist in the trie, verify thatnonce
is equal to0
. - Add
PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST
gas to the global refund counter ifauthority
exists in the trie. - Set the code of
authority
to be0xef0100 || address
. This is a delegation designation.
- As a special case, if
address
is0x0000000000000000000000000000000000000000
do not write the designation. Clear the accounts code and reset the account’s code hash to the empty hash0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470
.
- Increase the nonce of
authority
by one.
If any of the above steps fail, immediately stop processing that tuple and continue to the next tuple in the list. It will in the case of multiple tuples for the same authority, set the code using the address in the last valid occurrence.
Note that the signer of an authorization tuple may be different than tx.origin
of the transaction.
If transaction execution results in failure (any exceptional condition or code reverting), setting delegation designations is not rolled back.