SCWスワップのデコード

スマートコントラクトウォレット(SCW)では、スワップの流れは従来のEthereum/EVMウォレットとは大きく異なります。その違いは特に問題が発生したときに混乱を招くことがあります。しかし、フローの主要な関係者と、アプリやエクスプローラーで何が起きたかをステップごとに読む方法を理解すれば、状況は理解しやすくなります。

一緒に見ていきましょう。


ワンタップからオンチェーン実行まで:実際に何が起きるか

アプリで「Swap」をタップすると、1つの操作に感じられますが、実際にはEthereumのアカウント抽象化(ERC-4337)上に構築された多層的なプロセスを開始しています。通常のウォレットのようにトランザクションが直接ブロックチェーンに届くわけではなく、代わりに迂回します:

  1. 私たちがルートを構築します。ルーティングエンジン(1inchのような)に最適なパスを見つけてもらい、それが機能するかをシミュレートします。ガスを見積もり、トークンの所持を検証し、指示を特別な形式にパッケージします: UserOperation.

  2. 1つの bundler が介入します。これはUserOperationをブロックチェーンに送信する責任を持つオフチェーンのアクターです。あなたのオペレーションをチェックし、有効であることを確認し、ガスを前払いします(後で償還されます)。

  3. あなたのUserOpは EntryPoint スマートコントラクトを経由してブロックチェーンに入ります。EntryPointはすべてのSCWトランザクションが通る門のような存在です。EntryPointは最終チェックを実行し、すべてが問題なければ…

  4. EntryPointはあなたのスマートコントラクトウォレット(SCW)にスワップを実行するよう指示します。あなたのSCWはルーター(例:1inch)を呼び、ルーターがプールを呼び、トークンが移動し、出力はあなたのウォレットに戻ります。

まとめると:あなたがスワップをタップ → 私たちがシミュレート → bundlerが送信 → EntryPointが検証 → あなたのSCWが実行、です。


実際の例を見てみましょう

高レベルのフローを理解したので、実際のスワップでどのように展開するか見てみましょう:まずアプリ内で、次にオンチェーンで:

ここに見えるのは:

  • 1 USDCを0.765 KTAにスワップしました。

  • スワップはBase上で実行されました(コインシンボルのBaseアイコンに注目)。

  • 私たちが支払ったのは:

    • ガス $0.03(ETHで)

    • goodcryptoXへのスワップ手数料 0.22%

    • 1inchへのルータ手数料 0.05%

  • ルートは単純でした:Uniswap v4 プールを100%通過。

  • Bundler:Alchemy(上のステップ2を参照)

  • トランザクションがブロックチェーンに到達してブロックに記録されていれば、(失敗していても)エクスプローラーリンクが表示されます

ここまで問題なし。次にBaseScanリンクをクリックして、このトランザクションがオンチェーンでどのように見えるかを見てみましょう:

From: これはあなたのウォレットではなく、Alchemyのbundlerです。bundlerがトランザクションを送信したため、これは予想される表示です。

To: EntryPoint(v0.6.0)。再び予想される表示です — すべてのSCWトランザクションはここを通ります。

内部トランザクション: トランザクション内のネイティブトークン(Base上のETH)のフローを示します。ここで見えるのは:

  • 私たちのウォレット(…0A5)がガス費用のためにEntryPointにETHを送金しました。

  • EntryPointはbundlerに実際のガスコストを払い戻しました(bundlerがあなたに代わってガスを前払いしていたため;上のステップ2参照)。残ったETHは将来のトランザクションのための預金としてEntryPointに留まりました。

ERC-20転送: 実際のトークン移動を示します:

私たちのウォレットはUSDCを直接送っていません。代わりに、USDCトークンコントラクト(…2A8)が転送を処理して発行しました。これは正常なことです:EVMチェーンでは、トークン転送はスマートコントラクトウォレットからの指示を受けた後、トークンコントラクト自体によって処理されます。

  1. USDCコントラクトは私たちの1 USDCを3つの転送に分割しました:

    • 0.0022 USDC を私たちのプロトコルの手数料ウォレット(…608A)へ

    • 0.0005 USDC を1inchの手数料ウォレット(…1DE5)へ

    • 残りの0.9973 USDC を Uniswap v4 ルーター(…Universal Router)へ

  2. Uniswap v4 ルーターはそれを Uniswap v4 プールマネージャ(すべてのv4プールを扱う単一コントラクト)に渡しました。

  3. プールマネージャがスワップを実行しました:USDC入力 → KTA出力。

  4. KTAは1inchのAggregation Routerを経由してルーティングされ、最終的に私たちのウォレット(…0A5)に転送されました。


🧩 失敗したSCWトランザクションを解読する方法

スマートコントラクトウォレット(SCW)スワップの仕組みを理解し、成功した取引を通して見てきたので、同じツールを使って失敗した取引を解読してみましょう。

別の実例を使います:EntryPointコントラクト内で失敗したEthereum上のETH→トークンスワップです。失敗の理由は、スワップとガス費用の両方を賄うのに十分なETHがなかったためです。

アプリでスワップのステータスが「Error」と表示されたり、スワップが失敗した旨のプッシュ通知を受け取ったら、どうしますか?


ステップ1 — goodcryptoXで注文の詳細を確認する

このケースであなたが見るものは次のとおりです:

先に作成したフレームワークを使うと、すぐに気づくこと:

  • スワップのステータスは エラー (失敗?)

  • エラーメッセージは表示されていない (それは異常です)

  • ガス代がある (ブロックチェーンに到達した?)

  • ルートが表示されている (シミュレーションは問題なかった?)

  • ブロックチェーンエクスプローラーへのリンクがある (トランザクションをブロックチェーンで確認できる!)。

あなたの直感を確認しましょう:

  • その エラー ステータスはスワップが失敗したことを意味する

  • 人間向けの読みやすいエラーメッセージ(生のメッセージから翻訳されたもの)と生のエラーメッセージの両方があるはずです。エラーメッセージがないということは、明らかに何か異常が起きたことを意味します

  • ガス代があるということは、トランザクションが実際にブロックチェーンに到達し、何らかのオンチェーンの処理が行われて(ガスを消費して)いたことを意味します

  • ルートはトランザクションのシミュレーションが成功し、実行への明確なパスが得られたことを確認します

  • エクスプローラーのリンクは、たとえ失敗していてもトランザクションがブロックチェーンに到達したことを確認します — そのうちの一つを必ず開いて詳しく調査するべきです


ステップ2 – ブロックチェーンエクスプローラーでトランザクションを開く

何が起きたかを見るためにEtherscanのリンクをタップします:

一見すると、状況はさらに混乱しています:

  • ステータスは ✅ 成功 と表示されている — え、何だって?!

  • しかし私たちは既にスワップが 成功していないことを知っています

  • 「To」フィールド(EntryPoint)の下に、小さな黄色のメッセージがあります:

    1つ以上のエラーが発生しました [execution reverted] コントラクト実行が完了しました

では、ここで実際に何が起きているのでしょうか?

先に紹介したSCWトランザクションのフローを思い出してください:

  • バンドラーはあなたのスワップをに包みます UserOperation (あなたのスワップロジックを含むデータパッケージ)

  • それからそれをEntryPointスマートコントラクトに送ります

  • EntryPointはそれを検証します(残高、署名、nonce をチェック)

  • すべて問題なければ、ルーターやプールを呼び出し、トークンを移動させるなど、あなたの意図を実行します。

しかしブロックチェーンの観点では、この全体は単に「バンドラーがデータをEntryPointに送った」ように見えます。

SCWの用語では、このステップは 外側の トランザクションと呼ばれます。

そしてそのトランザクションは成功しました:データは届けられ、EntryPointは内部ロジックの実行を開始しました。したがって上部に ✅ 成功 が表示されます。


しかしエクスプローラーは丁寧に、何かが失敗したことも知らせてくれます 内部で EntryPointの小さな黄色い注記で。エクスプローラーにとって、その内部の失敗だけではトランザクションを失敗とマークするには十分ではありません。

さて、概要タブで別の詳細が目に入ります:

  • $6 相当のETHがあなたのウォレットからEntryPointに送られました(ガス前払い)。

  • わずか $2.3 分のETHがバンドラーに払い戻されました。

  • そして上部に表示されているトランザクション手数料はさらに低く、約 $2.15.

一見すると、これらの数値は合わないように見えます。調査を続ける前にまずそこを解きほぐしましょう


ステップ3 – ガスの差分を理解する

内訳は次のとおりです:

  • SCW → EntryPoint (約$6):これはガスのプレファンドです。EntryPointは常にUserOpを実行できるように必要以上に徴収します。

  • EntryPoint → Bundler (約$2.3):これは実際のガスの払い戻しです。これは あなたが実際に支払った金額 この失敗した試行に対して。

  • トランザクション手数料 (約$2.15):これはバンドラーがあなたのUserOpをEntryPointに送るために支払った金額です。EntryPoint自体が検証とバンドラーへの払い戻しの際に追加のガスを使用したため、これより低くなっています — その追加費用はあなたに課せられました。

経験則:

👉 真のガスコストは常にEntryPoint ➜ Bundlerの払い戻しです(上部に表示される「トランザクション手数料」ではありません)

そして、あなたがプレファンドした金額($6)と払い戻された金額($2.3)の差は消えたわけではありません。差額はEntryPointにあなたのデポジットとして残り、次のトランザクションに自動的に適用されます。


ステップ4 – AA Transactionsタブを確認する

エクスプローラーでは、 AA Transactions タブ(AA = アカウント抽象化)を確認できます。SCWはアカウント抽象化(ERC-4337)で動作するため、ここにスマートコントラクトウォレットのアクティビティが表示されます。

概要からそのタブに切り替えましょう:

ここでようやく、UserOperationがバンドラーの外側のトランザクション内の別個のエントリとしてリストされているのが見えます:

  • 「From」フィールドには現在 私たちのウォレットアドレスが表示され、これが私たちの操作であることを確認できます。

  • 外側のトランザクションハッシュとは別のAA Txn Hashが存在します。なぜでしょう?

    • 外側のTxn Hashは、あなたのUserOpを含んでいたBundler->EntryPointトランザクションに属します(さまざまなユーザーの複数のUserOpが含まれていた可能性があります)。

    • AA Txn Hashは、そのバンドル内での あなたの UserOperationの一意の識別子です。

これがバンドリングの重要な考え方です:

  • バンドラーは多くのUserOpをひとつのトランザクションにまとめることができます。

  • 各UserOpには独自のAA Txn Hashが付与されるため、バンドル内で個別に追跡できます。

  • 今回の場合、これは古いトランザクション(400日以上前)で、当時はSCWがまだ珍しく、バンドルに私たちのUserOpだけが含まれていたため、タブには「AA Transactions (1)」と表示されています。新しいトランザクションでは、複数のUserOpがひとつのバンドルにまとめられていることがよくあります。

このビューでは、AA Txn Hashの隣に (!) アイコンが表示されているのにも気づくでしょう — あなたのスワップが実行されなかったことの確認です。

次のステップはAA Txn Hashをクリックすることです。これにより専用のUserOperationページが開き、スワップ試行の詳細 — 手数料、送金、失敗箇所 — をすべて確認できます。


ステップ5 – AA トランザクションの詳細ページを開く

AA Txn Hashをクリックすると、あなたのUserOperation専用の詳細ページに移動します:

ここでようやく、実際のスワップ試行が明確に表示されます:

  • ステータス: x 失敗 (今回は曖昧さはありません)

  • From:あなたのスマートコントラクトウォレットのアドレス

  • AA トランザクション手数料:~0.00231 ETH($2.31)。これはあなたが支払った実際のガスコストです — バンドラーに送られた払い戻しです。

  • 内部トランザクション:SCWからEntryPointへの約0.00145 ETH($6.36)の1件の送金(ガスのプレファンド)。他に送金は発生しておらず、スワップ自体は実行されなかったことを確認しています。

  • バンドルTxnハッシュ:外側のバンドラートランザクションへリンクする形で表示されています。

このページはようやくあなたの直感と一致します:これが実際のトランザクションです — あなたのスワップ試行を表すUserOperationです。

これで調査はほぼ完了です。しかしここまで来たので、次もクリックしてみましょう: Internal Txns.


ステップ6 – Internal Transactionsタブを確認する

AAトランザクションビュー内のInternal Txnsタブに切り替えます:

ここではEntryPointがあなたの代わりに実行しようとしたステップごとのアクションが表示されます:

  1. ✅ あなたのSCW → EntryPointへの転送(約0.00145 ETH、約$6.36)=ガス用の前払い。これは成功しました。

  2. ❌ あなたのSCW → Uniswap Universal Routerへの実行(約0.002 ETH)=試みられたスワップ。これは失敗しました。

この内訳が失敗の原因を説明します:

  • あなたはガス用の前払いとしてETHをEntryPointに正常に送金しました。

  • しかしEntryPointがスワップのためにETHをUniswapに転送しようとしたとき、その試みは失敗しました。

最も詳細な内訳はLogsタブを開くと確認できます。


ステップ7 – Logsタブを調査する

Logs (3) をクリックします:

ここには3つの重要なイベントがあります:

  • Deposited → あなたのガス用前払いがEntryPointに受領されたことを確認します。

  • BeforeExecution → EntryPointがあなたのUserOperationの処理を開始したことを示します。

  • UserOperationEvent success: False — あなたのUserOpが失敗したというオンチェーンの正式な記録です。


実際に何が起きたのか(要約)

この種の失敗は、入力がネイティブトークン(ETH、BNB、MATIC…)であるEVM上のSCWを使ったスワップに特有のものです。

  • ギャップ:バンドラーもEntryPointも、ガス用前払いとスワップの両方を合わせてカバーするのに十分な ネイティブトークン をあなたが持っているかどうかを確認していません。彼らはこれらを別々にしかチェックしません—「ガスは十分か?」と「スワップは十分か?」。だからシミュレーションは通ったのです。

  • このようなケースに備えてアプリにはフェールセーフを組み込み、インターフェイス上でガスが不足する可能性があることを警告しました。しかしシミュレーションが問題なさそうだったため、あなたはそれでも先に進むことができました。

  • あなたが確認すると、バンドラーはあなたのUserOperationをEntryPointに提出しました。

  • EntryPointは前払いとして約$6相当のETHを取り込みました。

  • スワップを実行しようとしたとき、スワップと両方を賄うのに十分なETHが残っていませんでした そして 同時に前払いを賄うだけの額もありませんでした。

  • スワップ呼び出しはEntryPoint内部でリバートしました。

  • あなたはそれでも約$2.3のガス(バンドラーへの払い戻し)を支払いました。

  • 未使用の約$3.7はあなたのデポジットとしてEntryPointに残り、次のトランザクションで自動的に使用されます。

最終更新