RIP-7712: Enable RIP-7560 transactions using a two-dimensional nonce
An RIP-7560 transaction modification that allows Smart Contract Accounts to define their own transaction sequencing
Abstract
An RIP-7560 transaction modification that replaces the existing nonce-based sequencing mechanism of Ethereum with an on-chain pre-deployed contract in order to provide Smart Contract Accounts with the flexibility they need to support some advanced use cases.
Motivation
The traditional nonce-based system provides guarantees of transaction ordering and replay protection, but does so at the expanse of configurability. Accounts are not able to express their intentions like "allow these three transactions to be mined in whatever order" or "these two sets of transactions must have separate sequential nonces".
However, with Smart Contract Accounts this creates a bottleneck for some use-cases. For example, Smart Contract Accounts designed to be operated by multiple participants simultaneously, will require these participants to coordinate their transactions to avoid invalidating each other.
Another example when this can also be a limitation is a case where there are separate execution flows. A configuration change may require multiple participants to co-sign a transaction but a regular operation does not. With sequential nonces, all operations will have to be halted until the configuration change is executed.
Having a more agile ordering and replay protection system will significantly improve the user experience with RIP-7560.
Additionally, this change is required for the Native Account Abstraction to achieve feature parity and compatibility with ERC-4337, as all ERC-4337 Smart Contract Accounts already use the solution described below.
Specification
Non-sequential nonce support
We propose an introduction of a separate 2-dimensional nonce
value used when contracts initiate a transaction.
The nonce
parameter of the transaction is to be interpreted as uint192 key || uint64 seq
value.
The contract account nonce is then defined as a mapping address account => uint192 key => uint64 seq
.
This approach guarantees unique transaction nonce and hash but removes the requirement of nonces being sequential
numbers.
This nonce
is exposed to the EVM in a NonceManager
pre-deployed contract located at the AA_NONCE_MANAGER
address.
The nonce
is validated and incremented on-chain before the rest of the validation code.
The old nonce
account parameter use
The old 64-bit nonce
account parameter is used when the key
of the AA_TX_TYPE
transaction's nonce
is set to 0.
Notice that this also prevents the previously signed transactions from becoming valid again.
The old nonce
account parameter remains in use for transactions initiated by EOAs and for the CREATE
opcode.
It is not incremented when sender
makes the AA_TX_TYPE
transaction.
Nonce validation frame
Before the first validation frame is applied during the validation phase,
the NonceManager
is invoked with the following data:
The gas costs of this execution frame are counted towards the total for a transaction.
NonceManager Pseudocode
NonceManager Bytecode and deployment
TODO.
Rationale
Creating a pre-deployed contract instead of modifying an account data structure
While there is no technical benefit to either option, allowing EVM code to control the nonce seems to be a smaller change to the Ethereum protocol and is more aligned with the vision of Account Abstraction.
Backwards Compatibility
As actual nonce
value was never observable inside the EVM, there should be no major complications caused by the
migration to a different nonce mechanism.
Smart Contract Accounts could access the uint256 nonce
value in the TransactionType4
struct and ignore the
higher 192 bits assuming nonce cannot exceed 64 bits.
This assumption is wrong and is broken by the proposed change.
Security Considerations
Smart Contract Accounts that need to enforce the sequence of transaction execution must apply appropriate restrictions
on the uint192 key
value.
In order to require the incremental sequential nonce
behaviour on-chain, the contracts
may choose to require(key == 0)
.
Copyright
Copyright and related rights waived via CC0.