TL:DR
Account Abstraction is still one of the major hurdles of Ethereum developers. The recently approved EIP-3074 aims to take the first step towards bridging the gap between the EVM and the UX of traditional financial systems.
By adding 2 new opcodes - AUTH
and AUTHCALL
, EIP-3074 gives EOAs (Externally Owned Accounts) the functionality of SCAs (Smart Contract Accounts) and will change how users interact with the EVM.
EIP-3074 aims to “supercharge” EOAs!
Authorized transactions unlock the following for users’ EOAs:
Sponsored transactions
Performing multiple actions in one transaction
A pathway to asset recovery in case of private key loss
However, with all its benefits, EIP-3074 comes with some potential downsides:
Security concerns. A malicious invoker can steal funds from users.
Potential issues with Ethereum upgrades down the road
EOAs are in essence just a stored private key that encodes the user’s public key and blockchain address. While EOAs align with the core principle of asset self-custody on the blockchain, they fall short in providing the user experience that traditional wallet users are accustomed to.
The limitations of modern EOAs can be summarized by the following:
Each on-chain action requires a dedicated transaction (even more in case if token approval is needed)
ETH is required to perform all on-chain actions
It is impossible to recover funds if the private key is lost
EIP-3074 is aimed to address these issues and enhance the UX of EOAs. By serving as a form of native account abstraction, this upgrade makes a crucial step in Ethereum’s journey towards reaching the milestone of the next billion users.
There have been frequent requests to expand functionality of the EOAs, including adding features like batch processing, gas sponsorship, expiration times, and scripting. However, such additions can increase the complexity and rigidity of the protocol, and broaden its vulnerability to attacks.
This EIP takes a different route. Instead of building these functionalities directly into the protocol as part of the transaction validity requirements, it allows users to delegate control of their EOA to a contract. This approach offers developers a flexible framework to create unique transaction schemes for EOAs, effectively letting an EOA operate like a smart contract wallet without needing to deploy an actual contract.
Though this EIP offers significant advantages for individual users, the primary motivation behind it is "sponsored transactions." This means that the cost of a transaction is paid by a different account than the one initiating it. Given the substantial growth of tokens on Ethereum, it's become common for EOAs to hold valuable assets without having any ether. Currently, these assets must be converted to ether to cover gas fees. Yet, without ether for the conversion, this becomes a deadlock. Sponsored transactions break this cycle by allowing another account to cover the fees, enabling EOAs to operate even without holding ether.
A new context variable authorized
is introduced. This variable is valid for the current execution context only (i.e., there can be several authorized
values for the same contract, so long as they remain in separate call hierarchies). This variable stores the address of the account that has authorized (hence the name) the contract in question to act on its behalf in the current execution context.
It must be stated that the execution context is mutated under nested calls. Therefore, a call within a call has a context distinct from that of the parent call.
For the purposes of setting the authorized
context variable, a new opcode AUTH 0xf6
is introduced. This opcode takes in the address of the authorizer (authority
in the specification) and a specification of a contiguous memory range wherein the data necessary for proving authorization (i.e., ECDSA-security provision data) is stored. This data consists of the signature of a string with a specific structure and an optional EVM word (32 bytes) of commit
.
It must be said that authority
must not be a contract; i.e., its EXTCODESIZE
must be nil. Otherwise, the operation fails.
Any failure of the AUTH
opcode unsets authorized
, even if it has been set in this execution context before.
The string that must be signed (the message over which the signature is computed) is constructed as a concatenation (here ||):
MSG = keccak256(MAGIC||chainId||nonce||invokerAddress||commit)
Here:
MAGIC
- a fixed bytestring (0x04
) meant to prevent signature collisions
chainId
- chain ID for use on other EVM chains. Padded to a full EVM word
nonce
- current nonce of the signer, padded to a EVM word from the left
invokerAddress
- address of the contract from where the opcode is executed (i.e., active state address); padded to a EVM word from the left
commit
- the commit value residing in the memory as described above; it is meant to encode custom conditions determining validity of possible txns to be undertaken from the authorized contract on behalf of the authority
.
This opcode sets the authorized
context variable to equal authority
, provided that the signer address equals authority
(as can be determined from the signature) and that the signature is valid. The return value of AUTH
is a boolean success indicator.
The memory range accepted by AUTH
is not fixed as one may assume from the above description. It is dynamic for the purposes of upgradeability; however, all supernumerary bytes are currently ignored.
There is also another opcode introduced: AUTHCALL 0xf7
. It is intended as a modification of the extant CALL 0xf1
opcode and takes the same arguments (gas
, addr
, value
, argsOffset
, argsLength
, retOffset
, retLength
). The nature of these arguments are rather self-evident from their names. However, should the need to examine them arise, one is recommended to seek information on the arguments of the CALL
opcode, which are exactly the same.
There are a number of logical differences in the execution of AUTHCALL
as opposed to OPCALL
. They are as follows (ordered by precedence):
The caller address of the call is authorized
, unless it is unset, in which case AUTHCALL
fails. This is the mechanism whereby a contract may be aliased as an EOA.
If gas
is zero, all available gas is sent
If the gas available for a subcall is exceeded by gas
, the opcode fails
The subcall gas is computed according to the pseudocode below
if (gas == 0){
subcall_gas = remaining_gas - (remaining_gas//64) //see EIP-150 for reasoning
}
elif (remaining_gas - (remaining_gas//64) < gas) {
OPCODE_FAILS
}
else {
subcall_gas = gas
}
The 2300 gas stipend that usually accompanies nonzero value
calls is not allocated
value
is deducted from the balance of authorized
and not the contract
The authorized value is unchanged by AUTHCALL
Usage of commit
is not enforced in any way by the EIP, and, indeed, the community is expected to develop standards regarding its usage (and pay attention to the contracts they authorize to) on its own (though a set of recommendations is provided).
However, the intent behind commit
is to provide the user with the ability to encode specification of permitted calls or properties thereof (e.g., by computing a hash of the call values, which the invoker then must check before a call goes through). Since the commit
is signed over, it cannot be tampered with without invalidating the signature unless the private key of the authorizer is compromised.
The EIP recommends that the commit be made by hashing the values which the invoker must validate. It therefore follows that the invoker should ensure the integrity of the input (i.e., that it is authorized by the user) by computing the commit hash itself as a validation operation.
An example of the commit for a multi-call authorization, taken from the EIP text, is given below (the values given are hashed to produce the commit field)
This also means that control of the EOA can be arbitrarily delegated via the commit field with whatever conditionals the user desires to specify (ref. to the picture below for an example)
The EIP significantly broadens the native functionality of the EOAs, allowing arbitrary delegation without using the current conventional account abstraction tools. This means that once the invoker contract template is developed , all AA solutions but those with the most robust ecosystem built around them, will eventually wither for reasons of superior ease of usage of the EIP-3074 framework (as a funny miscellaneous fact: it would, in fact, be cheaper to use AUTHCALL
instead of CALL for sending native tokens for reasons of not providing the 2300 gas stipend for seeding the gas counter).
The pressure on existing AA solutions will only increase with time as more elaborate invoker templates will be developed. For example, solutions that allow to realize a form of joint signature with no extra off-chain technology.
Although the demand to trust the invoker which is authorized certainly sounds problematic, it is in fact no different from using one of the existing solutions, which also require the user to put his trust into their proper operation.
Moreover, this EIP will bring on-chain a certain form of conditionality on the transactions from a EOA that require no off-chain components to exist for monitoring, therefore definitely expanding automation possibilities.
EIP-3074 marks a significant milestone in Ethereum’s evolution towards a more user-centric, accessible, and cost-effective future. By enabling the possibility of delegating control of an EOA to a smart contract invoker, this upgrade opens up avenues for a range of new possibilities like batched and sponsored transactions, the possibility to retrieve funds in case of lost private keys, and much more.
These advancements will not only provide a much needed path to native Account Abstraction, streamlining user interactions, but expand the range of use cases for robust and decentralized on-chain automation.