Before the abstract of an account introduced in ERC-4337, the authorization process included checking only the following:

  1. Account’s key pair (elliptive-curve cryptography or ECDSA)
  2. Account’s nonce (Number-once)
  3. Account’s balance (prevention of overspending)

However, account abstraction was introduced, without any changes to the consensus protocol, to allow “pseudo-transactions” called UserOperations that end up being executed from a separate mempool into packages called bundle transactions by a special class of actors called bundlers after they make a call to the handleOps function of the special EntryPoint contract. Since this requires only external bundler nodes that direct back to the mainnet in the way it expects, this ERC already has a few popular implementations despite being closed.

This allows custom verification logic to be written in a deployed account-contract, and only a request made from an EOA, that the entrypoint contract adds to the chain by calling the account. Since the EOA sends UserOperations instead of ETH Transactions, and they send them to an alternative mempool instead of the Ethereum mempool, there is no gas involved.

This manages to diversify not only the verification logic which was original restricted to private-key cryptography, but also the individual involved in a transaction, since the account-contract needn’t be deployed by the same individual that wants to transact. Additionally, the concept of a paymaster also diversifies whose pocket the transaction fee comes from.

Actors involved in Account Abstraction

https://github.com/Cyfrin/minimal-account-abstraction Actors involved in Account Abstraction

Process Flow of Entrypoint contract

Entrypoint process flow

  1. User deploys Account or Account-factory contracts

    • Account contract provides the custom validation logic to validate any user-operation transactions (by implementing IAccount.validateUserOp)
    • Account-Factory contract is responsible for deploying the Account contract and provides benefits including:
      • No dependence on a particular entrypoint contract - A new account contract may be deployed if a new entrypoint contract is to be used. Including entrypoint mutability in the contract would lead to more gas consumption
  2. (Only if user deployed Account-factory contract instead of Account contract) User sends a special User-Operation to delegate to the entrypoint the duty of initializing (deploying) their account. This user-operation includes deployment calldata in the initCode field

  3. User sends a User-Operation to an alternative mempool where it is picked up by a bundler

  4. The bundler, after bundling a group of user-operations (which need not be from the same sender) sends them to an entrypoint

Responsibilities of handleOps

1. Verification Loop

  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.

  2. Calculate the maximum possible fee the account needs to pay (based on validation and call gas limits, and current gas values)

  3. Calculate the fee the account must add to its “deposit” in the EntryPoint

  4. Call validateUserOp on the account, passing in the UserOperation, its hash and the required fee. 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.

  5. Validate the account’s deposit in the entryPoint is high enough to cover the max possible cost (cover the already-done verification and max execution gas)

2. Execution Loop

  1. 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.

  2. If the calldata starts with the methodsig IAccountExecute.executeUserOp, then the EntryPoint must build a calldata by encoding executeUserOp(userOp,userOpHash) and call the account using that calldata.

  3. After the call, refund the account’s deposit with the excess gas cost that was pre-charged.

  4. A penalty of 10% (UNUSED_GAS_PENALTY_PERCENT) is applied on the amounts of callGasLimit and paymasterPostOpGasLimit gas that remains unused.

  5. This penalty is necessary to prevent the UserOps from reserving large parts of the gas space in the bundle but leaving it unused and preventing the bundler from including other UserOperations.

  6. After the execution of all calls, pay the collected fees from all UserOperations to the bundler’s provided address