ERC4337:以太坊账户抽象标准详解
系列钱包与账户2 / 2
- 1Web3钱包与用户体系设计
- 2ERC4337:以太坊账户抽象标准详解
- 查看系列 →
以太坊原生账户模型将账户分为两类:EOA(Externally Owned Account)和 CA(Contract Account)。这个二元结构有一个根本性限制——只有 EOA 能发起交易,CA 只能被动响应。ERC-4337 的目标是在不修改 L1 共识层的前提下,实现账户抽象——让智能合约具备发起操作的能力,同时保持 EOA 的原生灵活性。
整体流程
- 用户创建UserOperation - 用户通过钱包应用创建一个UserOperation对象
- 发送到内存池 - UserOperation被发送到专门的内存池(alt-mempool,不是以太坊的交易池)
- Bundler打包 - Bundler从内存池中选取多个UserOperation打包
- 提交到链上 - Bundler调用EntryPoint合约执行这些操作
- 验证和执行 - EntryPoint验证每个操作并执行
关键角色
| 角色 | 职责 |
|---|---|
| 智能合约钱包 | 用户的钱包逻辑合约,定义验签规则、权限控制、限额等 |
| UserOperation | 用户意图的结构化描述,包含 callData、gas 参数、签名等,不是标准 tx |
| Bundler | 一个 EOA,把多个 UserOp 打包成一笔真实交易提交上链,赚取打包费 |
| EntryPoint | 全网唯一地址的单例合约,所有操作的审核入口,两阶段执行(验证 + 执行) |
| Paymaster | 可选模块,实现代付 gas 或 ERC-20 换算支付 gas 的逻辑 |
详细说明
1. 智能合约账户实现
每个用户的钱包是一个智能合约,需要实现以下接口:
interface IAccount { function validateUserOp( UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds ) external returns (uint256 validationData); }
validateUserOp函数负责:
- 验证签名是否有效
- 检查nonce是否正确
- 如果需要,向EntryPoint存入足够的ETH支付gas
- 返回验证结果
2. UserOperation结构
UserOperation包含以下关键字段:
{ sender: address, // 智能合约账户地址 nonce: uint256, // 防重放攻击 initCode: bytes, // 如果账户不存在,用于创建账户的代码 callData: bytes, // 要执行的操作数据 callGasLimit: uint256, // 执行调用的gas限制 verificationGasLimit: uint256, // 验证阶段的gas限制 preVerificationGas: uint256, // 额外的gas补偿 maxFeePerGas: uint256, // 最大gas价格 maxPriorityFeePerGas: uint256, // 最大优先费 paymasterAndData: bytes, // Paymaster地址和相关数据 signature: bytes // 用户签名 }
3. EntryPoint合约核心逻辑
EntryPoint是整个系统的核心,主要函数是:
function handleOps( UserOperation[] calldata ops, address payable beneficiary ) external;
执行过程分为两个阶段:
验证阶段(Verification Loop)
对每个UserOperation:
- 检查账户是否存在,不存在则用initCode创建
- 调用账户的validateUserOp函数
- 如果有Paymaster,调用Paymaster的验证函数
- 确保有足够的gas费用
执行阶段(Execution Loop)
对每个UserOperation:
- 调用账户合约执行callData中的操作
- 如果有Paymaster,调用Paymaster的后置处理函数
- 计算实际消耗的gas并退款
- 将gas费用支付给Bundler
4. Paymaster实现
Paymaster是可选的,用于赞助用户的gas费用:
interface IPaymaster { function validatePaymasterUserOp( UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost ) external returns (bytes memory context, uint256 validationData); function postOp( PostOpMode mode, bytes calldata context, uint256 actualGasCost ) external; }
Paymaster可以实现各种支付策略:
- 用ERC20代币支付gas
- 为特定用户免费
- 根据业务逻辑决定是否赞助
可实现功能
1. 社交恢复
在 validateUserOp 里实现 M-of-N 多签逻辑,将 guardian 地址集合存储在合约 storage 中。恢复流程通常引入时间锁(如 48 小时),防止 guardian 合谋或被社工攻击——在时间窗口内,原主人可以取消恢复请求。Guardian 可以是另一个 EOA、另一部手机,或者其他智能合约。Argent 钱包已在生产环境使用这套机制。
2. Gas 抽象
Paymaster 在 EntryPoint 的 validation phase 介入,分两种模式:Sponsored Paymaster 由项目方预存 ETH 到 EntryPoint,对白名单用户免 gas;Token Paymaster 则通过 Chainlink 等预言机获取 ERC-20/ETH 实时汇率,在 validatePaymasterUserOp 阶段锁定用户代币,在 postOp 阶段按实际消耗结算退款。用户全程感知不到 ETH 的存在。
3. 批量操作
callData 编码为 executeBatch(calls[]),EntryPoint 单次调用账户合约,账户合约内部顺序执行多个子调用。关键在于原子性控制——可以选择"一个失败全部回滚"或"失败跳过继续执行"两种策略,根据业务场景在合约里自行实现。典型用例:Uniswap 的 approve + swap 从两笔交易合并为一笔,节省约 30-40% gas。
4. Session Key
向合约注册一个临时 signer,存储时附带精细的权限约束:允许调用的目标合约地址白名单、单笔转账金额上限、过期时间戳。验签逻辑判断:如果是普通操作用主密钥验证,如果签名来自已注册的 session key 则走权限校验路径。链游场景里,游戏合约拿到 session key 后可在一小时内自动签名操作,时间到了权限自动失效,主资产始终安全。
5. 限额保护
在账户合约的 execute 函数里解码 callData,提取目标地址和转账金额,与预设规则比对。日限额通常用滑动时间窗口实现(记录最近 24 小时的累计金额),超出则 revert。可以叠加多层规则:单笔上限 + 日总上限 + 高风险合约黑名单。即使私钥泄露,攻击者也只能在限额内操作,为用户争取响应时间。
6. 自动化执行
账户合约预存执行条件(时间、价格阈值等),链下 keeper 网络(Gelato、Chainlink Automation)监听条件是否触发,满足时由 keeper 构造并提交 UserOperation,gas 费可由 Paymaster 代付或从用户账户扣除。相比传统方案,整个流程无需用户在线,也不需要信任中心化服务器——keeper 无法超出合约规则执行任何操作。
优势与风险
优势
无需协议升级即可部署;功能可组合,钱包逻辑完全自定义;Paymaster 机制极大降低用户门槛;L2 上 gas 开销影响有限
风险
Bundler 生态目前较集中,存在审查风险;validateUserOp 实现 bug 可能被绕过;整体攻击面比 EOA 大;固定 gas 开销在 L1 仍偏高
(Bundler 去中心化是当前最值得跟进的方向,ERC-7562 提案在试图解决这个问题。)
目前可用的实现
| 项目 | 描述 |
|---|---|
| Biconomy | 模块化 AA SDK,大量 DApp 集成,开发者友好 |
| ZeroDev | Kernel 架构,插件化,支持多种验签方式 |
| Alchemy Account Kit | 配套 Rundler 高性能 Bundler,适合高频场景 |
| Stackup | 提供完整 AA 基础设施,含 Bundler + Paymaster 服务 |
| Candide | 移动端钱包,Safe 合约为底层 |
评论
加载中…