W3
EIP-4337ERC账户抽象Final(2023-03-01)

账户抽象(Account Abstraction)

不改协议层就实现智能合约钱包:用 UserOperation 替代交易,由 Bundler 代发,Paymaster 可代付 Gas。

适用链:以太坊主网 + Arbitrum / Optimism / Base / Polygon 等(需有 EntryPoint 与 Bundler)

为什么重要:它解决了 EOA 的三个硬伤:私钥丢失即资产全丢、必须持有原生币才能操作、多步操作要多次签名。社交恢复、无 Gas 交易、批量执行、会话密钥(session key)都建立在它之上。

函数签名与选择器

选择器是签名的 keccak256 前 4 字节;事件则是完整的 32 字节 topic0。 点一下即可复制。

签名 / 字段选择器 / topic0说明
EntryPoint.handleOps(UserOperation[],address)Bundler 调用的总入口,按顺序执行一批 userOp。
EntryPoint.getUserOpHash(UserOperation,bytes32)计算 userOp 哈希,签名必须签这个值(而不是 userOp 本身的编码)。
IAccount.validateUserOp(UserOperation,bytes32,uint256)账户自己验证签名与 Gas 预付款,返回 0 表示验证通过。
EntryPoint.simulateValidation(UserOperation)调试接口:本地模拟验证阶段,定位 AA 系列错误码。
UserOperation.sender发起操作的智能账户地址。
UserOperation.nonce非简单递增:高 192 位是 key(可用多个并行 nonce 通道),低 64 位是序号。
UserOperation.callData账户要执行的实际调用,通常是 execute(dest, value, func) 的编码。
UserOperation.paymasterAndDatav0.6:paymaster 地址 + 额外数据。v0.7 拆分成了四个独立字段。
UserOperation.signature账户自定义的签名数据,EntryPoint 不解析,直接透传给 validateUserOp。

代码模板

最小智能账户(validateUserOp + execute)
最小智能账户(validateUserOp + execute)Solidity

真实项目用 OpenZeppelin 的 Account + ECDSA 库(或 SimpleAccount 参考实现),它们处理了 EIP-191 前缀、可延展性与批量执行。

客户端:构造并发送 UserOperation
客户端:构造并发送 UserOperationTypeScript

常见 AA 错误码(都出现在 error.message 前缀里):AA21 预付款不足、AA22 费率过低、AA23 验证超限、AA25 nonce 无效。

实现与使用时的常见陷阱

  • 必须签 userOpHash,不能签 userOp 的编码结果——后者在不同链/不同 EntryPoint 上不可区分,会被重放。
  • v0.6 与 v0.7 的 UserOperation 结构不兼容(paymasterAndData 与 initCode 被拆成多个字段),接入前先确认 Bundler 与 EntryPoint 版本。
  • validateUserOp 里能调的存储范围受 ERC-7562 验证规则限制,不能读任意外部合约状态,否则 Bundler 会拒绝该操作。
  • Paymaster 有余额与抵押(stake)要求,欠费后所有依赖它的账户会集体无法发交易。
  • UserOp 的 nonce 是 256 位:高 192 位是 key,可以用不同 key 并行发多笔而不互相阻塞。

相关标准

想把这个标准用起来?开发者路径的第 1–2 阶段讲了怎么把它写进项目;合约 IDE里有对应的可编辑模板与静态自检;链上 API 参考则给出前端调用它的三种写法。