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

 / 
147

智能账户交易卡在 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 错误码(如 AA13、AA23、AA31、AA40 等)。

常见 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 限制参数是否过低或过高

  • 做什么:检查 callGasLimit、verificationGasLimit、preVerificationGas 这三个字段。

  • 怎么做:

    • 情况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(报错 maxFeePerGas 或 maxPriorityFeePerGas 过低):网络费率波动导致你的估算过时了。用 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 的链上执行状态。