Hi, I'm a bot! This change was automatically merged because: - It only modifies existing Draft or Last Call EIP(s) - The PR was approved or written by at least one author of each modified EIP - The build is passing
7.8 KiB
eip | title | author | discussions-to | status | type | category | created |
---|---|---|---|---|---|---|---|
3074 | Sponsored Transaction Precompile | Sam Wilson (@SamWilsn) | https://ethereum-magicians.org/t/eip-3074-sponsored-transaction-precompile/4880 | Draft | Standards Track | Core | 2020-10-15 |
Simple Summary
Creates a new precompile, analogous to CALL
(0xF1
), that sets CALLER
(0x33
) based on an ECDSA signature.
Abstract
This EIP creates two precompiles:
CALL_PRECOMPILE
- forwards aCALL
, settingCALLER
according to an ECDSA signature, using a invoker-sponsee nonce for replay protection.NONCE_PRECOMPILE
- provides access to invoker-sponsee nonces expected byCALL_PRECOMPILE
.
Motivation
Sponsored transactions—the separation of fee payment from transaction content—have been a long standing feature request. Unlike similar proposals, this EIP specifies a method of implementing sponsored transactions that allows both externally owned accounts (EOAs) and EIP-2938 contracts to act as sponsors.
With the explosion of tokens built on Ethereum, especially stable coins, it has become common for EOAs to hold valuable assets without holding any Ether at all. These assets must be converted to Ether before they can be used to pay gas fees, but without Ether to pay for the conversion, it's impossible to convert them. Sponsored transactions break the circular dependency.
While it is possible to emulate sponsored transactions (ex. Gas Station Network), these solutions require specific support in callee contracts.
Specification
Sponsored transactions are implemented with the addition of two precompiles:
- The first, at address
0x13
, which functions like aCALL
instruction that additionally sets the caller address based on an ECDSA signature. - The second, at address
0x14
, provides access to the current nonce for the given invoker-sponsee pair.
Definitions
CALL_PRECOMPILE
- the specific precompile at address0x13
, introduced by this EIP, which implements theCALL
analogue.NONCE_PRECOMPILE
- the specific precompile at address0x14
, introduced by this EIP, which exposes invoker-sponsee nonces.- Transaction-like Package - the signed arguments passed to
CALL_PRECOMPILE
. - Sponsor - the account which is responsible for paying gas fees and sending the transaction. May or may not be the same as the invoker.
- Sponsee - the account which signed the transactions-like package.
- Invoker - the account or contract which directly calls into
CALL_PRECOMPILE
. May or may not be the same as the sponsor. - Callee - the target of the call from
CALL_PRECOMPILE
.
API
CALL_PRECOMPILE
CALL_PRECOMPILE
requires the following eight arguments:
nonce
- the next nonce value, as described below;to
- the address of the callee (notCALL_PRECOMPILE
);gaslimit
- the minimum gas limit which must be provided with the call intoCALL_PRECOMPILE
;value
- the exact amount of Ether in wei to transfer from the invoker to the callee;data
- the calldata for the call intoto
; andv
,r
,s
- signature for the package, including chain id as specified in EIP-155.
The arguments to CALL_PRECOMPILE
are encoded as rlp([nonce, gaslimit, to, value, data, v, r, s])
.
The signature (v
, r
, s
) arguments are computed from secp256k1(keccak256(rlp([nonce, gaslimit, to, value, data, invoker, chainid])))
.
CALL_PRECOMPILE
returns a failure without changing the nonce in the following situations:
- Invalid signature
- Future or past nonce
- Gas limit supplied with the call into
CALL_PRECOMPILE
is less than the signedgaslimit
- The invoker's balance is insufficient to pay for the supplied gas plus
value
CALL_PRECOMPILE
returns a success in all other cases.
The return data of CALL_PRECOMPILE
will be a single byte to indicate the status of the call into callee followed immediately by the return data from that call.
NONCE_PRECOMPILE
NONCE_PRECOMPILE
requires the following two arguments:
invoker
- the invoker address; andsponsee
- the sponsee address.
Assuming the calldata is the correct length, NONCE_PRECOMPILE
will return a success, and place the nonce associated with the address pair in the return data.
Nonces
The two precompiles will maintain a nonce for each pair of invoker address and sponsee address, in essence:
{
(0x1234...5678, 0xEEEE...EEEE) => 55,
(0x1122...3344, 0xBBBB...BBBB) => 89,
}
Where:
0x1234...5678
and0x1122...3344
are the invoker addresses;0xEEEE...EEEE
and0xBBBB...BBBB
are the sponsee addresses; and55
and89
are the current nonce values for their respective pairs.
The nonce shall be incremented whenever a correctly signed transaction-like package containing the next nonce is submitted to CALL_PRECOMPILE
with a sufficient gas limit.
Gas Fees
CALL_PRECOMPILE
TODO: Probably something like the sum of:
- The cost of a normal call, including calldata and signature size, etc.
- An
SLOAD
to read the current nonce - An
SSTORE
to write the updated nonce - Cost of an ecrecover
NONCE_PRECOMPILE
TODO: Probably something like the sum of:
- An
SLOAD
to read the current nonce
Rationale
Another Sponsored Transaction EIP
Other approaches to sponsored transactions, which rely on introducing a new transaction type, are not immediately compatible with account abstraction (AA). These proposals require a signed transaction from the sponsor's account, which is not possible from an AA contract, because it has no private key to sign with.
Besides better compatibility with AA, a precompile is a much less intrusive change than a new transaction type. This approach requires no changes in existing wallets, and little change in other tooling.
CALL_PRECOMPILE
's single purpose is to set CALLER
. It implements the minimal functionality to enable sender abstraction for sponsored transactions. This single mindedness makes CALL_PRECOMPILE
significantly more composable with existing Ethereum features.
More logic can be implemented around the call into CALL_PRECOMPILE
, giving more control to invokers and sponsors without sacrificing security or user experience for sponsees.
Nonces
Other nonce schemes either do not provide enough security, or are too inefficient/inconvenient to be practical.
- Use sponsor nonce: every transaction from the sponsor's account invalidates every transaction-like package.
- Use invoker nonce: every sponsored transaction from the invoker's account invalidates every other transaction-like package. Also interacts with
SELFDESTRUCT
. - Use sponsee nonce: the sponsee could attack the sponsor by submitting another transaction with a conflicting nonce at a higher gas price.
Instead, by creating an independent nonce per invoker-sponsee pair, we get some attractive properties:
- A transaction package can only be invalidated if both the invoker and sponsee cooperate, which is nice for EOA sponsors, and necessary for AA contracts.
- The
SELFDESTRUCT
operation doesn't introduce replay attacks.
Precompile vs. Opcode
Opcodes do not have externally visible addresses, and therefore cannot be called directly by an EOA. Using a precompile allows a sponsor to avoid an intermediary contract call should they want to use this functionality directly.
Backwards Compatibility
No known issues.
Test Cases
TODO
Implementation
TODO
Security Considerations
- First precompiles that require persistent storage.
- Potential impersonation attacks if there is a bug in the signature verification.
- Potential replay-attack problems if there is a bug in the replay protection, or if two chains share chain ids.
Copyright
Copyright and related rights waived via CC0.