Ethereum has two types of accounts: Externally Owned Account (EOA) and Contract Account (CA). EOAs are controlled by a private key while CAs are controlled by the smart contract code contained in them. EOAs have always been more privileged than CAs because only EOAs can start transaction execution by paying gas. Account Abstraction (AA) is a proposal that allows a contract to be a “top-level” account, like an EOA, that can pay fees and start transaction execution.
The motivation for AA is to significantly improve the user experience in how users interact with the Ethereum blockchain today across various scenarios such as wallets, mixers, ÐApps and DeFi. AA provides a base layer functionality in Ethereum to decide when one can pay for the gas which also has implications on who pays for gas and how they pay for it.
The Status Messenger app bundles a privacy-centric messenger along with an Ethereum wallet and a Web3 ÐApp browser. Status wallet currently is an EOA wallet which limits us from offering a rich UX that only a smart contract wallet can offer such as multi-signature security, social recovery, rate-limiting, allow-/deny-list of addresses and gasless meta-transactions. However, the UX of smart contract wallets today is severely hindered by fluctuating gas prices which is not efficiently solved by third-party relayers. AA aims to address this problem.
In this article, we motivate the need for Account Abstraction in the context of smart contract wallets. We then deep-dive into key aspects of AA by describing the protocol changes and impact on nodes. Finally, we discuss some of the proposed extensions and conclude by rationalizing the planned roadmap for Status projects that interface with Ethereum and therefore could be impacted by AA.
History & Motivation
Account Abstraction was initially proposed as EIP-86 in 2017 to implement “Abstraction of transaction origin and signature” but the origins of the motivating idea go back even further to early 2016, where it was suggested that: “Instead of having an in-protocol mechanism where ECDSA and the default nonce scheme are enshrined as the only "standard" way to secure an account, we take initial steps toward a model where in the long term all accounts are contracts, contracts can pay for gas, and users are free to define their own security model.”
The initial proposals were considered to be challenging to implement because of the many protocol changes required and the security guarantees to be met. More recently, Vitalik et al. proposed a draft for EIP-2938 which outlines a much simpler implementation by keeping the protocol/consensus changes minimal and enforcing the required security guarantees via node mempool rules. Vitalik’s Ethereum Engineering Group Meetup presentation and ETHOnline presentation (together with accompanying articles 1 & 2) by Sam Wilson & Ansgar Dietrichs (two of the other EIP authors) offer great introductions to the topic. This article highlights key aspects from all these sources.
Motivation: The motivating rationale behind AA is very simple but fundamental: Ethereum transactions today have programmable effects (achieved via calls to smart contracts) but they have fixed validity in that transactions are valid only if they have a valid ECDSA signature with a valid nonce and have sufficient account balance. AA upgrades transactions from fixed validity to programmable validity by introducing a new AA transaction type that always originates from a special address for which the protocol does not require signature, nonce or balance checks. The validity of such AA transactions is determined by a target smart contract which can enforce its own validity rules after which it can decide to pay for such transactions.
So, why is this useful? Let’s take the example of Ethereum wallets to highlight the benefit of AA.
Smart Contract Wallets: Most Ethereum wallets today are EOA wallets which are protected by a private key generated from a seed phrase. (A BIP-39 seed phrase or mnemonic is an ordered list of 12-24 words which are randomly chosen from a list of 2048 words. This provides the entropy required to obtain a binary seed which is generated using the PBKDF2 function. The binary seed is then used to generate the asymmetric key pairs for the BIP-32 wallet.) The user is expected to write down the seed phrase somewhere safe because it could be required later for restoring the keys on another wallet. Such wallets are however vulnerable to private key theft or loss of seed phrases which result in loss of user’s funds.
Smart contract wallets are implemented on-chain via smart contracts (as the name suggests). Such wallets offer programmable risk mitigation and user-friendly experience by implementing features such as multi-signature security, social or time-based recovery, rate-limiting of transactions or amounts, allow-/deny-list of addresses, gasless meta-transactions and batched transactions.
While smart contract wallets are exposed to security risk from vulnerable smart contracts, this risk may be mitigated by security testing and reviews performed by the wallet provider. The risk in EOA wallets lies entirely with the wallet user who is entrusted with the security of the seed phrase without any of the programmable safeguards that are possible with smart contracts.
Examples of smart contract wallets are Argent, Authereum, Dapper, Dharma, Gnosis Safe, Monolith and MYKEY. The adoption of such wallets seems to be increasing as indicated by the below graph.
Argent implements seedless social recovery with their concept of Guardians who are user’s trusted people or devices that can help with recovering the user’s wallet. Argent also aims to enable bank-like security (via features such as daily transaction limits, account locking and trusted contacts) combined with Venmo-like usability (via use of ENS names instead of addresses and support for meta-transactions).
Gnosis Safe is a multi-sig smart contract wallet focussing on team management of funds that requires a minimum number (m-of-n) of team members to approve a transaction before it can occur. It also enables gasless signatures via meta-transactions.
All such advanced wallet capabilities require the use of non-trivial smart contracts. Wallet users either need an EOA with gas to interact with them or depend on the wallet provider to support meta-transactions via the provider’s relayers or third-party relayer networks such as Gas Station Network. While the former relies on ETH typically purchased on centralized exchanges after KYC, the latter aims to reduce this onboarding UX friction by transferring the user’s burden onto relayers for a cost that is compensated by the wallet provider on-/off-chain and/or by the user off-chain.
However, relayer-based architectures have three main drawbacks: (1) They may be considered as centralized intermediaries with potential for censoring transactions (2) They are technically/economically inefficient due to the 21000 extra base gas fee required for the relayer’s transaction and their business need to make a profit on top of the gas fees (3) The use of relayer-specific protocols forces applications to rely on non-base-layer Ethereum infrastructure with smaller user bases and uncertain availability guarantees.
Account Abstraction will enable smart contract wallets to accept user’s gasless meta-transactions and pay for their gas without depending on relayer networks. This base-layer capability will therefore significantly improve the onboarding UX of such wallets without sacrificing the decentralization guarantees of Ethereum.
Tornado Cash: A related motivating application is that of a mixer such as tornado.cash where Tornado improves transaction privacy by breaking the on-chain link between addresses using a smart contract that accepts ETH deposits which can later be withdrawn by a different address. The user is expected to provide the hash of a secret during the deposit and later provide a zkSnark proof during withdrawal to show the knowledge of the secret without revealing the secret or the earlier deposit itself. This de-links the withdrawal from the deposit.
But there is a chicken-and-egg problem with the withdrawal. To execute a withdrawal transaction from a newly generated address, the user needs to have some ETH in it to pay for gas. The source of this ETH (typically an exchange) can break Tornado’s privacy. The preferred alternative is to again use a relayer network which has the drawbacks outlined earlier.
Account Abstraction will solve this problem by allowing the Tornado contract to accept the user’s withdrawal AA transaction, validate the zkSnark, deduct some gas fees (from the earlier deposit amount) and then transfer the remainder of the deposit amount to the withdrawal address.
Account Abstraction, as proposed in EIP-2938, allows a contract to be the top-level account that pays fees and starts transaction execution. This is achieved by introducing protocol changes with a new AA transaction type that requires two new opcodes: NONCE and PAYGAS, changes to mempool rules and extensions to support advanced usages. The types of accounts continue to be two (EOA and Contract Account) and all proposed changes are backwards compatible with current transactions, smart contracts and protocol.
The applications of AA are considered across two categories: 1) Single-tenant applications such as smart contract wallets, which create a new contract for each user 2) Multi-tenant applications such as tornado.cash or Uniswap, where multiple users interact with the same set of smart contracts.
AA support for multi-tenant applications requires more research and is proposed as future work. So we will focus on single-tenant AA support in this article.
There is a new transaction type introduced along with two supporting opcodes of NONCE and PAYGAS. These are the only protocol changes.
AA Transaction: A new type of AA transaction AA_TX_TYPE is introduced. Its payload is interpreted as RLP([nonce, target, data]) instead of the existing transaction type whose payload is RLP([nonce, gas_price, gas_limit, to, value, data, v, r, s]).
The omitted gas_price and gas_limit in the AA transaction are specified by the target AA contract during execution. The omitted ECDSA signature v, r, s in the AA transaction is replaced by contract-specific verification checks on the data. The to address is replaced by the target contract address. The value is omitted because the originating address for all AA transactions is a special ENTRY_POINT address (0xFFFF...FFFF) and not an EOA which has a value associated with it.
Nonces are processed analogously to existing transactions by checking if tx.nonce == tx.target.nonce. if this check fails then the transaction is considered invalid but otherwise, tx.target.nonce is incremented and transaction proceeds.
The base gas cost of AA transaction is proposed to be 15000 instead of the current 21000 (to reflect the cost savings from lack of intrinsic ECDSA signature). Furthermore, AA transactions have no intrinsic gas limit. When beginning execution, the gas limit is simply set to the remaining gas in the block.
NONCE opcode: NONCE opcode (0x48) pushes the nonce of the callee, i.e. the AA target contract, onto the EVM stack. Nonces are thus exposed to the EVM to allow signature verification to be performed over all transaction fields (including nonce) as part of the validation in the AA contract.
PAYGAS opcode: PAYGAS opcode (0x49) takes two arguments off the stack: (top) version_number, (second from top) memory_start. The version_number allows future implementations to change semantics of the opcode. Currently, the opcode has the below semantics:
- Check version_number == 0 (else throw exception)
- Read gas_price = bytes_to_int(vm.memory[memory_start: memory_start + 32])
- Read gas_limit = bytes_to_int(vm.memory[memory_start + 32: memory_start + 64])
- Check contract.balance >= gas_price * gas_limit (else throw exception)
- Check globals.transaction_fee_paid == False (else throw exception)
- Check AA execution frame == top-level frame, i.e. if the current EVM execution exits or reverts, EVM execution of the entire transaction is terminated (else throw exception)
- Set contract.balance -= gas_price * gas_limit
- Set globals.transaction_fee_paid = True
- Set globals.gas_price = gas_price and globals.gas_limit = gas_limit
- Set current execution context’s remaining_gas = gas_limit - gas already consumed
At the end of AA transaction’s execution, (globals.gas_limit - remaining_gas) * globals.gas_price is transferred to the miner and the AA contract is refunded remaining_gas * globals.gas_price.
PAYGAS acts as an EVM execution checkpoint. Any reverts after this point will only revert until here and then the contract receives no refund and globals.gas_limit * globals.gas_price is transferred to the miner.
The new transaction type and the two new opcodes constitute the protocol/consensus level changes and their semantics are relatively straightforward to reason about.
“The mempool refers to the set of in-memory data structures inside an Ethereum node that stores candidate transactions before they are mined. Geth calls it the “transaction pool”; Parity calls it the “transaction queue.” Regardless of the name, it is a pool of transactions sitting in memory waiting to be included in a block. Think of it as a “waiting area” for transactions to be accepted into a block.”
Presently, with fixed transaction validity rules, miners and other nodes need minimal effort to validate transactions in their mempool and thus avoid DoS attacks. For e.g., a miner can be certain that a transaction will actually pay the fee if it has a valid ECDSA signature, valid nonce and has sufficient account balance. Other transactions in that miner’s mempool may invalidate this pending transaction only if they are from the same address and, either increase the nonce or sufficiently reduce the account’s balance. These conditions are computationally minimal to give miners and nodes sufficient confidence in their mempools for block consideration or rebroadcasting respectively.
AA transactions introduce more complexity with their programmable validity. AA transactions pay no upfront gas and rely on their target AA contracts to pay gas (via PAYGAS). Conceptually, AA transaction processing is split into two phases: the shorter verification phase (before PAYGAS) and the longer execution phase (after PAYGAS). If the verification phase fails (or throws an exception), the transaction is invalid (just like a non-AA transaction with an invalid signature today), does not get included in a block and the miner gets no fees.
Miners and nodes therefore need a predictable mechanism to avoid the dependency of a pending AA transaction’s validity on other pending transactions in the mempool. If not, one transaction’s execution could invalidate many/all AA transactions in the mempool leading to DoS attacks. To avoid this scenario, there are two proposed rules to be enforced (by miners and nodes but not in the protocol itself) on AA transactions in the mempools:
To prevent AA transaction’s validity from depending on any state external to the AA contract itself, the following opcodes are considered invalid in the verification phase (i.e. before PAYGAS): environment opcodes (BLOCKHASH, COINBASE, TIMESTAMP, NUMBER, DIFFICULTY, GASLIMIT), BALANCE (of any account, including the target itself), an external call/create to anything but the target or a precompile (CALL, CALLCODE, STATICCALL, CREATE, CREATE2) and external state access that reads code (EXTCODESIZE, EXTCODEHASH, EXTCODECOPY, DELEGATECALL) unless the address is the target.
Nodes are expected to drop AA transactions in the mempool that target AA contracts breaking this opcode restriction rule. This ensures that valid AA transactions in mempool will remain valid as long as the AA contract state does not change.
If non-AA transactions can affect the state of AA contracts then that will impact the validity of AA transactions in the mempool. To prevent this, AA transactions should only be allowed to target contracts that have an AA_PREFIX at the beginning of their bytecode, where AA_PREFIX implements a check that msg.sender is the special ENTRY_POINT address of AA transactions. This effectively prevents non-AA transactions from interacting with AA contracts.
Nodes are expected to drop AA transactions to AA contracts that do not have this AA_PREFIX at their bytecode entry points.
These two restrictions enforced on AA contracts together ensure that: (1) the only state accessible to an AA transaction’s validity logic is state internal to the AA contract and (2) this state can only be modified by other AA transactions targeting this specific AA contract.
A pending AA transaction to an AA contract may therefore only be invalidated by a block containing another AA transaction targeting the same AA contract. However, given that these are not protocol/consensus changes, miners are free to include transactions in a block that break these rules.
The above protocol changes and mempool rules allow for basic AA contracts to sufficiently and safely implement single-tenant applications such as smart contract wallets. Other advanced usages that need relaxation of above rules or need to implement multi-tenant applications require more support from AA in the form of extensions such as:
- SET_INDESTRUCTIBLE opcode, which disables SELFDESTRUCT and allows AA contracts to call libraries with DELEGATECALL safely in the verification phase.
- IS_STATIC opcode, which returns true if the current context is static and allows non-AA transaction callers to override the earlier bytecode-prefix restriction and read values out of AA contracts safely.
- RESERVE_GAS opcode, which establishes a lower bound on gas consumed by the AA contract when invoked from a non-AA transaction that seeks to write contract state. This serves to force attackers from spending a minimum amount of gas to disincentivize attempts to invalidate any AA transactions in the mempool.
There are others such as multiple pending transactions, caching results of validation, dynamic gas limits for validation and sponsored transactions which are required for supporting multi-tenant applications and zk proofs e.g. Tornado Cash. Their discussion is out of scope for this article.
The Account Abstraction EIP-2938 is currently in draft mode and is being discussed in Ethereum research forums. The next step for the EIP is to be considered for inclusion in one of the upcoming hard forks. The EIP authors are apparently aiming for the hard fork after Berlin (Berlin is tentatively scheduled for sometime in early 2021) whose timeline isn’t very clear at the moment. So it’s still early in the process for EIP-2938.
Furthermore, it’s also not clear that it will be necessary to include EIP-2938 at the Ethereum base Layer 1 (L1). Given the relative flexibility of Layer 2 (L2) solutions (as described in our earlier article), Account Abstraction may be implemented on specific L2’s without requiring the entire L1 to be upgraded. There are however benefits to uniform AA support on L1 even if some L2's implement their own AA versions. Therefore, it remains to be seen where and how AA gets implemented.
“Account abstraction is somewhat less important, because it can be implemented on L2 regardless of whether or not L1 supports it.” — Vitalik on things that would continue to matter at the base layer (in his post on rollup centric Ethereum roadmap).
Status: Status wallet presently is an EOA wallet which differentiates itself by the bundling of a privacy-centric messenger and enabling integrations such as payments in chat or enhanced security with Keycard. Smart contract wallet features such as multisig and social recovery are being considered for which AA EIP-2938 support will help by removing dependency on centralized and inefficient relayer-based architectures, as described earlier.
Status is also evaluating L2 solutions both for supporting multiple chains in its wallet and for providing the required scaling for various use cases as described in our earlier article. For e.g., Keycard is exploring a payments network whose design requirements of credit-card level scalability and near-instant finality are not fulfilled by the Ethereum network today. Additionally, there are numerous other initiatives such as the Referral Program, SNT reactions, Tribute-to-Talk and ENS names, all of which would benefit from L2 scalability for feasible deployment and reasonable user experience. If a viable L2 solution implements AA then projects building on that L2 will be able to leverage the benefits of AA without having to rely on L1.
A fundamental aspect of Ethereum protocol is that only Externally Owned Accounts (EOAs) can pay gas fees and start transaction execution. Contract Accounts (CAs) can not do that. Account Abstraction (AA) is a proposal that aims to change this distinction and allow specially constructed CAs to programmatically check the validity of a new type of AA transactions, decide to pay gas fees on their behalf and thereby effectively start their execution without the requirement of an EOA.
AA has implications to significantly improving the user experience across various scenarios such as wallets, mixers, ÐApps and DeFi without relying on centralized and inefficient relayer-based architectures. Basic single-tenant scenarios, such as smart contract wallets, can be safely supported by AA with the introduction of a new transaction type, two new opcodes and two mempool rules. Advanced multi-tenant applications, such as Tornado Cash, require extensions to these protocol changes and node rules.
In this article, we motivated the need for AA in the context of smart contract wallets. We highlighted key aspects of AA by describing the protocol changes and impact on nodes. We touched upon some of the proposed extensions for advanced usages and finally concluded by positioning AA in the context of current roadmaps of Ethereum and priorities at Status.
Reducing friction and improving user experience in Web3 is a top priority for all projects in this ecosystem. Account Abstraction, in some form, may certainly play an important role in this effort going forward.
(Thanks to Hester Bruikman for reviewing drafts of this article and providing helpful feedback. Thanks to Alex Howell for the thoughtful illustration.)