解码 SCW 兑换
使用智能合约钱包(SCW)时,交易路径与传统以太坊/EVM 钱包有很大不同。这种差异可能令人困惑,尤其是在出现问题时。但一旦你了解流程中的关键参与者,以及如何在应用和区块链浏览器上逐步读取发生了什么,事情就会开始变得清晰。
让我们一起逐步查看。
从一次点击到链上执行:实际发生了什么
当你在应用中点击“兑换/Swap”时,感觉像是一个单一操作。实际上,你启动的是一个建立在以太坊账户抽象(ERC-4337)之上的多层流程。你的交易不会像普通钱包那样直接发送到区块链。相反,它会绕道而行:
我们构建路由。我们请求路由引擎(如 1inch)为你的兑换找到最佳路径,并进行模拟以确保其可行。我们估算 Gas,验证你拥有相应代币,并将操作指令打包成一种特殊格式:一个
UserOperation.一个
bundler(打包器)介入。这是一个链下角色,负责将 UserOperations 提交到区块链。它会检查你的操作、确保其有效,并为你预付 Gas(稍后获得报销)。你的 UserOp 通过
EntryPoint智能合约进入区块链。把 EntryPoint 想象成所有 SCW 交易必须通过的唯一入口。EntryPoint 会进行最终检查,如果一切正常……EntryPoint 会指示你的智能合约钱包(SCW)执行兑换。你的 SCW 调用路由器(例如 1inch),路由器调用资金池,代币移动,输出回到你的钱包。
总结一下:你点击兑换 → 我们模拟 → bundler 提交 → EntryPoint 验证 → 你的 SCW 执行。
让我们看一个真实示例
既然我们了解了高层流程,让我们看看在一次真实兑换中这是如何发生的:先在应用中,再在链上查看:

我们看到的是:
我们用 1 USDC 兑换得到了 0.765 KTA。
该兑换在 Base 上执行(注意币符号上的 Base 图标)。
我们支付了:
0.03 美元的 Gas(以 ETH 支付)
0.22% 的兑换费用支付给 goodcryptoX
0.05% 的路由器费用支付给 1inch
路由很简单:100% 通过一个 Uniswap v4 池。
Bundler:Alchemy(参见上文第 2 步回顾)
如果交易已经到达区块链并被写入区块(即使失败),会出现浏览器链接
到目前为止,一切良好。接下来,让我们点击 BaseScan 链接查看该交易在链上的样子:

来自: 这不是你的钱包——是 Alchemy 的 bundler。这是预期之内,因为 bundler 提交了交易。
到: EntryPoint(v0.6.0)。同样是预期之内——所有 SCW 交易都通过这里进入。
内部交易(Internal Transactions): 显示交易中本原生代币(在 Base 上为 ETH)的流动。我们看到的是:
我们的钱包(…0A5)向 EntryPoint 发送了 ETH 作为 Gas 费用。
EntryPoint 按实际 Gas 成本向 bundler 报销(因为 bundler 代表你预付了 Gas;参见上文第 2 步)。任何剩余的 ETH 会留在 EntryPoint 作为你未来交易的存款。
ERC-20 转账: 显示实际的代币流动:
我们的钱包并未直接发送 USDC。相反,USDC 代币合约(…2A8)处理并发起了这些转账。这是正常的:在 EVM 链上,代币转账由代币合约在收到来自你的智能合约钱包的指令后执行。
USDC 合约将我们的 1 USDC 拆分为三个转账:
0.0022 USDC 到我们协议的费用钱包(…608A)
0.0005 USDC 到 1inch 的费用钱包(…1DE5)
剩余的 0.9973 USDC 到 Uniswap v4 路由器(…Universal Router)
Uniswap v4 路由器 将其传递给 Uniswap v4 池管理器(一个管理所有 v4 池的单一合约)。
池管理器执行了兑换:USDC 进入 → KTA 出来。
KTA 通过 1inch 的聚合路由器返回并转发到我们的钱包(…0A5)。
🧩 如何解析失败的 SCW 交易
既然我们了解了智能合约钱包(SCW)兑换的工作原理——并已经演示了成功的交易——让我们用相同的工具来解析一次失败的交易。
我们将使用另一个真实案例:一次在以太坊上将 ETH 换成代币的交易,该交易在 EntryPoint 合约内部失败,因为没有足够的 ETH 同时覆盖兑换和 Gas 费用。
好,所以你在应用中看到“错误/Error”作为兑换状态,或收到推送通知说兑换失败。你该怎么做?
步骤 1 — 在 goodcryptoX 中检查订单详情
在此情况下你会看到如下内容:

使用我们之前开发的框架,你会很快注意到:
兑换状态是
Error(错误)(失败?)没有显示错误信息 (这不寻常)
有 Gas 费用 (到达区块链了吗?)
显示有路由 (模拟通过了吗?)
有区块链浏览器的链接 (我可以在区块链上检查该交易!)
让我们验证你的直觉:
该
Error(错误)状态 表示兑换失败应同时有可读的错误信息(从原始信息翻译)和原始错误。缺少错误信息绝对意味着出现了异常情况
有 Gas 费用确实意味着交易已经到达区块链并发生了一些链上活动(消耗了 Gas)
路由确认交易模拟通过并产生了明确的执行路径
浏览器链接确认交易到达了区块链——即使它失败了。我们应该打开其中一个链接进一步调查
步骤 2 – 在区块链浏览器中打开该交易
你点击 Etherscan 链接查看发生了什么:

乍看之下,情况变得更令人困惑:
状态显示 ✅ Success(成功) — 等等,什么?!
但我们已经知道该兑换 并未完成
在 “To” 字段(EntryPoint)下,有一条小的黄色信息:
“虽然发生了一个或多个错误 [execution reverted] 合约执行已完成”
那到底是怎么回事?
记住我们之前讲过的 SCW 交易流程:
bundler 将你的兑换打包成一个
UserOperation(一个包含你兑换逻辑的数据包)然后将其发送到 EntryPoint 智能合约
EntryPoint 验证它(检查你的余额、签名和 nonce)
如果一切检查通过,它会执行你的意图——调用路由器、资金池并移动代币。
但从区块链的角度来看,整个事情看起来只是“bundler 向 EntryPoint 发送数据”。
在 SCW 术语中,这个步骤被称为 外部 交易。
而且该交易确实成功了:数据被传递,EntryPoint 开始运行其内部逻辑。因此顶部显示 ✅ Success。
但浏览器出于礼貌,仍会告诉你内部有事情失败了, 在 EntryPoint 内部,用那条小黄条提示。对于浏览器来说,内部的失败不足以将整个交易标记为失败。
现在,在概览(Overview)标签上另一个细节跳了出来:
大约 $6 价值的 ETH 从你的钱包发送到 EntryPoint(作为 Gas 的预付)。
只有 $2.3 价值的 ETH 被报销给 bundler。
而顶部显示的交易费用更低——大约 $2.15.
乍一看,这些数字似乎不一致。在继续调查之前,让我们先把这部分拆开来说明
步骤 3 – 了解 Gas 差异
下面是明细:
SCW → EntryPoint (约 $6):这是 Gas 的预付。EntryPoint 总是收取比运行 UserOp 所需更多的金额以确保你的 UserOp 能执行。
EntryPoint → Bundler (约 $2.3):这是实际的 Gas 报销。这是 你为这次失败尝试实际支付的金额, 。
交易费用(Transaction Fee) (约 $2.15):这是 bundler 为将你的 UserOp 发送到 EntryPoint 所花费的费用。它看起来更低,是因为 EntryPoint 在验证和报销 bundler 时本身使用了额外的 Gas——那部分额外费用由你承担。
经验法则:
👉 你实际的 Gas 成本始终是 EntryPoint ➜ Bundler 的报销(而不是顶部显示的“交易费用”)
你预付的金额(约 $6)与被报销的金额(约 $2.3)之间的差额并没有消失。它留在 EntryPoint 作为你的存款,将自动用于你下一笔交易。
步骤 4 – 检查 AA Transactions(AA 交易)标签
在浏览器上,你会看到一个 AA Transactions 标签(AA = Account Abstraction,账户抽象)。这是智能合约钱包活动所在的位置,因为 SCW 在账户抽象(ERC-4337)下运行。
让我们从概览切换到该标签:

在这里你终于会看到我们的 UserOperation 被列为 bundler 外部交易内的一个单独条目:
"From" 字段现在显示 我们的钱包地址,确认这是我们的操作。
有一个单独的 AA 事务哈希,与外部交易哈希不同。为什么?
外部交易哈希属于包含你 UserOp 的 Bundler->EntryPoint 交易(该交易可能包含来自不同用户的多个 UserOp)。
AA 事务哈希是你 的 UserOperation 在该打包内的唯一标识符。
这是打包的关键理念:
一个 bundler 可以将许多 UserOps 打包到一个交易中。
每个 UserOp 都有自己的 AA 事务哈希,因此可以在打包内被单独跟踪。
在我们的案例中,因为这是一个较早的交易(400 多天前),SCW 仍然很少,打包内只包含我们的 UserOp——这就是该标签显示 “AA Transactions (1)” 的原因。在更新的交易中,你经常会看到多个 UserOp 被批量打包在一个包中。
在此视图中,你还会注意到在你的 AA 事务哈希旁边有一个 (!) 图标——确认你的兑换没有执行成功。
下一步是点击 AA 事务哈希。这会打开专门的 UserOperation 页面,你将在那里看到我们尝试兑换的完整详情——费用、转账以及失败点。
步骤 5 – 打开 AA 交易详情页
点击 AA 事务哈希会将你带到该 UserOperation 的专用详情页面:

在这里你终于可以清楚地看到我们实际的兑换尝试:
状态: x 失败(Fail) (这次没有歧义)
From:你的智能合约钱包地址
AA 交易费用:约 0.00231 ETH(约 $2.31)。这是你实际支付的 Gas 成本——即报销给 bundler 的金额。
内部交易:一笔约 0.00145 ETH(约 $6.36)从你的 SCW 到 EntryPoint(作为 Gas 预付)。没有其他转账发生,这证实兑换本身从未执行。
Bundle 交易哈希:也会显示,链接回外部的 bundler 交易。
该页面最终与您的直觉相符:这才是真正的交易——代表你兑换尝试的 UserOperation。
这几乎就结束了我们的调查。但既然我们已经走到这一步,让我们也点击 Internal Txns(内部交易).
步骤 6 – 检查 Internal Transactions(内部交易)标签
在 AA 交易视图内切换到 Internal Txns 标签:

在这里你可以看到 EntryPoint 代表你尝试执行的逐步操作:
✅ 从你的 SCW → EntryPoint 转账(约 0.00145 ETH,约 $6.36)= Gas 预付。此操作成功。
❌ 从你的 SCW → Uniswap Universal Router 执行(约 0.002 ETH)= 试图执行兑换。此操作失败。
该分解说明了失败的原因:
你成功地将 ETH 发送到 EntryPoint 作为 Gas 预付。
但当 EntryPoint 试图将 ETH 转发给 Uniswap 以执行兑换时,该尝试失败了。
要获取最详细的分解,请打开日志(Logs)标签。
步骤 7 – 检查 Logs(日志)标签
点击 Logs(3):

在这里你会找到三个关键事件:
Deposited(已存入) → 确认你的 Gas 预付已被 EntryPoint 接收。
BeforeExecution(执行前) → 显示 EntryPoint 已开始处理你的 UserOperation。
UserOperationEvent(用户操作事件) →
success: False(成功:否)——这是链上对你的 UserOp 失败的规范记录。
实际发生的情况(综合说明)
此类失败特定于在 EVM 上使用 SCW 的兑换场景,且输入为本原生代币(如 ETH、BNB、MATIC…)的情况。
差距在于:无论是 bundler 还是 EntryPoint 都不会检查你是否有足够的 本原生代币 同时覆盖 Gas 预付和兑换本身。他们只分别检查——“够支付 Gas 吗?”和“够兑换吗?”。这就是模拟通过的原因。
我们已在应用中为这些情况构建了一个保险措施,在界面中提醒你 Gas 可能不足。但由于模拟看起来正常,你仍然可以继续点击确认。
一旦你确认,bundler 将你的 UserOperation 提交给 EntryPoint。
EntryPoint 拉入了约 6 美元的 ETH 作为预付。
当它尝试执行兑换时,剩余的 ETH 不足以同时覆盖兑换 和 和预付金额。
兑换调用在 EntryPoint 内部回滚(revert)。
你仍然支付了约 $2.3 的 Gas(作为对 bundler 的报销)。
未使用的约 $3.7 留在 EntryPoint 作为你的存款,将在下一笔交易中自动使用。
最后更新于