Blockchain@USC
In Web 2.0, if you forget your password you can recover it from a centralized authority. In crypto, if you lose your private key or forget your seed phrase, you lose everything. This is one key bottleneck to crypto mass adoption — account security is very fragile. Moreover, expecting the next billion blockchain users to all safely retain their private keys is a very far-fetched notion. On the internet, you can often recover your accounts with two-factor authentication if you lose your password. Similarly, this can be built on blockchain technology through the use of a new concept called account abstraction. In this paper, I will examine the user experience and technical engineering problems solved by account abstraction, and also dive deeper into the further implications of the concept.
To wrap our heads around the UX friction caused by the existing technology, we need to first examine how accounts currently work on Ethereum. Your typical wallet (e.g. MetaMask or Ledger) manages what is called an externally owned account (EOA).
An EOA contains:
• An address for identification
• A nonce to track uniqueness of transactions
• A balance in ETH to pay gas fees.
Users own EOAs through a signer, which is a pair of cryptographic keys. the public key is used to derive the EOA address, and the private key is used to sign transactions. Essentially, the signer is authorized to spend from the account and make transactions. A key idea here is that the signer — especially the private key — is quintessential to truly owning your assets. If someone else gets a hold of your keys, those assets are no longer yours.
Putting security aside for now and moving to user experience: EOAs are very rudimentary — every single transaction must be manually signed by the EOA private key, and transactions cannot be sent in batches. If you spend a lot of time on chain, you know how annoying it can be to have to sign all those approvals and transactions while trading or using a decentralized application (dApp). This would be even more tedious in the GameFi realm, for example, where constant interactions are necessary for a fluid user experience.
It is very hard to automate certain logic from an EOA unless you grant a smart contract unlimited permission to call transactions from it — not only is this a security risk, it is a user experience pain point. We will see later how account abstraction introduces the possibility to run automated payment subscriptions, spending limits, pre-approvals, batch transactions, and much more.
Another issue that arises with EOAs is that they are hard-coded to use elliptic curve cryptography (ECDSA secp256k1) for the private key signatures, with no way to change the signature scheme. Although the threat of quantum computing is still distant, elliptical curve cryptography is not quantum-resistant, which would introduce catastrophic problems in a quantum-computing future. We will later see how account abstraction allows builders to modify the cryptographic signature schemes of wallets.
Finally, the most relevant pain point of all — storing private keys. Telling people to securely retain their private keys has been the approach to wallet security for over a decade now. Wallet recovery is impossible if the human loses their private key, meaning security is almost completely reliant on there being zero human error. However, if you know anything about tech security, you know that the majority of security issues stem from human error.
Many may argue for the simple regurgitation of the phrase “just store your mnemonic seed phrase on a piece of paper in three different locations and memorize it”. For argument’s sake, even if every wallet owner employed this exact tactic or any arbitrary, equally-secure method (which is certainly not the case), there would still be wallet losses. Why? A simple intuition derived from the law of large numbers — the larger the population space of crypto users grows, the more wallet losses there will be. We just cannot expect people to go through all this effort to protect their digital assets, and still have a non-zero chance of losing everything. Something needs to be fixed!
I’ll finish up this section with a quote from Vitalik Buterin’s very good article on social recovery wallets:
“But the reality is that the whole point of digital technology, blockchains included, is to make it easier for humans to engage in very complicated tasks without having to exert extreme mental effort or live in constant fear of making mistakes.”
If blockchain is to scale to become the future’s global economic infrastructure, we need to make sure it enhances the human experience. If you hope for the non-tech-savvy senior citizen to store and spend his or her retirement savings using the blockchain, you realistically can’t expect these people to understand anything about a public-private key cryptosystem, and worry themselves constantly about losing their seed phrase in a house fire or some other unpredictable event. The technology should be smooth, easy-to-use, and accounts should be recoverable. The value proposition for consumers to migrate from Web 2.0 to Web 3.0 is seriously in question if this is not the case. Moreover, if crypto wallet UX remains bothersome, new users will default to custodial, centralized options, and the overall rate of migration from Web 2.0 to 3.0 will remain stifled.
Enter account abstraction.
Account abstraction aims to decouple the hard-coded relationship that Signer(public key, private key) == Account. The term “abstraction” comes from the idea that we can engineer solutions to modulate this relationship in ways that we want. This means moving from EOAs to wallets created with smart contracts, which can allow us to use different cryptographic signature schemes, add multiple signers to an account, set specific rules and roles with respect to signing transactions, and more. Let us call these new abstracted accounts smart wallets. Here are the various use-cases of account abstraction via ERC-4337 and their benefits:
1. Social recovery — Wallet accounts can be customized into social recovery wallets, which are controlled by a single “signing key” that can be used to approve transactions, with some amount of “guardian” keys of which a majority can collaborate to change the signing key of the account. This way, if a user loses their signing key, they can get their guardians (whether mnemonics/keys they have on other devices, friends or family, or institutions) to re-establish a new signing key that the user has access to. Otherwise, the user will be able to use their smart wallet normally.
2. Dead man’s switch — A dead man’s switch is a mechanism that allows some person to transfer ownership of their wallet to some designated receiver after a certain time has passed. Imagine this as a Will of sorts — a person knowing they will die within some amount of time can encode a function to change the signing key of their wallet to that of a family member. This can happen after a set amount of time (say, 10 years) or can happen after a certain period of the wallet owner not doing some on-chain actions to prove they are living. This can be implemented in many interesting custom ways, hence the word “abstraction”.
3. Fraud monitoring / 2FA — For extra security, smart wallets can require that transactions need to undergo two-factor-authentication (i.e. sign the transaction with multiple keys) if those transactions fall under some special criteria. Say, for example, I want all transactions above a certain $ETH threshold, all batch transactions, or all transactions on an unfamiliar dApp to require 2FA. This can also be built in a way that requires 2FA via phone number or email by using an Oracle like Chainlink functions to make off-chain API requests. Alternatively, we will see next how signature abstraction will allow us to change the signature schemes of our smart wallets, meaning 2FA transactions can ask for key signatures not using the typical Ethereum ECDSA (like one generated on your phone hardware, for example).
4. Custom signatures schemes / signature abstraction — ERC-4337 allows custom cryptographic signature scheme for private key signatures on transactions. For example, non-ECDSA signature schemes could be used to make transaction signing quantum-resistant. Another possibility is for accounts to be re-configured to use signature schemes compatible with the secure enclave on an iPhone (a completely isolated chip that verifies cryptographic signatures for biometric data, which is how Face ID works). This would make it possible to turn smartphones into hardware wallets that can generate private keys and sign transactions through the secure enclave chip. Being able to securely sign transactions with Face ID while using your smartphone as its own hardware wallet will be a ground-breaking user experience upgrade.
5. Batch transactions — While having 2FA and more cryptographic signing tools (which are both up to the developer and user to include) makes UX sound far more tedious, batch transactions counter that. EOAs only allow one operation at a time. Smart wallets allow transactions to be executed in batches, and this can be abstracted to automate transactions with time-delay and event-driven flows (e.g. subscription models like we have in Web 2.0). This also makes transactions cheaper since many operations are bundled into single transactions, lowering the space complexity. See the image below, courtesy of Vitalik Buterin on Twitter:
How ERC-4337 signature aggregation compresses transactions: Twitter
StarkNet and zkSync, two major layer 2s, have committed to ship with native account abstraction. Argent is working on creating a standard interface for smart wallets on StarkNet using Cairo. Combining account abstraction with zk-rollups will drastically reduce transaction size through both ERC-4337 signature aggregation and rollup transaction batching. This is very positive for the future of user experience and scaling.
6. Gas abstraction —
• Gas sponsorship — someone other than the user (the paymaster, as we will see below) can pay the gas fee on transactions. For example, dApps that want to sponsor or subsidize fees for their users can cover gas fees through the ERC-4337 smart contracts.
• Pay fees with ERC-20 tokens — ERC-4337 accepts fee payments in tokens other than ETH (including the token being received in the transaction). This is massive for user experience, as you don’t need to worry about filling up your wallets with ETH for fee payments every time you want to spin up a new one. Users that spend a lot of time on chain know how tedious this can be, especially when you have to bridge assets to other chains just to pay gas for a transfer fee.
7. Roles & policies — Smart wallets can set policies like spending limits. For example, small payments can happen without signatures but large payments would require a signature. Smart wallets can also delegate specific actions to different private key signers. This would be useful for corporations operating out of one account, with rules such as:
• Payroll can pay employees once a month with a spending limit
• CFO can transfer any sum of money with a 1 day delay and a signature from another executive
• External auditor can veto delayed payments but not initiate them
The possibilities are endless.
8. Session keys — Session keys are very important for the UX of dApps that rely on continuous interaction over some period of time, like gaming apps for example. A smart wallet could generate a temporary session key for a dApp, with constraints on spending and which tokens it can access. This way, you don’t have to give the dApp permission to spend more tokens than you’d like, and you conversely don’t have to manually sign with your private key every time you make a interaction with the application. By opening a session with a game, for example, a user could play for a day without worrying that their wallet is now exposed to hacks in the future.
Smart contract wallets seem like such an obvious idea, especially with some tools like multi-signature wallets already existing. This begs the question, why has it taken until now to implement something like account abstraction? To understand this, we can take a look at the history of Ethereum Improvement Proposals (EIPs) and movements within the ecosystem that touched on smart contract wallets:
• EIP-86 (2016) — Introduces a “forwarding contract” to abstract signature verification and nonce
• 2018 — Idea of smart contract wallets is introduced, for the purpose of creating social recovery accounts and on-chain fraud monitoring
• EIP-2938 (2020) — Introduces new AA transaction (opcode) to enable smart contracts to act as top-level accounts
• EIP-3074 — Make existing EOAs act like smart contracts by allowing users to delegate control of their wallet to a smart contract
As you can see, previous proposed account abstraction solutions included Ethereum protocol changes at the consensus layer, new opcodes, different smart contract standards, and more. All of these never gained traction. With EIP-4337, the Ethereum community created decentralized account abstraction infrastructure on top of the normal Ethereum protocol, with no protocol change needed.
EIP-4337 introduces the ERC-4337 interface, which builders can use to implement into their own smart contract wallets, plus some additional infrastructure at the protocol layer including “bundlers” and alternative mempools. We will go into further details about this infrastructure below. ERC-4337 serves as a universal smart wallet interface in the form of a smart contract standard which acts as a toolset for creating wallets with abstract, customizable features.
In the future, the goal is to expand this from just a smart contract standard to a full protocol upgrade, including converting EOAs to smart contracts and introducing fundamentally new transaction types related to smart wallets (even possibly at the opcode level). The purpose of this is to move smart contract wallets from second-class citizens to first-class citizens by bringing account abstraction from the application layer (ERC-4337 as a code standard) to the protocol layer. While the ERC-4337 standard has now created account abstraction possibilities on the application layer, ways to embed smart wallets at the protocol level are still in discussion by Ethereum engineers.
• UserOperation — an ABI-encoded structure that describes a transaction to be sent on behalf of a user.
• Sender — the smart contract account (or smart wallet) sending a new user operation. Smart wallets must implement the IAccount interface of ERC-4337, with necessary function validateUserOp() and two additional functions that execute user operations and return their nonces. These wallets are deployed by a wallet deployer, which is a singleton contract that creates a wallet contract.
• EntryPoint — a pre-published, global, and singleton smart contract that contains functions to handle all bundles of user operations. Bundlers/Clients whitelist the supported EntryPoint.
• Bundler — a node (block builder) that bundles multiple user operations from the alternative mempool and creates an EntryPoint.handleOps() transaction. Not all validator nodes on the protocol level have to be bundlers. Some nodes will support user operations from the alternative mempool (thus making them bundlers) and others will not.
• Aggregator — a helper contract trusted by accounts to validate an aggregated signature. Bundlers/Clients whitelist the supported aggregators. Aggregators must implement the aggregator interface of ERC-4337.
• Paymasters — a contract that can pay for transactions instead of a smart contract wallet itself, if it has deposited enough ETH within the entry point contract to do so. Paymasters must implement the paymaster interface of ERC-4337.
The UserOperation struct:
• address sender — The account making the operation
• uint256 nonce — Anti-replay parameter; also used as the salt for first-time account creation
• bytes initCode — The initCode of the account (needed if and only if the account is not yet on-chain and needs to be created)
• bytes callData — The data to pass to the sender during the main execution call
• uint256 callGasLimit — The amount of gas to allocate the main execution call
• uint256 verificationGasLimit — The amount of gas to allocate for the verification step
• uint256 preVerificationGas — The amount of gas to pay for to compensate the bundler for pre-verification execution and calldata
• uint256 maxFeePerGas — Maximum fee per gas (similar to EIP-1559 max_fee_per_gas)
• uint256 maxPriorityFeePerGas — Maximum priority fee per gas (similar to EIP-1559 max_priority_fee_per_gas)
• bytes paymasterAndData — Address of paymaster sponsoring the transaction, followed by extra data to send to the paymaster (empty for self-sponsored transaction)
• bytes signature — Data passed into the account along with the nonce during the verification step
1. The smart wallet sends user operations to a bundler node via RPC, which subsequently adds them to the alternative UserOps mempool.
2. Bundlers, block-building nodes that support the alternative mempool, send bundles of user operations to the EntryPoint contract by calling EntryPoint.handleOps(). The rest of the operation handling is done on-chain, where the bundle transaction is validated normally and added to a block.
Notice below — the bottom two nodes support both the UserOps mempool and the normal mempool. Thus, these nodes are bundlers. The top node only pulls transactions from the mempool, not supporting user operations. This is how two mempools can coexist without having to force the consensus layer to change.
Off-chain architecture: YouTube Presentation by Yoav Weiss, Dror Tirosh
Another visual of the UserOperation flow:
UserOperation Flow Chart: Vitalik Buterin on Medium
Multiple user operations are packaged into an array which is passed as an argument to the handleOps() function on the global entry point contract. The entry point smart contract then operates in the following functionality:
The entry point’s handleOps function must perform the following steps (we first describe the simpler non-paymaster case). It must make two loops, the verification loop and the execution loop.
In the verification loop, the handleOpscall must perform the following steps for each UserOperation:
1. Create the account if it does not yet exist, using the initcode provided in the UserOperation. If the account does not exist, and the initcode is empty, or does not deploy a contract at the “sender” address, the call must fail. (*see step 1 in the flow chart below)
2. Call validateUserOp on the account. This function should be implemented in the account, as it is part of the IAccount interface. Pass in the UserOperation, and the required fee (pass in zero if using a paymaster) and signature aggregator (if there is one). The account should verify the operation’s signature, and pay the fee if the account considers the operation valid. If any validateUserOp call fails, handleOps must skip execution of at least that operation, and may revert entirely. (*see step 2 in the flow chart below)
In the execution loop, the handleOps call must perform the following for each UserOperation:
• Call the account with the UserOperation’s calldata. It’s up to the account to choose how to parse the calldata; an expected workflow is for the account to have an execute function that parses the remaining calldata as a series of one or more calls that the account should make. (*see step 4 in the flow chart below)
On chain flow: YouTube Presentation by Yoav Weiss, Dror Tirosh
Before accepting a UserOperation, bundlers should run the simulateValidation function of the entry point, to verify that the signature is correct and the operation actually pays fees. If it fails, the bundler should not add the UserOperation to the mempool.
Paymaster (gas abstraction) — When the paymaster is not equal to the zero address in the UserOperation struct, the entry point flow is slightly different, as can be seen above.
• During the verification loop, in addition to calling validateUserOp , the handleOps execution also must check that the paymaster has enough ETH deposited with the entry point to pay for the operation, and then call validatePaymasterUserOp on the paymaster to verify that the paymaster is willing to pay for the operation. Note that in this case, the validateUserOp is called with a missingAccountFunds (the gas fee parameter) of 0 to reflect that the account’s deposit is not used for payment for this user operation.
• Paymasters must implement the paymaster interface of ERC-4337, which includes the necessary validatePaymasterUserOp() function mentioned above.
• The paymaster must also have a deposit in the entry point contract from which the entry point will pull fees for user operating costs.
Here’s another useful flow diagram of ERC-4337 in action, courtesy of Messari:
As of March 1, 2023, ERC-4337 is live on Ethereum main net, making it possible for any developer to make their own smart contract wallet.
The implications of account abstraction are huge. Smart contract wallets are quintessential in the narrative of crypto reaching mainstream adoption, as they will bring user experience so much closer to being on par with traditional web2/tradFi infrastructure.
As web3 expands through the world, builders in the industry must prioritize making self-custody technology more attractive to consumers than centralized options, such as exchanges. Right now, the simplicity of custodial options triumphs over the complexity of self-custody. However, through account abstraction, the blockchain no longer has to be tacky, slow, and hard to use or understand. When the next 100 million users join crypto, we must be ready to provide them with solutions that convince them to stay and stick with decentralization.
With that being said, the pursuit of account abstraction is not over. Ethereum still has a long way to go with respect to smart accounts, especially if the goal is to completely eradicate EOAs on the protocol level. Until this is done, smart accounts will not be compatible with decentralized applications not built for ERC-4337. The protocol-level changes are going to take a lot more work from the Ethereum foundation and open source community, but the notion of native smart contract accounts on Ethereum is extremely exciting, and it will be even more rewarding.
“Account abstraction: Making accounts smarter,” YouTube, 14-Nov-2022. [Online]. Available: https://www.youtube.com/watch?v=HbNdGex47ks&t. [Accessed: 19-Mar-2023].
“ERC-4337: A complete guide to account abstraction,” BeInCrypto, 14-Mar-2023. [Online]. Available: https://beincrypto.com/learn/erc-4337/#h-unpacking-eip-4337-and-erc-4337. [Accessed: 19-Mar-2023].
“Ethereum Foundation 🛠 account abstraction: Building an ERC-4337 wallet — yoav weiss, Dror Tirosh,” YouTube, 16-Oct-2022. [Online]. Available: https://www.youtube.com/watch?v=xHWlJiL_iZA&t. [Accessed: 19-Mar-2023].
Jarrod Watts, “What is account abstraction? EIP-4337 explained,” Jarrod Watts, 24-Jan-2023. [Online]. Available: https://blog.jarrodwatts.com/what-is-account-abstraction-and-how-does-eip-4337-work. [Accessed: 19-Mar-2023].
V. Buterin, “ERC 4337: Account abstraction without ethereum protocol changes,” Medium, 10-Oct-2022. [Online]. Available: https://medium.com/infinitism/erc-4337-account-abstraction-without-ethereum-protocol-changes-d75c9d94dc4a. [Accessed: 19-Mar-2023].
“Why account abstraction is a game-changer for Dapps | Devcon Bogotá,” YouTube, 14-Oct-2022. [Online]. Available: https://www.youtube.com/watch?v=OwppworJGzs&t. [Accessed: 19-Mar-2023].
“Why we need wide adoption of Social Recovery Wallets,” Vitalik Buterin’s website. [Online]. Available: https://vitalik.ca/general/2021/01/11/recovery.html. [Accessed: 19-Mar-2023].
Y. W. (@yoavw) Vitalik Buterin (@vbuterin), “ERC-4337: Account abstraction using Alt Mempool [draft],” Ethereum Improvement Proposals, 29-Sep-2021. [Online]. Available: https://eips.ethereum.org/EIPS/eip-4337. [Accessed: 19-Mar-2023].
Zeneca, Letter 36: All about ERC-4337, 04-Mar-2023. [Online]. Available: https://zeneca33.substack.com/p/letter-36-all-about-erc-4337?sd=pf. [Accessed: 19-Mar-2023].