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
Constants
Name | Value |
---|---|
AA_BASE_GAS_COST | 15000 |
AA_BASE_GAS_COST_RIP7712 | 10000 |
AA_NONCE_MANAGER | tbd |
Non-sequential nonce support
We propose an introduction of the nonceKey
parameter to provide a second dimension
for the RIP-7560 transaction's nonce
parameter.
The two-dimensional nonce value of the transaction is represented as uint256 nonceKey || uint256 nonceSequence
value.
The contract account nonce is then defined as a mapping address account => uint256 nonceKey => uint256 nonceSequence
.
This approach guarantees unique transaction nonce and hash but removes the requirement of nonces being sequential
numbers.
This two-dimensional nonce mechanism is exposed to the EVM in a NonceManager
pre-deployed contract
located at the AA_NONCE_MANAGER
address.
The two-dimensional nonce is validated and incremented on-chain
as part of a AA_TX_TYPE
transaction validation before the rest of the validation code.
Nonce validation
We propose to introduce a new validation frame to the RIP-7560 transaction validation flow. This validation frame performs an on-chain nonce validation and runs before all other frames in a transaction.
If nonceKey is zero (non-existent), the nonce field is compared to the system nonce,
and then the system nonce is incremented.
The transaction's base cost is A_BASE_GAS_COST
.
If nonceKey
is non-zero, then the NonceManager
is called to validate and increment
the nonce for this key, and the base cost is AA_BASE_GAS_COST_RIP7712
, as the NonceManager
frame is paid separately.
In this case, the old system nonce
is not checked and not incremented.
Deployment transaction
During the account deployment transaction, the nonceKey
MUST be zero.
The old system nonce
parameter is not incremented before the transaction:
the CREATE
or CREATE2
opcode used by the deployer
will cause the nonce to be incremented to 1 according to EIP-161.
Nonce validation frame
Before the first RIP-7560 transaction type defined validation frame is applied during the validation phase,
the NonceManager
is invoked with the following data:
The gas costs of this validation frame are counted towards the total for a transaction,
and is deducted from the account's validationGasLimit
.
Nonce query frame
In order to query its current nonceSequence
for a given nonceKey
, the user performs a view call
to the NonceManager
contract with the following data:
The returned value of this call is the current nonceSequence
that can be used
in the nonce validation frame.
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.
Applications should not assume that eth_getTransactionCount
method returns the total transactions for an account
Security Considerations
Smart Contract Accounts that need to enforce the sequence of transaction execution must apply appropriate restrictions
on the nonceKey
value.
In order to require the incremental sequential nonce
behaviour on-chain, the contracts
may choose to require(nonceKey == 0)
.
Copyright
Copyright and related rights waived via CC0.