C++、Rust、分散型暗号交換: 適用性と効率性
導入
システム自体が非常に誤解されやすいため、暗号通貨では言語に関する議論が特に誤解を招きやすくなります。人々は、分散型取引所が 1 つのレイテンシ プロファイル、1 つの信頼モデル、および 1 種類の失敗を備えた 1 つの実行可能ファイルであるかのように「DEX を構築する」と言います。実際には、本格的な DEX は層状の有機体です。これには、オンチェーン ロジック、バリデーターまたはノードの相互作用、ブロック構築の認識、メモリプールの監視、市場データの収集、状態シミュレーション、価格設定、ルーティング、リスク チェック、オペレーター ダッシュボード、および場合によっては、ブロックチェーンの語彙を身に着けた従来の取引所インフラストラクチャに似ている疑いのあるオーダーブックまたはマッチングに隣接するサービスが含まれる場合があります。
この重層的な現実を認識すると、C++ と Rust の間の議論はより穏やかになり、より有益になります。正しい問題は、どの言語がアーキテクチャ全体の名誉として値するかということではありません。正しい質問は、どの層がRustの安全性とエコシステムへの適合性から恩恵を受けるのか、どの層が依然としてC++の低レベルのパフォーマンス制御に報酬を与えるのか、そしてどこのハイブリッド設計が妥協をやめて単純な良識を持ち始めるのかということです。
分散型取引システムはさまざまな圧力の下で運用されているため、その枠組みが重要です。一部のレイヤーは、正確性の失敗、監査可能性の問題、安全でない状態の遷移に対して最も厳しく罰せられます。他のレイヤーは、レイテンシー、スループット、および機会を十分に迅速に評価できないため、罰せられます。さらに、実際のコストが長期的なメンテナンスとチームの速度にかかる運用サービスもあります。ある言語は、これらの負担の 1 つに優れている場合もあれば、別の言語には十分である場合もあります。成熟した建築は、それを率直に認めることから始まります。
DEX はスタックであり、アイデンティティ ステートメントではありません
最初の最も重要な修正は概念的なものです。 DEX は 1 つではありません。 EVM 指向の AMM プロトコル、Solana ネイティブ プログラム エコシステム、アプリ チェーンの永久交換、市場状況に反応するサーチャー システムはすべて、さまざまなエンジニアリングの本能に値します。オンチェーン AMM ロジックは、1 セットの制約内に存在します。オフチェーン シミュレーターとルート エバリュエーターは別の内部に存在します。オーダーブックのようなコンポーネントや高頻度の検索インフラストラクチャは、システムの観点から見ると、通常の Web アプリケーション開発よりも従来の取引所ソフトウェアにはるかに近いかもしれません。
言語に関する議論がすぐに迷走してしまうのはこのためです。エンジニアは Solana を指さし、Rust がそこでのプログラム開発の自然な道であることを正しく観察しました。別の研究者は、レイテンシーに敏感なルーティング エンジンまたはシミュレーション エンジンを指摘し、C++ が依然として非常に強力な選択肢であることを正しく観察しています。どちらも文脈上は正しいです。問題は、各観察がスタック全体の全体的な理論に膨らむときに始まります。
精神的なリセットに役立つのは、サブシステムごとに、どのような種類の痛みが罰せられているかを尋ねることです。コンポーネントが間違っている場合、その痛みは主に公的な正当性の欠如でしょうか?民間の運営費なのでしょうか?チャンスが閉まる前に、急速に変化する状態に対応できないのでしょうか?それは監査の負担でしょうか、採用の負担でしょうか、それともインフラストラクチャの負担でしょうか?レイヤーが異なれば、これらの質問に対する答えも異なります。そのため、公開討論で純粋性が求められている場合でも、成熟した DEX システムでは言語が混在してしまうことがよくあります。
Rust が正しく主導権を握る場所
Rust は、状態遷移、安全規律、およびエコシステムの適合がアーキテクチャを支配する場所で最も自然にその地位を獲得します。 Solana のような Rust ファーストのブロックチェーン環境では、これはわずかな利点ではありません。それは重心です。言語は単にそこで利用できるだけではありません。それは、プロトコル チームがエコシステムに逆らうのではなく、エコシステムの粒度の中で動くのを助けるフレームワーク、サンプル、セキュリティ習慣、ツールに囲まれています。オンチェーン プログラムの場合、抽象的な言語の比較よりも適合性が重要です。紙の上で最良の言語であっても、その周囲のすべての重大な運用パスが別のことを期待している場合、多くの場合、より悪い言語になります。
Rust は、主な敵が超低遅延ではなく長期的な正確性と保守性である場合、DEX を取り巻くグリーンフィールド サービスでも魅力的です。コントロールプレーンサービス、調整層、および特定のプロトコル対応ツールは、Rust が奨励する規律から真の恩恵を受ける可能性があります。コンパイラは、C++ で制御するプロセス、警戒心、およびレビュー文化を必要とする間違いのカテゴリを検出します。それはロマンチックな主張ではありません。実用的なものです。 Rust の優れた人材を擁するチームは、早期にいくつかのクラスのリスクを軽減し、時間の経過とともにサービス境界をより穏やかに保つことができます。
有用な反例は、これを根拠にしています。チームは、チェーンネイティブな作業における Rust の強みから、周囲のすべてのオフチェーン サブシステムもデフォルトで Rust であるべきだと推論することがあります。しかし、それは周囲のシステムが同じ支配的な痛みを持っている場合にのみ続きます。厳しいタイミングのプレッシャーの下で市場の状態を繰り返し評価するホットパス シミュレーターや検索エンジンは、暗号商品を提供するという理由だけで、パフォーマンスに敏感なネイティブ システムであることに変わりはありません。チェーンは Rust 型になる可能性がありますが、周囲の実行パスはほぼ C++ 型のままです。
C++ が依然としてその地位を確立している場所
DEX がアプリケーション プラットフォームではなく、交換インフラストラクチャのように動作し始めると、C++ を置き換えるのは困難になります。市場データの取り込み、メモリプールのリスニング、正規化パイプライン、ルート評価、状態シミュレーション、アービトラージ検索、清算エンジン、およびオーダーブック隣接サービスはすべて、共通の特性を共有しています。つまり、これらのサービスはプレッシャーの下で低レベルの作業を繰り返し実行し、その作業は多くの場合、メモリ レイアウト、割り当て戦略、パーサーの効率、キューの動作、または CPU の予測可能性と密接に関係しています。
これは、システムと取引における C++ の長い歴史が引き続き重要な点です。この言語を使用すると、エンジニアは、データ構造、スレッド モデル、オブジェクトの有効期間、カスタム アロケータ、ベクトルに適したレイアウト、およびまさにこの種の環境で実戦テストされたパフォーマンス ツールを直接制御できます。また、高性能ネットワーク システム、シミュレータ、パーサー、ネイティブ ゲートウェイ、およびハードウェアを意識したコードのサンプルの古くて密度の高いエコシステムの恩恵も受けています。 AI アシスタントがこれらの問題にも対処するよう求められている時代においては、その密度が利点をさらに高めます。
市場のシグナルを聞き、経路をシミュレートし、機会を追う価値があるかどうかを判断する検索者を考えてみましょう。興味深いコストが、単独の 1 つの式であることはほとんどありません。興味深いコストは、取り込み、デコード、ルーティング、意思決定ロジックに囲まれた多くの式をステートフルに繰り返し使用することです。いくつかの回避可能なコピー、不適切に配置された 1 つのロック、または規律のないキューによって、パス全体の経済性が変化する可能性があります。ここで C++ は魔法ではありませんが、エンジニアがマシンに正確な質問をするための非常に使い慣れた言語を提供します。時間的プレッシャーの下で繰り返し生きては死ぬシステムでは、それは依然として重要です。
経済学が言語の答えを変える
こうした議論が過熱する理由の 1 つは、エンジニアが勝利の条件がエレガントであるかのように話すことです。 DEX システムでは、通常、勝利条件は経済的です。チャンスを逃すとコストが発生するため、レイテンシが重要になります。大規模なシミュレーションの繰り返しにはコストがかかるため、効率が重要です。不適切な状態遷移にはコストがかかるため、安全性が重要です。オペレーターを常に怖がらせるシステムにはコストがかかるため、運用のシンプルさが重要です。いったん議論がそのような言葉で述べられると、言語の選択は象徴的なものではなくなり、経済的なものになります。
Rust は多くの場合、将来の最大のコストがハード ステートフル ロジックの正当性の失敗、または十分な構造的規律のない複雑なサービスの維持によって発生する場合に、それ自体で元をとります。 C++ は、ホット パスの非効率性、反復計算における過度の抽象化、または高パフォーマンスのネイティブ インフラストラクチャとの統合の難しさによって将来最大のコストが発生する場合に、多くの場合、それ自体で元をとります。賢明なチームは、サブシステムの寿命全体にわたってどのコストが支配的になるかを検討し、それに応じて選択します。
この視点は、よくある混乱の 1 つ、つまり決済速度と実行パス速度は同じものではないという問題にも役立ちます。ブロックチェーンはプロトコル レベルで 1 つのタイミング特性を備えている可能性がありますが、ブロックチェーンを囲むオフチェーン システムはまったく異なるレイテンシーの世界に存在します。オンチェーン決済が遅いからといって、迅速なオフチェーン評価が無関係になるわけではありません。実際、機会が争われている場合、誰が反応するか、誰が正確に価格を設定するか、誰が最初に有益なアクションを提出するかが決まるため、オフチェーンのスピードの価値はさらに高まる可能性があります。これら 2 つのタイミング領域を速度と呼ばれる 1 つの概念に平坦化するエンジニアは、通常、労力の置き場所を間違えることになります。
ハイブリッド アーキテクチャが大人の答えになることが多い
ハイブリッド設計が尊重されるようになると、最も本格的な DEX アーキテクチャの多くは、容易に理解できるようになります。オンチェーン ロジックは、チェーンが期待する言語およびフレームワーク環境内で動作できます。コントロール プレーンと製品サービスは、メンテナンスを健全に保つ言語を選択できます。ホットパス シミュレーション、ルーティング、市場データ処理、または隣接コンポーネントのマッチングは、従来のパフォーマンスに近い状態を保つことができるため、調整や検証が容易になります。その結果はイデオロギー上の妥協ではありません。各部分が実際の負担に合わせて最適化できるシステムです。
これには成熟度が必要です。ハイブリッド システムは、境界が明確な場合にのみ健全です。チームには、明確なインターフェース、狭い責任分担、複雑さがどこに属するのかについての誠実さが必要です。しかし、それは言語に関係なく当てはまります。境界が混乱している 1 言語のアーキテクチャは、境界が明確な 2 言語のアーキテクチャよりも単純ではありません。場合によっては、同じ混乱を単一言語で表現しただけの場合もあります。
ここには人員配置の側面もあります。チームは、複数のネイティブ ドメインにわたって採用するのは難しいと感じるため、1 つの言語を選択しなければならないと想像することがよくあります。その懸念は理解できますが、それはアーキテクチャ上の怠惰の言い訳になる可能性があります。もっと良い質問は、最もパフォーマンスに敏感な層が本当に独自の言語を必要としているのか、それともプロファイラーがそのコストをまだ正当化していないのかということです。一部のチームは絶対に主に Rust に留まり、ホット パスが得られた場合にのみ C++ を導入する必要があります。すでに C++ の深い専門知識を持っている人もいますが、自分たちの最も強力なシステム本能と一致しない Rust 型のワークフローにすべてを強制することで、自分自身に害を及ぼす可能性があります。ここでもまた、名声よりもコンテキストが重要です。
AI支援エンジニアリングによる変化
AI コーディング システムの登場は、文脈に応じた言語選択の根拠を弱めるのではなく、むしろ強化しています。 Rust ファーストのブロックチェーン エコシステムでは、エージェントはフレームワークを意識したスキャフォールディング、日常的なサービス コード、および一部のカテゴリのリファクタリングを以前よりも快適に支援できます。しかし、低レベルでパフォーマンス重視のネイティブ サブシステムでは、単純な理由からバランスが依然として C++ に傾いています。パブリック コード、パブリック ツール、およびパブリック統合サンプルがはるかに密集しているからです。現在、エージェントには、DEX システムが頻繁に必要とする種類のホットパス インフラストラクチャに役立つドラフトを作成するためのより多くの履歴資料があります。
これは、AI が C++ を普遍的に優れたものにするという意味ではありません。これは、古いエコシステムの重力が新しいツールによって増幅されることを意味します。アシスタントが CMake 統合のデバッグ、キューの再設計の提案、パーサーの改善、シミュレーション ループのベンチマークのドラフトを支援する場合、パブリック C++ の世界のディープ ネイティブ メモリの恩恵を受けることができます。アシスタントが Rust-first オンチェーン環境内で作業する場合、その逆が当てはまる可能性があります。言語の決定は依然としてワークロードに属しますが、AI 時代により、環境密度が以前よりもさらに重要になります。
私の実践的な推奨事項
Rust ファーストのエコシステムでチェーンネイティブ プログラムを構築している場合は、言語レトリックのために領域と戦わないでください。 Rust がすでに正確さ、ツール、コミュニティの実践の自然な本拠地となっている場所を Rust にリードしてもらいましょう。パフォーマンス重視の交換エンジニアリングのように動作するオフチェーン インフラストラクチャを構築している場合は、製品ドメインが暗号であるという理由だけで C++ を放棄しないでください。高速な取り込み、反復的なシミュレーション、厳密なルーティング ロジック、および低レベルのシステム制御など、C++ が今でも非常にうまく機能している作業を C++ に実行させます。
そして、あなたのアーキテクチャが本当に両方の世界にまたがるのであれば、恥ずかしがらずにその事実を受け入れてください。すべてのコンポーネントが同じ種類の障害に苦しんでいるふりをしても、優れたエンジニアリングがより純粋になるわけではありません。これは、各コンポーネントに実際のジョブの物理学を尊重する言語を割り当てることによって強化されます。
このように問題に取り組むと、静かな楽観主義が生まれます。これはエンジニアに、建築は公共の場での議論よりも穏やかなものになり得ることを思い出させます。議論に永遠に勝つために、1 つの言語を選択する必要はありません。システムの次の正直な層に適したツールを選択するだけで済みます。それははるかに有益な種類のインテリジェンスです。
ハンズオン ラボ: 小さな AMM ルート エバリュエーターを構築する
理解できるほど小さく、触れられるほど本物のものを構築しましょう。
目標は Uniswap を再作成することではありません。目的は、シミュレーションと比較を繰り返すことで、DEX の作業がいかに迅速に行われるかを感じることです。
__コード_0__
#include <cmath>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
struct Pool {
std::string name;
double reserve_in;
double reserve_out;
double fee; // 0.003 for 0.3%
};
double swap_out(const Pool& p, double amount_in) {
const double effective_in = amount_in * (1.0 - p.fee);
return (effective_in * p.reserve_out) / (p.reserve_in + effective_in);
}
double two_hop(const Pool& a, const Pool& b, double amount_in) {
const double mid = swap_out(a, amount_in);
return swap_out(b, mid);
}
int main() {
Pool eth_usdc_a{"ETH/USDC pool A", 500.0, 1750000.0, 0.003};
Pool eth_usdc_b{"ETH/USDC pool B", 650.0, 2262000.0, 0.0005};
Pool usdc_dai{"USDC/DAI stable pool", 900000.0, 901200.0, 0.0001};
const double trade_eth = 4.0;
const double direct_a = swap_out(eth_usdc_a, trade_eth);
const double direct_b = swap_out(eth_usdc_b, trade_eth);
const double routed = two_hop(eth_usdc_b, usdc_dai, trade_eth);
std::cout << std::fixed << std::setprecision(4);
std::cout << "Input: " << trade_eth << " ETH\n";
std::cout << "Direct via " << eth_usdc_a.name << ": " << direct_a << " USDC\n";
std::cout << "Direct via " << eth_usdc_b.name << ": " << direct_b << " USDC\n";
std::cout << "Two-hop via " << eth_usdc_b.name << " -> " << usdc_dai.name
<< ": " << routed << " DAI\n";
if (direct_b > direct_a) {
std::cout << "Best direct route: " << eth_usdc_b.name << "\n";
} else {
std::cout << "Best direct route: " << eth_usdc_a.name << "\n";
}
}
建てる
Linux または macOS の場合:
g++ -O2 -std=c++20 -o amm_router main.cpp
./amm_router
Windows の場合:
cl /O2 /std:c++20 main.cpp
.\main.exe
なぜこれが重要なのか
この小さなプログラムでも、オフチェーン DEX 作業の実際の形をすでに示唆しています。
- 反復パス評価
- 手数料を意識した比較
- 状態依存の出力
- 正確さとスピードの間の一定の緊張感
これを数百のプール、頻繁な状態更新、敵対的なタイミングプレッシャーまで拡張すると、言語の選択がすぐに抽象的でなくなる理由がわかり始めます。
愛好家向けのテストタスク
- スリッページ許容値を追加し、有効出力が設定されたしきい値を下回るルートを拒否します。
- プログラムを拡張して、2 つではなく 5 つまたは 10 つのプールを比較し、時間の経過をプロファイリングします。
- リザーブをわずかに変更してルートを 100 万回再評価するループを追加し、「おもちゃの」ルーターが実際のホット パスにどのように似てくるかを測定します。
- 浮動小数点の出力フォーマットを構造化された数値ログに置き換えて、実際のルート ロジックの周囲にどの程度の「非数学的」作業が発生するかを観察します。
- Rust または別の言語で 2 番目のバージョンを追加し、生のランタイムだけでなく、シミュレーション ループが作業の中心になったときに言語がどの程度快適に感じられるかを比較します。
これは、微妙な点を明らかにするため、良い練習になります。Exchange ソフトウェアでは、多くの場合、興味深い問題は 1 つの式にあるのではなく、多くの通常の式を一度に繰り返し、ステートフルで、待ち時間に敏感に使用することにあります。
まとめ
C++ と Rust は両方とも分散型交換エンジニアリングに属しますが、異なる理由で分散型交換エンジニアリングに属します。 Rust は、状態の安全性、監査可能性、チェーンネイティブのワークフローが中心となるエコシステムとレイヤーで信頼を獲得します。 C++ は、繰り返しのシミュレーション、市場データ処理、ルーティング、検索、およびメモリ、スケジューリング、パフォーマンス検証の厳密な制御に報いるその他のホット パス システムなど、作業が再び取引所インフラストラクチャのように見え始めるレイヤーで信頼を獲得します。
したがって、最も有益な質問は、どの言語がスタック全体を獲得するかということではありません。それは、実際にどの層を設計しているのか、そしてその層がどのような種類の障害を最小限に抑えられるのかということです。この質問を正直に尋ねると、通常、アーキテクチャはより明確になり、議論はイデオロギー的ではなくなります。適切に設計された DEX が言語の純粋性の記念碑となることはほとんどありません。これはコンポーネントの実用的な配置であり、それぞれのコンポーネントが担う負荷を最大限に考慮した言語で書かれています。
参考文献
- Uniswap v3 ホワイトペーパー: https://uniswap.org/whitepaper-v3.pdf
- Uniswap v3 コア リポジトリ: https://github.com/Uniswap/v3-core
- Ethereum.org MEV ドキュメント: https://ethereum.org/developers/docs/mev/
- Solana プログラムの概要: https://solana.com/docs/core/programs
- Solana Rust プログラム開発: https://solana.com/docs/programs/rust
- アンカードキュメント: https://www.anchor-lang.com/docs
- dYdX チェーンのドキュメント: https://docs.dydx.exchange/
- dYdX 統合ドキュメント: https://docs.dydx.xyz/
- オンチェーン決済を使用したオフチェーン注文帳の dYdX: https://integral.dydx.exchange/dydx-closes-10m-series-b-investment/
- Cosmos SDK ドキュメント: https://docs.cosmos.network/