智能账户交易卡在Bundler:3步定位失败原因

 / 
1

智能账户交易卡在 Bundler,通常卡在三个环节——模拟验证失败、Gas 估算不足、或 Nonce 冲突。按下面三步定位,比盲目重发有效率得多。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

1. 第一步:查 Bundler 返回的 AA 错误码

Bundler 在收到你的 UserOperation 后,会先做链下模拟验证(Simulation)。ERC-4337 规范为 EntryPoint 的报错保留了 AA 前缀的错误码。如果你在调用 sendUserOperation 时抛出 UserOperationExecutionError,错误信息里通常会包含一个 AA 开头的错误码。

步骤1:捕获并解析 sendUserOperation 返回的错误

  • 做什么:从你的代码或钱包日志里,找到 Bundler 返回的具体错误信息。

  • 怎么做:在代码的 catch 块里打印完整错误对象。如果用的是 permissionless.js 或 aa-sdk,可以先用 debugUserOperation 替代 sendUserOperation,它会在控制台输出详细的 AA 错误码和原因。

  • 做到什么程度算完成:你拿到了一个具体的 AA 错误码(如 AA13AA23AA31AA40 等)。

常见 AA 错误码速查

错误码含义可能原因
AA13InitCode 失败账户工厂部署失败,检查 initCode 或增加 verificationGasLimit
AA21账户未预存 Gas 费智能账户余额不足以支付 Gas,或 Paymaster 未正确配置
AA23validateUserOp 回滚签名无效、Nonce 过期或账户验证逻辑本身报错
AA25Nonce 无效Nonce 不匹配当前链上状态——用 account.getNonce() 重新获取
AA31Paymaster 存款不足你的 Gas Tank 或 Paymaster 账户余额不够
AA33Paymaster 验证失败Paymaster 配置错误,或 Gas Tank 余额不足
AA40verificationGasLimit 超限验证阶段消耗的 Gas 超过了设置的 verificationGasLimit
AA41 / AA42callGasLimit 过低/过高执行阶段的 Gas 设置不当,尝试让 Bundler 自动估算,不要手动覆盖

2. 第二步:查 Gas 估算相关报错(Precheck Failed)

如果 Bundler 在链下模拟阶段就因为"Gas 给少了"而拒绝你的 UserOperation,你会收到 "precheck failed" 类型的错误。

步骤2:检查 Gas 限制参数是否过低或过高

  • 做什么:检查 callGasLimitverificationGasLimitpreVerificationGas 这三个字段。

  • 怎么做

    • 情况A(报错 callGasLimit is X but must be at least XXXX:说明你手动设的 callGasLimit 太低。解决方案是去掉手动覆盖,让 Bundler 通过 eth_estimateUserOperationGas 自动估算。

    • 情况B(报错 verificationGasLimit is X but must be at most XXX:说明验证逻辑太复杂了,超出了 Bundler 的限额。尝试简化签名逻辑,或联系 Paymaster 服务方确认上限。

    • 情况C(报错 maxFeePerGasmaxPriorityFeePerGas 过低):网络费率波动导致你的估算过时了。用 getUserOperationGasPrice 获取最新费率,或给估算值加一个 10%-20% 的乘数。

  • 做到什么程度算完成:你确认了是哪个 Gas 参数导致 Precheck 失败,并调整了对应值。

欧易OKX交易所
全球领先的加密货币平台,适合新手与进阶交易者
新手福利:注册即享20% 交易手续费减免!

3. 第三步:检查 Nonce 冲突(最隐蔽的坑)

如果你同时向两个不同的 Bundler 发送了相同 Nonce 的 UserOperation,或者你的钱包在本地 Nonce 计数与链上不一致,会发生 Nonce 碰撞——即其中一个 Bundler 的交易上链后,另一个 Bundler 提交的包含相同 Nonce 的交易会被回滚,导致该 Bundler 白白损失 Gas 费,你的交易也卡住了。

步骤3:确认并重置 Nonce

  • 做什么:检查你的账户 Nonce 是否被"吃掉"了。

  • 怎么做

    • 情况A(怀疑并发提交):用一个工具或脚本查询 EntryPoint 合约上该账户的当前 nonce 值。确保你的下一次提交使用的是正确的 Next Nonce。

    • 情况B(收到 AA25 错误):在签名前,调用 account.getNonce() 获取最新值,而不是用缓存。

  • 做到什么程度算完成:你的提交使用了正确的 Nonce,不再收到 AA25 错误。

前置条件:你正在通过钱包或代码向 Bundler(如 Alchemy、Pimlico、Gelato 的 Bundler 节点)提交 UserOperation。

风险提醒:如果 UserOperation 在链上执行阶段回滚(比如目标合约方法不存在、余额不足),但验证阶段通过了,Bundler 依然会收取 Gas 费。如果 Bundler 因 Nonce 碰撞导致交易被回滚,它只会损失 Gas 费,不会从你账户扣钱,但你需要重新发起 UserOperation。

做完以上排查,怎么确认问题解决了?

在区块浏览器(如 Etherscan)中找到 Bundler 提交的 handleOps 交易,查看内部的 UserOperationEvent 日志 —— 如果 success 字段为 true,说明你的 UserOperation 已执行成功。如果你使用的是 Pimlico 或 Alchemy 的 Bundler,也可以调用 getUserOperationReceipt 直接查询 UserOperationHash 的链上执行状态。