eip | title | description | author | discussions-to | status | type | category | created |
---|---|---|---|---|---|---|---|---|
7702 |
Set EOA account code for one transaction |
Add a new tx type that sets the code for an EOA during one transaction execution |
Vitalik Buterin (@vbuterin), Sam Wilson (@SamWilsn), Ansgar Dietrichs (@adietrichs), Matt Garnett (@lightclient) |
Draft |
Standards Track |
Core |
2024-05-07 |
Add a new transaction type that adds a contract_code
field and a signature, and converts the signing account (not necessarily the same as the tx.origin
) into a smart contract wallet for the duration of that transaction. Intended to offer similar functionality to EIP-3074.
There is a lot of interest in adding short-term functionality improvements to EOAs, increasing the usability of applications and in some cases allowing improved security. Three particular applications include:
- Batching: allowing multiple operations from the same user in one atomic transaction. One common example is an ERC-20 approval followed by spending that approval, a common workflow in DEXes that requires two transactions today. Advanced use cases of batching occasionally involve dependencies: the output of the first operation is part of the input to the second operation.
- Sponsorship: account X pays for a transaction on behalf of account Y. Account X could be paid in some other ERC-20 for this service, or it could be an application operator including the transactions of its users for free.
- Privilege de-escalation: users can sign sub-keys, and give them specific permissions that are much weaker than global access to the account. For example, you could imagine a permission to spend ERC-20 tokens but not ETH, or to spend up to 1% of total balance per day, or to interact only with a specific application.
EIP-3074 solves all of these use cases. However, it has forward-compatibility concerns:
- It introduces two opcodes,
AUTH
andAUTHCALL
, that would have no use in an "endgame account abstraction" world where eventually all users are using smart contract wallets (which seems like it must happen eventually, at the least because eventually quantum computers will break the ECDSA that EOAs use) - It leads to the development of an "invoker contract" ecosystem that would be separate from the "smart contract wallet" ecosystem, leading to possible fragmentation of effort.
The purpose of this EIP is to enable all of the use cases of EIP-3074, without these two weaknesses.
The keywords “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
FORK_BLKNUM
=TBD
TX_TYPE
=TBD
MAGIC
=TBD
PER_CONTRACT_CODE_BASE_COST
=5000
As of FORK_BLOCK_NUMBER
, a new EIP-2718 transaction is introduced with TransactionType
= TX_TYPE(TBD)
.
The EIP-2718 TransactionPayload
for this transaction is
rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, data, access_list, [[contract_code, y_parity, r, s], ...], signature_y_parity, signature_r, signature_s])
The intrinsic cost of the new transaction is inherited from EIP-2930, specifically 21000 + 16 * non-zero calldata bytes + 4 * zero calldata bytes + 1900 * access list storage key count + 2400 * access list address count
. Additionally, we add a cost of 16 * non-zero calldata bytes + 4 * zero calldata bytes
over each contract_code
, plus PER_CONTRACT_CODE_BASE_COST
times the length of the contract_code
array.
At the start of executing the transaction, for each [contract_code, y_parity, r, s]
tuple:
- Let
signer = ecrecover(keccak(MAGIC + contract_code), y_parity, r, s]
. - Verify that the contract code of
signer
is empty. - Set the contract code of
signer
tocontract_code
.
At the end of the transaction, set the contract_code
of each signer
back to empty.
Note that the signer of any of the contract_code
signatures, and the tx.origin
of the transaction, are allowed to be different.
In this design, it requires fairly little work to convert an existing EIP-3074 workflow. Specifically, AUTH and AUTHCALL would get replaced by calls into the EOA. One way to do this is that the contract_code
would be a user wallet (which could be a DELEGATECALL
forwarder to save gas), and would expose two functions, verify
and execute
.
- AUTH would be replaced by a code to
verify
, which would use TSTORE to locally setauthorized[msg.sender, ...] = True
. - AUTHCALL would be replaced by a call to
execute
, which would use TLOAD to verifyauthorized[msg.sender, ...]
, and then execute from there.
Hence, there is a very simple transformation from "existing EIP-3074 workflows" into workflows under this new scheme.
This EIP is designed to be very forward-compatible with endgame account abstraction, without over-enshrining any fine-grained details of ERC-4337 or RIP-7560.
Specifically:
- The contract code that users would need to sign could literally be existing ERC-4337 wallet code.
- The "code pathways" that are used are code pathways that would, in many cases (though perhaps not all), continue to "make sense" in a pure-smart-contract-wallet world.
- Hence, it avoids the problem of "creating two separate code ecosystems", because to a large extent they would be the same ecosystem. There would be some workflows that require kludges under this solution that would be better done in some different "more native" under "endgame AA", but this is relatively a small subset.
- It does not require adding any opcodes, that would become dangling and useless in a post-EOA world.
- It allows EOAs to temporarily convert themselves into contracts to be included in ERC-4337 bundles, in a way that's compatible with the existing
EntryPoint
. - Once this is implemented, EIP-5003 is "only one line of code": just add a flag to not set the code back to empty at the end.
This EIP breaks the invariant that an account balance can only decrease as a result of transactions originating from that account. This has consequences for mempool design, and for other EIPs such as inclusion lists. However, these issues are common to any proposal that provides similar functionality, including EIP-3074.
Many security considerations with EIP-3074 are shared. Particularly, user wallets need to be very careful about which contract_code
they sign.
Copyright and related rights waived via CC0.