こんにちは、よだかです。
今日は、DeFiアービトラージbotの執行環境の整備を進めました。
これまでは、DEX間の価格差を観測し、取引数量やガス代、実行に必要な時間などを考慮して、実際に利益を取得できる可能性があるかを調べてきました。
最近はそこから一歩進み、検出した裁定候補を実際の取引につなげるための執行部を構築しています。
今回、特に大きく進展したのは、botの管理用インターフェース(UI)の実装です。
管理ウォレットの確認、チェーンごとの設定、スマートコントラクトの配置、各種権限の管理などを、ブラウザから操作できるようになりました。
もともと管理UIを作ることが目的だったわけではありません。
執行部の設定を進めるうちに、扱う項目が複雑になり、細かな操作を一つずつ手作業で行うことに不安を感じていました。その問題を解消するためにCODEXと開発を進めた結果、想像していた以上に実用的な管理画面が出来上がりました。

今回は、この管理UIがどのような技術で構成され、実際の取引環境とどう接続されているのかを整理します。
なお、具体的な裁定経路や運用パラメータなど、取引上の優位性に関係する情報は一部省略しています。
1.DEX Arbの執行準備が新たな課題になる
これまで進めてきたDEX Arb研究では、価格差が存在することと、その価格差から実際に利益を取得できることを区別してきました。
以前の開発記録#600「DEX Arbの『判定不能』を分解する」では、監視の欠測や見積もりの失敗、仮実行の不成立などを分けて評価する必要性について書きました。
その後も監視と検証を進め、ローカルのfork環境でスマートコントラクトを動かし、取引全体の成否や費用を検証する仕組みを整えてきました。
ここでいうforkとは、公開ブロックチェーンの特定時点の状態をローカル環境へ複製し、実際の資産を移動させずに取引を試す方法です。
この方法なら、過去の市場状態を使って取引処理の正しさを調べられます。
ただし、ローカル環境で取引が成立しても、そのまま本番環境で動かせるわけではありません。
実際に取引を行うには、少なくとも次のような準備が必要です。
- 管理用ウォレットとbot用ウォレットの用意
- 各チェーンで必要になるガス代の準備
- 執行用スマートコントラクトの配置
- botに認める操作権限の設定
- 取引に使用する資産と数量上限の管理
- 執行停止や資金回収の手段の確保
これらは価格差の予測や裁定経路の探索とは異なる問題です。
しかも、設定を間違えると、実際の資産やコントラクトの権限に影響します。
例えば、ウォレットを取り違えたり、意図しないチェーンで操作したり、設定したつもりの値が反映されていなかったりする可能性があります。
そこで、執行準備の各作業を人間が確認しながら進められる環境が必要になりました。
2.設定作業からブラウザ管理UIが生まれる
今回、CODEXが構築したのは、ローカルPC上で動作するブラウザベースの管理UIです。
画面には、ウォレットの接続状態、チェーンごとの残高、コントラクトの配置状況、設定項目、操作の進捗などがまとめられています。
管理者はブラウザ上で現在の状態を確認し、必要な設定を選択して操作できます。
特に便利だったのが、各操作の進行状況を確認できることです。
これまでは、コマンドを実行してログを確認したり、別のツールでトランザクションを調べたりする必要がありました。
ところが今回のUIでは、何を設定しようとしているのか、どの段階まで進んだのか、操作後にどのような状態になったのかを一つの画面で追跡できます。
また、単に操作ボタンを配置するだけでなく、必要な準備や確認項目も整理されています。
この点は、実際に触ってみて驚いたところでした。
これまでにもCODEXがUIを作ることはありましたが、今回は見た目が整っているだけではなく、人間が実際に操作することを考えた画面になっていました。
使用したフロントエンド技術
今回の管理画面は、比較的シンプルな構成で作られています。
画面の表示にはHTMLとCSSを使用し、操作や状態更新にはJavaScriptを利用しています。
Reactなどの大規模なフロントエンドフレームワークは採用していません。
また、Node.jsで構築したローカルHTTPサーバーが、画面の配信と設定操作の受付を担当しています。
ブラウザは、このローカルサーバーを通して必要な情報を取得します。
一方、ウォレットの署名にはMetaMaskを使用します。
つまり、ブラウザ画面、ローカルサーバー、ウォレット、ブロックチェーンが、それぞれ役割を分担する構造です。
重要なのは、管理UIそのものに秘密鍵を持たせていないことです。
管理者の秘密鍵はMetaMask側で管理し、ローカルサーバーは取引内容の準備や確認を担当します。
また、管理画面はローカルPCから利用することを前提としており、一般公開するWebサービスとしては構築していません。

3.UIの操作をオンチェーン処理へ接続する
次に、ブラウザから設定を変更するとき、内部で何が起きているのかを整理します。
今回のUIは、ボタンを押すだけで勝手に資金移動を実行するものではありません。
基本的には、操作内容の準備、確認、署名、結果照合という段階を踏みます。
操作内容を準備する
例えば、スマートコントラクトの設定変更を行う場合です。
まずブラウザからローカルサーバーへ、変更したい設定や対象チェーンなどの情報を送ります。
サーバー側では、入力された内容を確認したうえで、RPCを利用して現在のブロックチェーンの状態を取得します。
RPCは、ブロックチェーン上の情報を取得したり、取引を送信したりするための通信窓口です。
ここでは、残高、権限、トランザクションの順序を管理するnonce、必要なガス代などを照合します。
そのうえで、実行するための未署名トランザクションを組み立てます。
この段階では、まだ実際の取引は送信されません。
MetaMaskで本人が承認する
次に、準備した取引内容を画面で確認します。
署名前にも、接続しているチェーンやアカウント、nonce、手数料条件などが再確認されます。
問題がなければ、MetaMaskを通して本人が取引を承認します。
ここで使用するのは、単なるログイン認証ではありません。
MetaMaskのトランザクション送信機能を利用するため、承認後には実際のブロックチェーンへ取引が送信されます。
つまり、管理用の署名権限はブラウザ画面やNode.jsのサーバーではなく、MetaMask側に残されています。
取引結果を照合する
送信後は、返却されたトランザクションハッシュを記録し、ブロックチェーン上の実行結果を確認します。
ここで利用するのが、トランザクションのreceiptです。
receiptには、取引がブロックに取り込まれた後の実行結果やガス使用量などが記録されます。
ただし、receiptの成功だけですべての確認が終わるわけではありません。
例えば、権限を変更した場合には、実際にコントラクトへ新しい権限が反映されているかを読み直す必要があります。
今回の実装では、こうした状態照合も管理処理に組み込まれています。
また、送信直後にRPCから取引が見えない場合でも、直ちに失敗と断定しないようになっています。
未確認の取引を重複送信してしまうことは、資金操作では特に避けたい問題です。
そのため、送信した取引の識別情報を保持し、確認できていない状態と、明確に失敗した状態を区別する設計になっています。

なお、今回のUIでは、操作内容と実際のトランザクションの送信先が直感的には一致しない場面もありました。
例えば、あるDEXを許可先として登録する場合、取引の送信先はDEXそのものではなく、設定を受け付ける管理コントラクトになります。
登録対象のDEXは、コントラクトに渡す引数として指定されます。
そのため、送信先アドレスだけを見ても、何を変更する取引なのかは十分に分かりません。
この問題に対しても、管理画面に操作対象と設定内容を分けて表示する改善が行われています。
こうした細かな部分にも、人間が操作するためのUIとしての設計が反映されていました。
4.管理者とbotの権限を分離する
今回の実装では、管理者が行う操作と、botが自動的に行う売買を分離しています。
ここは、管理UIと並んで重要な技術的変更です。
botによる自動取引では、プログラムが秘密鍵を使ってトランザクションに署名する必要があります。
しかし、資金の回収や権限の変更まで同じ鍵で行えるようにすると、その鍵が扱える範囲が大きくなります。
そこで、管理者とbotを別々の署名主体として扱う構成にしました。
管理者が資金と設定を管理する
管理者側では、MetaMaskを利用してコントラクトの配置や設定変更を行います。
資産ごとの使用上限、取引の実行権限、停止状態、資金回収などを管理します。
一方、bot側には必要な売買実行権限だけを付与します。
botの専用鍵は管理者のMetaMaskとは別に用意し、暗号化してローカル環境で管理しています。
現時点では、この鍵を使った本番の自動送信は開始していません。
スマートコントラクトの役割を分ける
オンチェーン側では、Solidityで作成した管理用コントラクトと、実際の取引処理を担当する執行用コントラクトを組み合わせています。
管理用コントラクトは、管理者やbotの権限、停止状態、資産の使用制限などを扱います。
執行用コントラクトは、許可された取引を実行する役割を持ちます。
複数の交換を一つのトランザクションにまとめ、途中で失敗した場合や必要な条件を満たさなかった場合には、取引全体を取り消す構造です。
これはAtomic Executionと呼ばれる仕組みです。
ただし、取引がrevertした場合でも、ブロックに取り込まれた失敗トランザクションのガス代まで返還されるわけではありません。
また、コントラクト内部で定めた利益条件を満たしていても、それだけでガス代などを差し引いた純利益が保証されるわけではありません。
そのため、執行前の判定側でも費用や実行条件を評価する必要があります。
今回は取引戦略の詳しい説明ではなく、こうした役割分担を中心に整理しておきます。

5.実際の資金を使った執行準備を検証する
今回は管理UIの構築に加えて、実際のブロックチェーン上で執行環境の準備も進めました。
先日の開発記録#602「送っていないETHと、戻ってきたDAI」では、執行準備の途中で行ったウォレット点検について書きました。
その時点では、資産の準備や入出金を主にローカルfork環境で検証していました。
今回はそこから進み、Ethereum上に管理・執行コントラクトを配置しました。
管理用ウォレットから本人署名で操作し、必要な権限設定や資産上限の設定、小額の原資入金まで確認しています。
また、別チェーンで必要になる初期資金の準備も一部進めました。
ただし、現在監視しているすべてのチェーンで執行環境の配置が完了したわけではありません。
実原資を使った送信なしの検証を接続する
今回の実装では、実際に配置されたコントラクトの状態を利用するshadow判定も追加しています。
ここでいうshadow判定とは、実際の市場状態やコントラクトの設定を参照しながら、トランザクションを本番チェーンへ送信せずに実行可能性を評価する方法です。
これまでのローカルforkでは、検証用の資金や権限を用意して、取引が成立するかを試してきました。
一方、今回のshadow判定では、実際に配置されたコントラクトの原資残高や資産上限、許可設定などを参照して評価します。
ただし、現在は本番執行を停止しており、送信なしの検証で必要な一部条件については、シミュレーション内部で補っています。
したがって、shadow判定が通ったとしても、その時点で実際の注文を送信できることまで証明されたわけではありません。
また、実際に取引を送信して、他の市場参加者との競争の中で採用されるかどうかも未検証です。
テストと実行状態を確認する
今回、AIでの監査を通して出力させた技術資料では、Node.js・Solidity側で91件、Python側で139件のテストが合格したことが記録されています。
これらのテストには、権限管理、執行処理、設定操作、保存処理、通信障害時の対応などが含まれています。
実際の資金移動やコントラクト設定についても、トランザクションの実行結果とオンチェーン状態を照合しました。
ただし、テストの合格は、スマートコントラクトに脆弱性がないことや、本番運用で利益を取得できることを保証するものではありません。
また、第三者によるスマートコントラクト監査を受けたわけでもありません。
現時点で、本番の自動裁定は開始していません。その直前で止めています。
今回確認できたのは、管理UIを利用した実際の設定操作と、実原資を参照する送信なしの執行判定までです。

6.操作しやすさと内部構造の理解を両立させる
今回、個人的に印象に残ったのは、CODEXが予想以上に実用的な管理UIを作ってきたことです。
これまでのbot開発では、市場データの取得、価格差の検出、取引条件の判定、API接続、ログの保存などが中心でした。
これらは基本的に、プログラム同士が情報をやり取りするための仕組みです。
しかし、今回作られた管理UIは少し性質が違います。
人間が何を確認し、どの順序で操作し、どこで承認するのかという部分まで設計されています。
これはフロントエンドエンジニアリングやUI/UX設計の領域です。
私はもともとbot開発の過程でフロントエンド開発を主軸としてきたわけではないので、botの執行部を構築する過程で、ここまで実用的な管理画面が出来上がってきたことには新鮮な驚きがありました。
しかも、今回のUIは最初から完成形を目指して設計したものではありません。
実際に設定を進めるうちに、不安や不便を感じた部分を解消していった結果として生まれています。
ただし、便利になったことと、その内部を十分に理解できていることは別です。
ここは少し注意したいところでもあります。
AIによって実装速度が上がると、自分がまだ十分に把握していない仕組みまで、一度に構築できてしまいます。
今回も、管理UIの完成度が想像以上だったからこそ、その裏側でどのような処理が行われているのか気になりました。
そこで、CODEXに実装構成や技術仕様、検証結果を整理させ、実際のソースコードと対応づけながら確認を進めました。
今回把握できたのは、少なくとも次の関係です。
管理UIは人間の操作を受け付け、ローカルサーバーが処理内容を組み立てます。MetaMaskが管理者による承認を担当し、スマートコントラクトが設定された権限に従って処理を行います。
一方、市場監視や裁定候補の評価、将来の自動署名処理は、管理UIとは別のプログラムとして動作します。
ブラウザを閉じたからといって監視プログラムが自動的に停止するわけではありませんし、管理コントラクトの停止を解除しただけで、自動売買が始まるわけでもありません。
こうした違いを理解しておくことは、今後の運用や障害対応でも重要になるはずです。
今後は送信なしの検証から実運用へ進める
今後は、実際の資金と権限を反映したshadow判定を継続し、取引候補の評価や費用計算、処理時間などを確認していきます。
そのうえで、必要なガス代や権限を整え、本番での送信試験へ進めるか判断します。
もちろん、実際にトランザクションを送信する段階では、採用状況、失敗時のガス代、実際の残高変化、資金回収の動作などを改めて確認する必要があります。
また、管理UIについても、今回の実装を完成形とは考えていません。
実際の操作で分かりにくい部分や、状態の確認が不十分な部分が見つかれば、その都度修正することになるでしょう。
今回の開発では、裁定取引の仕組みそのものだけでなく、自分がbotを操作し、管理するための環境も開発対象になりました。
そして、CODEXによって実装できる範囲が広がった一方、構築された仕組みを自分自身が理解する必要性も改めて感じています。
便利な道具を作れることと、その道具を正しく扱えることは別です。
今回は、その両方を進める一日になりました。
それでは、また。