Keys, wallets & account abstraction

ERC-4337

ERC-4337 is the standard that delivers account abstraction on Ethereum without any change to the core protocol. Earlier attempts needed a hard fork; ERC-4337 instead builds a parallel transaction system on top of the existing chain, so smart-contract wallets gained first-class features on Ethereum as it already was. Its singleton EntryPoint contract was deployed to mainnet in March 2023.

The flow works like this. Instead of sending a normal transaction, a user signs a UserOperation — a structured object expressing their intent — and submits it to a separate, higher-layer mempool. Specialized actors called bundlers collect many UserOperations, validate them, and pack them into a single ordinary Ethereum transaction that calls the global EntryPoint contract. The EntryPoint then, for each operation, calls the user's smart-contract account: first its validateUserOp function (which runs whatever custom signature or policy check the account defines), then its requested action. An optional paymaster contract can be invoked to sponsor the gas.

Two design choices make it robust. First, the validation step is sandboxed: bundlers simulate each UserOperation and a set of rules restricts what validation may touch, so a bundler can be confident the operation will pay before it spends gas including it — this stops denial-of-service griefing in the alt-mempool. Second, because everything routes through one audited EntryPoint, accounts and paymasters share a common, well-reviewed settlement and gas-accounting core rather than each reinventing it. The costs are real, though: a UserOperation carries verification overhead and is generally more expensive in gas than a plain EOA transfer, and the bundler/paymaster layer adds infrastructure that must stay live and honest.

// EntryPoint, simplified, per UserOperation:
function handleOps(UserOperation[] ops, address payable beneficiary) {
  for (op in ops) {
    account = op.sender;
    account.validateUserOp(op, opHash, missingFunds); // custom auth runs here
    if (op.paymasterAndData.length) paymaster.validatePaymasterUserOp(op, ...);
    (success, ) = account.call(op.callData);          // the user's intended action
    // gas is metered and refunded to `beneficiary` (the bundler)
  }
}

The EntryPoint validates then executes each UserOperation, reimbursing the bundler from the account or paymaster.

A frequent misunderstanding is that ERC-4337 UserOperations are 'transactions'. They are not — to the base protocol they are just calldata until a bundler wraps them in a real transaction. That is why they live in their own mempool and why their inclusion depends on bundlers, not directly on block proposers.

Also called
account abstraction via entry pointEntryPoint 帳戶抽象化