使用 Jito DontFront 实现 MEV 防护

使用 Jito DontFront 实现 MEV 防护

最大可提取价值(MEV)是指通过对区块内交易进行重新排序、纳入或排除所能获取的价值。MEV 并非某条链独有的问题,而是任何由区块生产者控制交易排序的区块链的基本属性。某些形式的 MEV(如套利)通过纠正 DEX 之间的价格差异来维持市场效率,而另一些形式(如三明治攻击)则直接从用户处提取价值。对于构建 DeFi 应用的开发者而言,这可能意味着更差的交易执行结果和利润损失。

本指南重点介绍三明治攻击——一种常见的有害 MEV 形式,以及如何利用 Jito 的 dontfront 功能来应对它。

建议预先阅读: Jito Bundles

Solana 上的 MEV

与拥有公共内存池的链相比,Solana 的架构已经缩小了 MEV 的攻击面。交易会直接转发给即将出块的区块领导者,而不是在共享内存池中等待,未处理的交易在约 150 个区块(约 1 分钟)后过期。这大幅压缩了搜索者观察和利用待处理交易的时间窗口。

尽管如此,MEV 提取依然存在。拥有优化基础设施和直接 validator 连接的搜索者可以观察交易流并作出响应。Solana 上大部分 MEV 活动属于原子套利:机器人在单笔交易中纠正 DEX 之间的价格差异。这类 MEV 通常是有益的,因为它有助于提升市场间的价格一致性。

有害的 MEV 形式——三明治攻击,才是开发者应当积极防范的对象。

什么是三明治攻击?

三明治攻击发生在搜索者检测到你的待处理交换并利用交易排序时:

  1. 抢先交易:搜索者在你的交易之前买入代币,推高价格
  2. 你的交易以比预期更差的价格执行
  3. 跟后交易:搜索者在你的交易之后卖出代币,赚取差价

在 Solana 上,这可以通过 Jito bundles 实现。 搜索者提交一个交易包,例如: [frontrun_tx, your_tx, backrun_tx],区块引擎按顺序原子化执行它们。受害者以更差的执行价格成交,而搜索者从价差中获利。

DontFront 的工作原理

DontFront 是 Jito 区块引擎的一项功能,可防止搜索者在交易包中将其交易排在你的交易之前。

其机制为:将任意以 jitodontfront 开头的有效 Solana 公钥添加到你交易中的任意指令中。区块引擎识别该前缀并强制执行规则:任何包含你交易的交易包必须将其置于索引 0 的位置

Without dontfront: [frontrun_tx, your_tx, backrun_tx] ← sandwich possible
With dontfront: [your_tx, ...] ← your tx must be first

分步说明

  1. 选择一个有效地址,该地址以 jitodontfront 开头(例如: jitodontfront111111111111111111111111111111)。该账户无需在链上存在,它不会被读取或写入。你可以使用 @solana/kit 中的 assertIsAddress 函数验证某字符串是否为有效地址,也可以在 Solana Explorer 中输入该地址查看是否能解析。这里是一个 无效地址的示例。

  2. 将其作为只读非签名账户添加到你交易中的任意指令中。标记为只读可获得最佳上链速度。大多数程序(包括 System Program)会忽略超出预期的额外账户。

  3. 通过 Jito 区块引擎提交

    • sendTransactionhttps://mainnet.block-engine.jito.wtf/api/v1/transactions
    • sendBundlehttps://mainnet.block-engine.jito.wtf/api/v1/bundles

    文档: sendTransactionsendBundle

  4. 区块引擎检测到 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]

单个交易包中包含多个 DontFront 交易

同时满足以下两个条件时,单个交易包中允许包含多个 dontfront 交易:

  1. 所有 dontfront 交易连续排列在交易包的最前面
  2. 每个 dontfront 交易与第一个 dontfront 交易至少共享一个签名者
✅ [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 防护 cookbook 条目

TypeScript(@solana/kit)

核心思路是编写一个辅助函数,将 dontfront 账户追加到任意指令中:

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 }
]
};
}

然后将已签名的交易提交到 Jito 区块引擎,而不是标准 RPC 节点。请始终使用 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 是防护的一层保障。一套完善的 MEV 缓解策略需要结合多种方法:

交易级防护

  • 设置严格的滑点容差。 防范三明治攻击最有效的单一手段是限制交换的可接受滑点。更小的滑点窗口压缩了攻击者可获取的利润空间,使你的交易对三明治攻击者吸引力降低。

  • 设置合理的小费和优先费用。 在网络拥堵时,较高的小费和优先费用能提高你的交易/交易包快速上链的概率,从而缩短搜索者的可操作窗口。有关如何设置合理小费的更多详情,请参阅 Jito 文档中的 小费金额部分。

  • 优化计算单元使用量。 每个区块的可用计算单元数量有限(账户在每个区块内的可用计算单元也有限制)。为最大化你的交易/交易包被纳入区块的概率,应优化计算单元使用量。详情请参阅 如何优化 Solana 上的计算使用 指南。

DontFront 专项建议

  1. 将 dontfront 账户标记为只读。 标记为可写也能正常工作,但只读标记 可优化上链速度

  2. 为每个应用使用唯一的 dontfront pubkey。 任何以 jitodontfront 开头的 pubkey 均可使用。采用唯一变体(例如 jitodontfront111111111111111111111111111123)便于在检查链上数据时区分各应用的使用情况。

  3. DontFront 支持地址查找表(ALT)。 dontfront 账户可通过 ALT 添加。但请勿将 ALT 用于小费账户。

局限性

  • 仅限区块引擎。 DontFront 由 Jito 区块引擎强制执行。直接提交给 validator(绕过 Jito)的交易不受保护。

  • 不提供保证。 来自 Jito 文档:"此功能可能有助于减少三明治攻击,但不保证能做到这一点,也不能解决所有交易排序方面的变化,包括第三方实施的任何排序。"

  • 仅限主网/测试网。 这是 Jito 区块引擎的功能,在开发网或本地环境中不可用。

参考资料

Is this page helpful?

©️ 2026 Solana 基金会版权所有