你发起一笔包含多个调用的批量交易,钱包只弹了一次确认。你心里可能犯嘀咕:如果中间某个调用失败了,后面的还会继续执行吗?
答案是:取决于交易怎么打包的。如果交易是原子的,一个失败全部回滚;如果不是,部分失败后剩下的仍可能执行,并且你可能看不出异常。
先搞懂:批量交易的两种模式
现在主流的批量交易有 ERC-5792(钱包级)和 EIP-7702(账户级)两种实现。
原子执行(Atomic):所有调用要么全部成功,要么全部失败。任何一步 revert,整笔交易回滚,链上不会留下部分执行的状态。EIP-7702 的 delegate 合约通过 execute 函数执行批量调用时就是原子的——如果任何一个子调用 revert,整个批次都会回滚。Base 文档也确认这个原子性的保证:所有交易必须一起成功,否则一起失败。
非原子执行(Non-Atomic):各调用独立执行,前一个失败不影响后面的。EIP-5792 在最新修订中支持钱包返回 atomic 字段来明确执行模式:"strict" 代表原子执行;"loose" 代表以多笔交易原子执行;"none" 代表非原子执行。
风险提醒:如果钱包走的是非原子模式,前几个调用失败了,后面的调用还是可能继续执行。而你只签了一次名,可能以为整笔交易已经"失败"了,实际上某些操作已经上链。
错误结果展示:部分成功的"半成品"状态
很多人遇到的情况是这样的:
钱包弹出一个批量交易确认,你点了确认。
区块浏览器显示这笔交易状态为"Success"。
但实际操作的结果是:前两个调用成功了,第三个因为 Gas 不足或参数错误 revert 了。
链上留下了"部分成功"的状态:你授权了某个代币,或者花了一笔 Gas,但最终想要的操作没完成。
因为你只签了一次名,直觉上会以为"这笔交易要么全成要么全没成"。但非原子模式下,"部分成功"就是"部分成功"。
还原错误路径:用户是怎么踩到这个坑的
第一步:钱包没有明确告知执行模式 有些钱包在处理批量交易时,不会在签名界面清晰标注"原子"还是"非原子"。用户只看到"一笔交易,一次确认",以为是一笔传统交易。
第二步:调用链中的某个环节失败 比如一个批量交易包含:① 授权 USDT → ② Swap → ③ 提现。第①步成功了,第②步因为滑点超出预期 revert 了。EIP-7702 的原子模式会回滚所有操作;但非原子模式下,第③步可能仍会继续执行。
第三步:用户只查交易状态,不查内部调用 大多数用户查交易只看顶层的"Success"或"Fail"。如果顶层状态是 Success,但内部某个调用失败了,区块浏览器的"Internal Transactions"或"Calls"标签页里其实会显示失败记录,但很多人不会去看。
正确做法对比
| 做法 | 说明 |
|---|---|
| 错误做法 | 只看顶层交易状态,默认"成功=全成功"。 |
| 正确做法 | 1. 确认钱包是否支持原子执行(查 wallet_getCapabilities 的 atomic 字段)。2. 如果钱包不支持原子执行,对于相关操作(如 Swap 组合),避免使用批量批处理,改用单独交易。3. 交易后,在区块浏览器查看"Internal Transactions"确认所有子调用状态。 |
举一反三的排查清单
| 排查项 | 安全状态 | 危险信号 |
|---|---|---|
| 钱包的 atomic 支持 | 明确支持原子执行 | 不支持或状态未知 |
| 签名界面提示 | 清晰标注执行模式 | 只显示"确认"没说明是否原子 |
| 交易后检查 | 查看 Internal Transactions | 只看顶层状态 |
| 调用顺序 | 了解每个调用的依赖关系 | 调用之间有顺序依赖但不知道 |
操作完成的校验方式: 在区块浏览器打开你刚执行的批量交易哈希,展开"Internal Transactions"或"Calls"标签页,确认每一个子调用的状态都是"Success"。如果发现有任何一个子调用 revert,而交易顶层状态却是 Success,说明你在一个非原子环境下操作,需要单独重试失败的步骤。



