第四层第一篇——MEV 开篇。01–13 解释了"链上现在有什么",14 解释**"接下来 12 秒会发生什么"**: 一笔 tx 从你按下 send 到落账之间经历了什么、谁能在这中间看到它、谁来决定它进哪一块、 顺序怎么决定。这是 MEV 全部技艺的物理基础——也是我们 mempool.ts / flashbots.ts / demo-backrun.ts / demo-flashbots.ts 这些 watcher 模块直接操作的层面。 沿用 01–13 的村庄画面。结构见 README.md §1。


0. 一句话本质

Mempool = 每个节点本地的"待打包 tx 临时桶",不是全网共享的单一队列; 一笔 tx 通过 P2P gossip 在节点间扩散,最终被某个 builder 选中、组进候选区块、 通过 relay 拍卖给当 slot 的 proposer。 PBS(Proposer-Builder Separation)= 把"决定块内容"和"提议块"两件事分给不同角色, proposer 不知道块里装了什么、只看价高签名——MEV 经济学全部建立在这条结构上。


1. 怎么产生的:它解决什么问题

01–13 留下的最后一类硬问题:

  1. 我钱包按 send 之后,tx 在变成"块里某行"之前的 12 秒到底在哪? ⇒ 在很多个节点的本地"mempool"里。没有全网统一队列——每个节点各自维护,gossip 协议互相同步。
  2. 谁能看到我那笔 pending tx?只有我的 RPC 节点吗? ⇒ 任何接入 P2P 网络的节点都能看到——这意味着搜寻 MEV 的人 24/7 监听所有 pending。 你的 swap 一进 mempool,可能 0.1 秒内被几百个 searcher 见过。
  3. 既然 12 秒后才打包,那"谁先按 send 谁先成交"成立吗? ⇒ 不成立。出块者按 priority fee(小费)排序而非时间排序(07 §4.3)。 给小费高的 tx 先打包;MEV 搜寻者还会专门搭乘你的"未来打包"赚价差。
  4. 04 §5 说 PBS 让 proposer 不看块内容,具体是怎么做到的?谁负责构造块? ⇒ Proposer(PoS 验证者)被随机选中后不亲自构造块。Builder 们各自从 mempool + 私有订单流 + searcher bundle 拼出候选块 → 通过 relay 出价("我出 0.05 ETH 给你 sign 我这块") → proposer 看到的只是"哪个 builder 出价最高 + 一个 header hash" → sign → relay 揭开块体 → 上链。
  5. Flashbots / BloXroute / Eden 这些 relay 是什么?怎么排队的? ⇒ Relay 是 builder 和 proposer 之间的可信中介。每个 relay 有自己的策略 (Flashbots OFAC-合规,Agnostic 中立,Ultra Sound 不审查等)。 Proposer 通过 mev-boost 软件同时听多个 relay → 选出价最高那个。
  6. 为什么用"私有 mempool"(Flashbots Protect)就能避免被 sandwich? ⇒ 你的 tx 不经过公共 P2P 网络,直接发给 builder(或 relay);公共 mempool 里 searcher 看不到 → 无法在你前面塞 frontrun tx。代价:builder 知道你的内容(信任假设转移)。
  7. 我们 publicnode mempool filter expired after 5s——为什么? ⇒ 公共 RPC 是无状态负载均衡的代理:你的"订阅"其实附在某一台后端节点上,请求被路由到另一台时 filter 就失效。生产 MEV 必须用自建 WSS 节点——05 §3.2 已展开过基础设施层面,14 接的是经济意义层面。
  8. PBS 把决定权移给 builder,那 builder 不会作恶吗? ⇒ 单个 builder 的"作恶空间"=塞自己的 MEV tx + 收 searcher 的 bundle 费用。 但 builder 之间相互竞争 → 出价更高的 builder 拿下 slot → 长期看 builder 经济收敛到 "尽量多收 MEV + 给 proposer 出价高 + 留小利润给自己"。这就是 MEV 经济学的均衡

→ 这一篇答全部。


2. 它本质在做的"那一件事"

把"一笔 tx 从签名到上链的 12 秒生命窗口"工程化为一条流水线: mempool(每节点本地)→ gossip 扩散 → builder 抓取 + 私有订单流 + searcher bundle 拼装 → relay 拍卖 → proposer 选高价 sign(不看内容)→ slot 出块。 这条流水线的每个环节都是 MEV 经济活动的舞台:看 mempool 找 victim、抢 builder 信任、 给 proposer 加 tip、绕开 OFAC 审查、与他 searcher 拼速度……一切都在这 12 秒里发生。

→ 这是为什么 MEV 不是"找漏洞"——它是对 PBS 流水线每个环节理解 + 执行力的较量。


3. 类比:村庄"快递分拣 + 邮局拍卖"

01–13 的村庄已经有了 EVM 计算器、AMM 桶、Aave 当铺、Oracle 邮差。 14 加的是这一切之间消息传递的物流系统:

┌── 节点本地 mempool ─────────────────────────────────────────┐
│  每户村民(节点)家门口有个收件箱(mempool)                  │
│  邻居寄来的 tx 都先丢进收件箱                                │
│  你(村民)会从自己收件箱里挑、转发给邻居(gossip)          │
│                                                              │
│  **没有"全村统一收件箱"**——每家箱子内容略不同               │
│  最新的 tx 可能 0.5 秒后才扩散到全村                        │
└─────────────────────────────────────────────────────────────┘

┌── Builder(块构造者)─────────────────────────────────────┐
│  builder 是一伙专业的"装箱工"                               │
│  每 12 秒装一只"未来块":                                   │
│    - 从公共 mempool 抓便宜 + 高 tip 的 tx                   │
│    - 从私有 orderflow 拿独享 tx(Flashbots Protect 等)     │
│    - 接 searcher 发来的 bundle(封装好的 MEV 套餐)         │
│  装好之后,把这只块**估价**:"我这块能赚 N ETH"             │
│  装箱工之间互相竞争——同一时刻有几十只候选块在拼              │
└─────────────────────────────────────────────────────────────┘

┌── Relay(中介拍卖)+ Proposer(出块者)─────────────────────┐
│  Relay = 拍卖会:                                            │
│    每个 builder 把自己候选块的 header(标签)+ 出价交给 relay│
│    relay 整理:"现在有这些块,最高出价是 N ETH"              │
│                                                              │
│  Proposer = PoS 抽中的村民:                                 │
│    他不亲自装块——他打开 mev-boost 软件:                    │
│       "给我现在最高价的 header"                             │
│    relay 给他一个标签 + 价格 → proposer sign 它             │
│    sign 完成那一刻 relay 才揭开块体 → 全村广播 → 落账       │
│                                                              │
│  Proposer 全程不知道块里装了什么:                            │
│    他只看到"这个标签价 0.05 ETH,我 sign 它能拿 0.05 ETH"   │
│    内容是不是审查 / 是不是恶意 — 全靠 relay 选择             │
└─────────────────────────────────────────────────────────────┘

→ 一图说尽 04 §5 PBS 全貌:Proposer 卖slot 上某块的签名权;Builder 出价竞争;Relay 当公证。


4. 核心关键点(5 条)

  1. Mempool 是"per-node local cache",不是全网共享队列

    • 每个节点维护自己的 pending tx 集合
    • tx 通过 devp2p gossip 协议向邻居广播;扩散是概率性的
    • 不同节点的 mempool 内容会略不同(特别是高峰期)
    • 没有"上链时间"的概念——只有"被某 builder 选进某块"的事件
  2. TX 生命周期 = 7 阶段:

    ① 钱包构造 tx + 签名 (02)
    ② 钱包/dApp 通过 RPC submit eth_sendRawTransaction
    ③ RPC 节点把 tx 放进自己 mempool + gossip 给邻居
    ④ gossip 扩散;任何监听节点 0.1-5s 看到
    ⑤ builder 收纳 → 装进候选块(可能 1 个或多个 builder 同时收)
    ⑥ 12-second slot:relay 拍卖 → proposer 通过 mev-boost 选高价 → sign
    ⑦ block propagation → 全网节点验证 → 落账 → receipt
    
    • ③-⑥ 步任何一个都可能不发生(tx 被 drop / replaced / 价过低永远卡 pending)
    • 当 tx 在 mempool 长时间未上链时,钱包可"replace":用相同 nonce 发新 tx 把旧的覆盖
  3. PBS(Proposer-Builder Separation)= 04 §5 复习 + 经济学:

    • Proposer:PoS 随机选中的 validator;负责 sign 块
    • Builder:专门构造块的实体(专业,跑高性能服务器,订阅多个 mempool + 私有 orderflow)
    • Relay:builder 和 proposer 之间的可信中间人
    • mev-boost:proposer 节点跑的软件,连多个 relay
    • 块价值流向:searcher → builder → relay → proposer
    • 当前 mainnet ~92% 的块走 mev-boost (PBS) 路径
    • 剩下 ~8% 是 proposer 自己装块(vanilla execution layer)
  4. 公共 mempool vs 私有 orderflow:

    维度 公共 mempool 私有 orderflow
    可见性 任何节点 仅特定 builder/relay
    防 frontrun
    信任 不需要 信任 builder 不偷看
    例子 普通 RPC 提交 Flashbots Protect / MEV-Share / 1inch RFQ
    现状 越来越少(大部分智能 router 用私有) 主流(大约 40-60% 量进入私有路径)
  5. Searcher 工具箱的 mempool 部分:

    • 频道 1:监听公共 mempooleth_subscribe newPendingTransactions)→ 看 victim swap → 算 backrun → 抢
    • 频道 2:监听 builder 的 hint stream(如 Flashbots MEV-Share)→ 用模糊化的提示构造 backrun
    • 频道 3:与 builder 直接合作(私有 orderflow 共享,搜寻独家机会)
    • 三条路径互有交叉,专业 searcher 三条都跑;普通用户/教学场景跑频道 1

5. 必须先认识的前置名词(小词典)

名词 一句话 类比
mempool 节点本地待打包 tx 的临时缓存 收件箱
devp2p 节点间 P2P 通信协议(包含 tx gossip) 邻居互通的传话规则
gossip 节点间扩散信息的方式 村民口耳相传
pending tx 已签名提交、未上链的 tx 寄出但没到的快递
eth_sendRawTransaction RPC 提交已签 tx 的入口 把信投进邮筒
eth_subscribe newPendingTransactions 订阅 pending tx 流的 RPC 方法 实时收件箱监听
priority fee / tip 给 proposer 的小费(07 §4.3) 加急费
base fee 每块协议自调、销毁(07 §4.3) 村规价
builder 专门构造候选块的实体 装箱工
relay builder 与 proposer 之间的中介 拍卖会公证
proposer 当 slot 出块的 PoS 验证者 这一秒的执笔人
mev-boost proposer 节点跑的 PBS 软件 拍卖客户端
bundle searcher 提交的 tx 列表,原子打包 套餐
frontrun / backrun / sandwich 抢在前 / 抢在后 / 前后夹击 抢插队 / 收尾 / 两边夹
private orderflow 不经公共 mempool 的 tx 流 走 VIP 通道
MEV-Share Flashbots 推的"匿名提示 + 收益分成"方案 模糊化的拍卖广播
OFAC compliance 美国制裁名单合规(Flashbots 默认开 2022) 拒收某些地址的快递
commit-reveal proposer 先 sign 标签、relay 后揭开块体的两步协议 蒙眼竞拍
searcher 找 MEV 机会的实体 战场扫荡兵(13 §5 词典)

6. 一个完整过程走一遍:我们 demo-backrun.ts 的端到端

照搬 demo-backrun 的故事——一笔 victim swap 进 mempool、我们的 watcher 捕获、构造 backrun bundle、anvil 演示成功 wei-exact:

─── T0: anvil 启动 fork,--auto-mining off ──────────────────
─── T1: victim EOA 发出 swap ────────────────────────────────
  victimTx = router.swapExactTokensForTokens(
    10 WETH → USDC on Uni V2,
    minOut=...
  )
  victimTx 进 anvil 本地 mempool (pending)

─── T2: 我们的 watcher (mempool.ts) 监听 ──────────────────
  ws.subscribe('newPendingTransactions')
  → 收到 victimTx hash
  → eth_getTransactionByHash(hash) 拿到 raw tx
  → 解码 input:识别是 swap on routerX, [WETH, USDC]

─── T3: 我们的 predictBackrun.ts ───────────────────────────
  根据当前 reserves 算出:
    - victim swap 后 Uni V2 的新 reserves
    - 与 Sushi 的价差是否值得做 backrun
    - 最优 backrun amountIn (10 §4 闭式公式)

─── T4: 我们构造 backrun bundle ────────────────────────────
  bundle = [
    victimTx,                                       // 先 victim
    arbTx (we send to Arbitrageur.arb([Uni, Sushi], USDC, 26869e6))
  ]
  注:在 anvil demo 里我们直接给本地 sequencing 二者
  在生产里我们把这个 bundle 发 Flashbots relay (16 待写)

─── T5: anvil 通过 evm_mine 触发出块 ───────────────────────
  → 块包含 [victimTx, arbTx] 按顺序
  → victimTx 执行:Uni V2 价偏向 USDC 一边
  → arbTx 执行:闪电贷 + 借此偏离做套利 + 还款

─── T6: 验证 ───────────────────────────────────────────────
  P1 = predictBackrun 预测的 profit (我们事前算的)
  P2 = anvil 真实 post-tx 状态读出的 profit
  P3 = arbTx 实际链上利润扣 5bps premium

  P1 = P2 = 2419.7984 USDC   (wei-exact!)
  P3 = P2 - 5bps premium     (1 wei 误差源于整数除法)

→ 这就是为什么 demo-backrun.ts 是项目里最 deterministic 的 MEV 演示:

  • 不依赖公网 mempool(避开 publicnode 5s 过期问题)
  • 不依赖 Flashbots(避开 relay 不可控)
  • 纯 anvil + 我们的逻辑 → P1 = P2 字节级一致 → 证明 watcher + predictor + executor 三件套全对

生产 vs 教学的差异

维度 我们 demo-backrun (anvil) 真实主网
Victim 来源 我们自己构造 公共 mempool 看到(频道 1)
Mempool 来源 anvil 本地 自建 WSS 节点(05 §3.2)
Bundle 提交 直接 evm_mine Flashbots relay 提交
排序保证 anvil 顺序 builder 接受 + 包含进块
竞争 ~100+ searcher 同时盯同一 victim

→ 教学场景把 wei-exact 推导跑通即胜利;真实场景胜负在毫秒


7. 常见误区(逐条拍死)

误区 实情
"Mempool 是全网共享的" 错。每个节点本地各一份。gossip 协议同步但不保证全网状态一致
"TX 上链顺序 = 提交时间" 错。按 priority fee 排序 + searcher MEV 竞争 + builder 自身策略
"高 gas price 一定先上链" 大概率,但 builder 可能拒收(OFAC / 计算成本高 / bundle 冲突)
"Flashbots 不审查" Flashbots 自 2022 起对 OFAC 制裁地址做 filtering(默认开)。中立 relay 有 Agnostic / Ultra Sound / BloXroute(部分)
"私有 mempool = 匿名" 错。Builder 看到全部内容。是"对公众观察者隐藏",不是"对所有人隐藏"
"Proposer 决定块内容" PBS 下不是。Proposer 盲签 header;内容由 builder 决定
"Relay 是 builder" 不同角色。Relay 是中介公证;builder 是块装配工。一家公司可同时跑(Flashbots 跑 builder + relay)
"Mempool 是协议层" 不是。它是节点实现层——不在 EVM 规范、不在 consensus 规范、各客户端实现策略可不同
"Searcher 看 mempool 就够了" 对低端 MEV 是。高端 searcher 还订阅 builder hint 流(MEV-Share)+ 私有 orderflow + ASIC 级硬件加速
"我能监听 mempool 就能赚 MEV" 监听是入门。赢的关键:基础设施延迟(毫秒)+ 算力(同时算几十种 backrun)+ 资金(高 tip 抢入)+ relay 关系
"PBS 让 MEV 减少了" 反了。PBS 正规化 + 提高效率了 MEV 提取。MEV 总量没减少;只是分配从 proposer 移到 builder/searcher 链
"搭个家用机就能跑生产 searcher" 现实不行。延迟 + 带宽 + 算力 + relay 信用都要积累。这是 05 §5 L0–L4 阶梯接此

8. 与本项目实践的对应

mempool.ts watcher(Phase 5 step 2)

  • provider.on("pending", ...)(ethers v6 内部走 eth_subscribe)订阅 pending tx
  • 收到 hash → getTransaction(hash) 拿 raw → 解码 input 判断是否 V2 swap
  • _seenHashes: Set<string> 去重(同一 hash 在多个节点上扩散会被反复推送)
  • 触发 predictBackrun 算潜在收益 + 决定是否提交 bundle

publicnode mempool filter expired 的精确解释

  • publicnode 是 stateless load balancer:你的 WSS subscribe 实际附在某一台后端节点
  • 但同一连接的不同请求被路由到不同节点 → 第二台后端不认识你的 filter id → 5 秒后告诉你过期
  • 解决方案两条:(a) 自建 geth/erigon 节点跑 WSS(05 §3.2 L1);(b) 用 alchemy/infura 的 enhanced subscription(专为 dev 提供 sticky session)
  • 教学场景我们选 (a) 的简化版:用 anvil 跑 fork 演示 demo-backrun

predictBackrun.ts 中的"factory mismatch"修正

  • 早期 bug:1 ETH 在 Uni V2 swap 进了 mempool → predictBackrun 盲目对每个池套用 → 误报"Sushi 也受影响"
  • 根因:没区分调用 router → factory 的映射
  • 修复:predictBackrun(routerAddr, ...)只把跟 routerAddr 同一 factory 的 pair 当 victim 影响目标
  • 这是项目里 evidence-first 自我抓 bug + 修正的小例子,连回 docs 自我更正纪律

demo-flashbots.ts 真实 relay 握手

  • 通过 @flashbots/ethers-provider-bundle SDK 包装 bundle
  • 提交到 https://relay.flashbots.net → 收到 structured error "insufficient funds for gas * price + value: have 0 want 1050000000000000" = 0.00105 ETH = 50 gwei × 21000 (EIP-1559 ceiling × min gas)
  • 这条 error 是关键证据:整个 SDK / auth / transport 链路全通过 relay 验证,只差 EOA 没有真 ETH
  • 16 篇 Flashbots / bundle 待写时会回到这条 → 把 protocol 层端到端讲透

04 / 05 / 06 / 07 / 11 / 12 / 13 → 14 的承接

  • 04 §5 PBS 给 MEV 的结构性根;14 把 PBS 从协议结构 → 经济流水线
  • 05 §3.2 mempool 给基础设施的硬件需求;14 给经济意义上的"看到/被看到"含义
  • 06–07 给一笔 tx 在 EVM 里跑的细节;14 给一笔 tx 进 EVM 之前 12 秒的细节
  • 11 + 12 给 MEV 机会的来源(清算 + oracle 抖动);14 给"怎么把机会变现"的执行层
  • 13 给"零本金"的杠杆;14 给"找到目标 + 抢到执行权"的路径

第四层的串接

  • 14 mempool 给"看到机会 + 抢到执行权"
  • 15 MEV 给"策略类目"(套利 / 清算 / 三明治 / backrun 各自机制)
  • 16 Flashbots / bundle 给"上线提交工具链"(demo-flashbots 接的就是这条)
  • 17 跨链给"机会跨域 → 失去原子性 → 新风险新机会"

9. 自检问题(答得出才算过)

  1. Mempool 是全网共享队列吗?为什么不同节点看到的 pending set 会不同?
  2. 一笔 tx 从签名到落账经过哪 7 阶段?哪几步可能"永远没发生"?
  3. PBS 中 proposer / builder / relay / searcher 各自做什么?块价值的流向是?
  4. 为什么 proposer 盲签 header 而不看块内容?这种 commit-reveal 设计解决了什么问题?
  5. 公共 mempool 和私有 orderflow 在可见性、防 frontrun、信任假设上各自如何?为什么主流智能 router 都走私有?
  6. "publicnode mempool filter expired after 5s"在节点架构上是什么?怎么彻底解决?
  7. 我们 demo-backrun.ts 为什么能 P1 = P2 字节级一致?这种 wei-exact 在主网上能不能成立?
  8. PBS 让 MEV 提取量增加还是减少了?为什么?

── Q&A / 更正记录区(按日期追加)──

规范见 README.md §0。质疑/反馈/纠错按日期累积,不抹错误轨迹。

  • (2026-05-21 建立。暂无 Q&A。)

  • (2026-07-27) 问:详细讲一下交易的竞争与打包机制。

    答(补充"竞争"具体竞的是什么、"打包"具体怎么排序,未更正原文;完整版含交易全流程 stepper 见 ../total/Q&A/2026-07-27-链上账本手记.html 第三节 "竞价广播"/"打包"两步):

    竞价广播:交易广播进 mempool,此刻公开可见但未生效。EIP-1559 后费用分两块:base fee(协议按 上一块拥堵程度自动设定,每块最多变动 ±12.5%,这部分被销毁,不给任何人)+ priority fee/tip (自己出的小费,真正付给打包者的钱)。effectiveGasPrice = min(maxFeePerGas, baseFee + maxPriorityFeePerGas)"竞争"竞的就是这笔 tip:builder 天然倾向优先打包 tip 更高的交易, 因为区块空间有限。MEV searcher 竞争的不是"谁先广播",是"谁能出更高价格/给 builder 更好的组合收益, 换取交易被排在关键位置之前或之后"——这也是大额交易走私有 orderflow 直接发给 builder、不进公开 mempool 避免被抢跑的原因。

    打包:一个块的总 gas 有硬上限(以太坊主网约 3000 万 gas,协议目标平均用量落在 1500 万, base fee 就是照着"上一块用量相对目标高低"调的杠杆)。builder 从 mempool(以及私有 orderflow) 里挑一批交易,目标是让这个块的总收益(tip 总和 + 可提取的 MEV)最大化,不是谁先来就排谁—— 常见误区"打包=排队窗口先来后到"是错的,实际排序逻辑更像一场组合竞价。PoS 之后这个流程进一步拆成 proposer(出块权持有者)和 builder(实际组装区块内容的专业角色),大多数区块通过 mev-boost 这类 中继完成"proposer 盲选出价最高的 builder 方案"这一步(PBS)。

    与滑点的串联:竞价排序权 + 交易方设置的滑点容忍空间(amountOutMin)合在一起,正是三明治攻击 的具体机制——完整推导见 10-DEX与AMM.md 同日条目。