Jito DontFrontによるMEV対策
Maximal Extractable Value(MEV)とは、ブロック内のトランザクションを並べ替え、含める、または除外することで得られる価値のことです。MEVは特定のチェーンに固有のものではなく、ブロック生成者がトランザクションの順序を制御するあらゆるブロックチェーンの基本的な特性です。裁定取引のように、DEX間の価格差を修正することで市場効率を高めるMEVの形態もあります。一方、サンドイッチ攻撃のように、ユーザーから直接価値を搾取するものもあります。DeFiアプリケーションを構築する開発者にとって、これはトレード実行の悪化や利益損失を意味する可能性があります。
このガイドでは、有害なMEVの一般的な形態であるサンドイッチ攻撃と、Jitoのdontfront機能を使ってそれを軽減する方法に焦点を当てます。
事前に読むことを推奨します: Jito Bundles
SolanaにおけるMEV
Solanaのアーキテクチャは、パブリックメンプールを持つチェーンと比較して、すでにMEVの攻撃対象領域を縮小しています。トランザクションは共有メンプールに置かれるのではなく、次のブロックリーダーに直接転送され、未処理のトランザクションはおよそ150ブロック(約1分)後に期限切れになります。これにより、サーチャーが保留中のトランザクションを観察して対応できる時間帯が大幅に狭まります。
それでも、MEVの搾取は発生します。最適化されたインフラと直接的なvalidator接続を持つサーチャーは、トランザクションフローを観察してそれに対応できます。Solana上のMEV活動の多くはアトミック裁定取引です。つまり、単一のトランザクションでDEX間の価格差を修正するボットです。このタイプのMEVは市場全体の価格一貫性を向上させるため、一般的に有益とみなされています。
開発者が積極的に対策すべき有害な種類は、サンドイッチ攻撃です。
サンドイッチ攻撃とは?
サンドイッチ攻撃は、サーチャーが保留中のスワップを検知し、トランザクションの順序を悪用することで発生します:
- フロントラン:サーチャーがあなたのトレードより先にトークンを購入し、価格を 引き上げる
- あなたのトレードが実行され、予想より悪い価格になる
- バックラン:サーチャーがあなたのトレードの後にトークンを売却し、 差額を手に入れる
Solanaでは、これは
Jitoバンドルを通じて発生する可能性があります。
サーチャーは[frontrun_tx, your_tx, backrun_tx]のようなトランザクションのバンドルを送信し、ブロックエンジンがそれらをアトミックに順番に実行します。被害者は実行価格が悪化し、サーチャーはスプレッドから利益を得ます。
DontFrontの仕組み
DontFrontは、 Jitoブロックエンジンの機能であり、サーチャーがバンドル内であなたのトランザクションより前にトランザクションを配置することを防ぎます。
仕組み:jitodontfrontで始まる有効なSolanaの公開鍵をトランザクションの任意のinstructionsに追加します。ブロックエンジンはこのプレフィックスを認識し、あなたのトランザクションを含むバンドルはそれをインデックス0に配置しなければならないというルールを適用します。
Without dontfront: [frontrun_tx, your_tx, backrun_tx] ← sandwich possibleWith dontfront: [your_tx, ...] ← your tx must be first
ステップバイステップ
-
有効なアドレスを選択する(例:
jitodontfront111111111111111111111111111111のようにjitodontfrontで始まるもの)。アカウントはオンチェーンに存在する必要はなく、読み取りも書き込みもされません。文字列が有効なアドレスであるかどうかは、@solana/kitのassertIsAddress関数を使用して確認するか、Solana Explorerにアドレスを入力して解決するかどうかを確認できます。こちらは 無効なアドレスの例です。 -
読み取り専用の非署名者アカウントとしてトランザクションの任意のinstructionsに追加します。最適なランディング速度のために読み取り専用としてマークしてください。ほとんどのプログラム(System Programを含む)は、想定外の追加アカウントを無視します。
-
Jitoブロックエンジン経由で送信する:
sendTransaction:https://mainnet.block-engine.jito.wtf/api/v1/transactionssendBundle:https://mainnet.block-engine.jito.wtf/api/v1/bundles
ドキュメント: sendTransaction および sendBundle
-
ブロックエンジンが
jitodontfrontプレフィックスを検出し、順序ルールを適用します。
ブロックエンジンでの処理
ブロックエンジンがjitodontfrontアカウントを含むトランザクションを検出した場合:
sendTransaction経由:トランザクションは保護されます。どのバンドルも その前に別のトランザクションを配置できませんsendBundle経由:トランザクションはインデックス0に配置されなければならず、そうでない場合はバンドル全体が拒否されます
jitodontfrontアカウントを含まないトランザクションおよびバンドルには影響しません。
バンドルの順序ルール
これらのルールは、バンドル内にjitodontfrontトランザクションが存在する場合に適用されます。
許可されるパターン
[tx_with_dontfront, tip][tx_with_dontfront, arbitrage, tip][tx_with_dontfront_signer1, tx_with_dontfront_signer1_and_signer2, tip]
1つのバンドル内の複数のDontFrontトランザクション
1つのバンドル内に複数のdontfrontトランザクションを含めることは、両方の条件が満たされる場合に許可されます:
- すべてのdontfrontトランザクションがバンドルの先頭に連続して配置されている
- 各dontfrontトランザクションが最初のdontfrontトランザクションと少なくとも1つの署名者を共有している
✅ [txA_df, txB_df, txC_df, arbitrage, tip](contiguous at front, overlapping signers)✅ [txA_df_signer1_signer2, txB_df_signer1_signer3, txC_df_signer2_signer4](each shares a signer with txA)
拒否されるパターン
❌ [tip, tx_with_dontfront]→ dontfront tx is not at index 0❌ [txA_df_signer1, txB_df_signer2]→ no overlapping signer between txA and txB❌ [trade, tx_with_dontfront, arbitrage, tip]→ dontfront tx is not at the front
統合例
クイックコードレシピについては、 MEV保護クックブックエントリを参照してください。
TypeScript(@solana/kit)
核となるアイデアは、dontfrontアカウントを任意のinstructionsに追加するヘルパーです:
import {address,AccountRole,type Instruction,type Address} from "@solana/kit";const DONT_FRONT: Address = address("jitodontfront111111111111111111111111111111");function withDontFront(ix: Instruction): Instruction {return {...ix,accounts: [...(ix.accounts ?? []),{ address: DONT_FRONT, role: AccountRole.READONLY }]};}
次に、署名済みトランザクションを標準のRPCノードではなくJitoブロックエンジンに送信します。常にbase64エンコーディングを使用してください。Base58はJitoのAPIでは非推奨です。
const response = await fetch("https://mainnet.block-engine.jito.wtf/api/v1/transactions",{method: "POST",headers: { "Content-Type": "application/json" },body: JSON.stringify({jsonrpc: "2.0",id: 1,method: "sendTransaction",params: [base64Tx, { encoding: "base64" }]})});
ベストプラクティス
DontFrontは保護の1つのレイヤーです。堅牢なMEV軽減戦略は複数のアプローチを組み合わせます:
トランザクションレベルの保護
-
スリッページ許容値を厳しく設定する。 サンドイッチ攻撃に対して最も効果的な防御策は、スワップの許容スリッページを制限することです。スリッページ幅が小さいほど、攻撃者が得られる利益マージンが減少し、サンドイッチの標的として魅力が薄れます。
-
適切なチップと優先手数料を設定する。 混雑時には、チップと優先手数料を高くすることでトランザクション/バンドルが迅速にランディングする可能性が高まり、サーチャーが対応できる時間帯を縮小します。適切なチップの設定方法については、Jitoのドキュメント Tip Amountsを参照してください。
-
コンピュートユニットの使用量を最適化する。 各ブロックには利用可能なコンピュートユニット数に上限があります(アカウントごとにもブロック単位での上限があります)。トランザクション/バンドルがブロックに含まれる可能性を最大化するために、コンピュートユニットの使用量を最適化する必要があります。詳細については、 SolanaでのコンピュートUsageの最適化方法 ガイドを参照してください。
DontFront固有の設定
-
dontfrontアカウントを読み取り専用としてマークする。 書き込み可能としてマークしても機能しますが、読み取り専用の方が ランディング速度を最適化できます。
-
アプリケーションごとに固有のdontfront pubkeyを使用する。
jitodontfrontで始まるどのpubkeyでも機能します。固有のバリアント(例:jitodontfront111111111111111111111111111123)を使用すると、オンチェーンデータを検査する際にアプリごとの使用状況を区別できます。 -
DontFrontはAddress Lookup Tablesをサポートしています。 dontfrontアカウントはALT経由で含めることができます。ただし、チップアカウントにはALTを使用しないでください。
制限事項
-
ブロックエンジンのみ。 DontFrontはJitoブロックエンジンによって強制されます。 validatorに直接送信されたトランザクション(Jitoをバイパスするもの)は保護されません。
-
保証ではありません。 Jitoのドキュメントより:「この機能はサンドイッチ攻撃の軽減に役立つ可能性がありますが、保証されるものではなく、第三者が実施する順序付けを含む、トランザクション順序のすべてのバリエーションに対する解決策でもありません。」
-
メインネット/テストネットのみ。 これはJitoブロックエンジンの機能です。devnetやlocalhostでは動作しません。
参考資料
Is this page helpful?