功能说明
已知有些验证者会对收到的交易进行三明治攻击或以其他方式加以利用。开启 MEV 保护后,Apex 在转发您的交易时会跳过 Shield 黑名单上的领导者。交易会等待一个不在名单上的领导者,而不是被交给名单上的领导者。 该黑名单是一项链上的 Yellowstone Shield 策略,因此是公开且可审计的。权衡
mevProtect: false(默认) | mevProtect: true | |
|---|---|---|
| 使用的领导者 | 所有领导者 | 除 Shield 黑名单上的领导者之外的所有领导者 |
| 上链速度 | 最快 | 可能因黑名单领导者的 slot 而变慢 |
| 最适合 | 转账、铸造、清算,以及任何不会被三明治攻击的交易 | 兑换和其他对价格敏感的交易 |
如何启用
通过 HTTP 时,MEV 保护按交易设置;通过 QUIC 时,按连接设置。| 传输方式 | 设置 |
|---|---|
JSON-RPC sendTransaction | 第三个参数为 true |
POST /send | JSON 请求体中的 "mevProtect": true |
POST /send-bin, /send-batch | 查询标志 ?mev_protect=1 |
| QUIC,Rust 客户端 | ClientOptions::mev_protect = true |
| QUIC,其他语言 | 在交易数据包中将 mev_protect 字节设为 1 |
TX_BASE64 和 apex-tx 辅助模块来自发送交易。
TX_BASE64=$(node apex-tx.mjs)
# JSON-RPC: the third param is mevProtect.
curl -s "$APEX_RPC" \
-H "Content-Type: application/json" \
-H "x-api-key: $APEX_API_KEY" \
-d "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"sendTransaction\",\"params\":[\"$TX_BASE64\",{\"encoding\":\"base64\"},true]}"
# Binary route: the mev_protect query flag.
TX_BASE64=$(node apex-tx.mjs)
echo "$TX_BASE64" | base64 --decode | curl -s "$APEX_RPC/send-bin?mev_protect=1" \
-H "Content-Type: application/octet-stream" \
-H "x-api-key: $APEX_API_KEY" \
--data-binary @-
import { apexRpc, buildTx, confirm } from "./apex-tx.mjs";
const tx = await buildTx({ label: "apex mev protect" });
const signature = await apexRpc("sendTransaction", [
Buffer.from(tx.serialize()).toString("base64"),
{ encoding: "base64" },
true, // mevProtect
]);
console.log("accepted:", signature);
console.log("landed in slot", await confirm(signature));
import base64
from apex_tx import apex_rpc, build_tx, confirm
tx = build_tx(label="apex mev protect")
signature = apex_rpc("sendTransaction", [
base64.b64encode(bytes(tx)).decode(),
{"encoding": "base64"},
True, # mevProtect
])
print("accepted:", signature)
print("landed in slot", confirm(signature))
// QUIC: protection is a connection option. Every send on this client is protected.
use apex_sender_client::{ApexSenderClient, ClientOptions, Region};
let client = ApexSenderClient::connect_with_options(
ClientOptions {
endpoint: Some(Region::Frankfurt.quic_endpoint()),
mev_protect: true,
..Default::default()
},
&api_key,
)
.await?;
let signature = client.send_transaction(&tx).await?;
在 Rust 中,如果您既需要受保护的发送,也需要不受保护的发送,请持有两个客户端:一个设置
mev_protect: true,另一个不设置。每个客户端各自保持自己的连接,并且两者都保持预热。