承接 01(账本去中心化)+ 03 (改一处=重写其后所有块+跑赢全网)。前三篇解决"账本不可篡改",但留了一个根本问题: 谁来写下一页?怎么让全网自发认同一条链?——这一篇答。 顺带把MEV 的结构性根源讲清——它不是 bug,是"谁排序,谁拿钱"的必然副产物。 沿用村庄账本画面。结构见 README.md §1。


0. 一句话本质

没有裁判的网络里,"谁有权写下一页"和"全网怎么自发认同一条链"靠两件事: ① 让"假装成很多个人"代价高到不划算(Sybil 抗性,PoW 烧电 / PoS 押币); ② 让所有人自发跟同一条"最长/最重"的链。 副产物是:出块者拥有排序权 → 排序权值钱 → MEV。


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

03 留了一串没答的问题:

  1. 谁写下一页? 没有银行/没有管理员/没有裁判,谁来当本轮执笔人?
  2. 若多人同时写,凭什么全村只认其中一本? —— **分叉(fork)**怎么处理?
  3. 怎么阻止有人造一千个假身份伪装"多数"? —— **女巫攻击(Sybil attack)**怎么防?
  4. "算赢全网"具体是算什么? —— PoW 烧电、PoS 押币,本质都是"让作恶代价 > 收益"。
  5. 既然出块者能决定一块里装哪些交易、怎么排——这个权力值钱吗? —— 是的,这就是 MEV

→ 共识机制 = 在开放、无信任、异步、可能有恶意参与者的网络里,让全网对"哪条链是真账"自发达成一致的规则集。


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

把"无裁判下的协调"转化为"有真实代价的角色 + 一条机械的择优规则"。 两件事缺一不可:

  • Sybil 抗性:让"成为出块候选人"要么烧电(PoW)要么押币(PoS)。 假身份不是被禁止,是被定价——你伪装一千个,就得付一千份代价。
  • 择优规则(fork choice):所有诚实节点本地各自跑同一条规则 ("跟着最长/最重的链"),自然汇聚到同一条历史。不是投票,是博弈均衡。

3. 类比(村庄账本视角)

3.1 PoW(工作量证明)= 一场全村数学彩票

全村想抢着写下一页?发起一场算力彩票:

每个想出块的人:不断尝试不同 nonce,计算 hash(页眉_含nonce) < 目标值 才中奖
→ 难度调整,让全网平均每 10 分钟(BTC)/ 之前 12 秒(ETH-PoW)出一张中奖票
→ 中奖者把那一页广播给全网,其他人验证后接受
→ 烧的电就是 "工作量证明"——没人能凭空多算(除非真烧更多电)

Sybil 抗性:你想"假装一千个矿工"?没用,算力总和不变,胜率取决于实际算力。 作恶代价 = 放弃中奖收益 + 大量电费打水漂。

比特币至今仍用 PoW。以太坊 2022 年 9 月 "The Merge" 切到 PoS。

3.2 PoS(权益证明)= 一个押金陪审团

想当出块候选人:往合约里押 32 ETH(成为 validator)
→ 协议每 12 秒一个 slot,伪随机(RANDAO)从全部 validator 里抽一个当 proposer
→ 其他 validator 当 attester(见证人),对该块投票
→ 出诚实块 → 拿小额奖励
→ 作恶(双签 / 长程攻击 / 投错块)→ 押金被 slashing(部分或全部销毁)

Sybil 抗性:你想"假装一万个 validator"?得真押 32 万 ETH。胜率正比于你押的总币量, 作恶代价 = 真金白银被烧(不是只是失去机会,而是没收)。

这就是为什么 PoS 不耗电、且作恶代价更直接显式。代价:质押集中度问题(少数大池)。

3.3 Fork choice:两本账本打架时全村怎么自发一致

两个有效区块同时在 100 高度出现 → 网络分叉 → 大家先各自接受一边继续。 但都遵循同一条规则:跟着累积工作量最大(PoW)/ 累积投票最重(PoS)的链。 几块后,落后那条会被全村放弃(uncle / orphan),赢家的链成为规范链。 没有人投票"哪条是真的",规则机械执行的结果就是收敛。 这是 03 §6 场景 A "改三天前一页要跑赢全网"的"赢"的精确意思。

3.4 Finality:从"概率"到"经济不可逆"

  • PoW:finality 是概率性的。深度 N 块后被反转的概率 ≈ 攻击者算力比例^N, 随 N 指数下降。"等 6 个确认"就是在买概率。
  • 以太坊 PoS(LMD-GHOST + Casper FFG):每约 2 个 epoch(≈12.8 分钟)累计够票 → 该高度经济终局(economic finality)。要反转必须使 ≥ 1/3 总质押 ETH 被 slashing 销毁(当前规模下数百亿美元)。这是定量上界,不是迷信

4. 核心关键点(5 条)

  1. 共识问题 = 在开放、无信任、异步、可能有恶意的网络里,让所有人自发同步同一条链。
  2. Sybil 抗性靠真实代价:PoW=电力/硬件,PoS=被 slash 的押金。否则"多数"无意义。
  3. 领袖选择:PoW = 解谜中奖(概率);PoS = 协议伪随机选 proposer(确定 slot)。
  4. Fork choice + finality:所有诚实节点跑同规则自发收敛(最重链); PoS 加经济终局。"N 个确认"是这条的量化。
  5. MEV 的结构性根(连接整个 Phase 5)出块者决定块内交易选什么、怎么排 → 排序权值钱 → frontrun / backrun / sandwich 等。 现代以太坊把它拆成 PBS(Proposer-Builder Separation)
    • Builder:监听 mempool + 私有 orderflow,模拟出"最赚钱的块"并给 proposer 一个出价。
    • Proposer:盲选最高出价的块,签名广播(自己不直接排交易)。
    • Relay(如 Flashbots):中介,转发 builder 的出价、保证 proposer 不能偷看后偷换。 → 我们 flashbots.ts 真实握手过的 relay.flashbots.net 就是这一环。 → 我们 Arbitrageur / LiquidationBot 的 bundle 是付给 builder 的 "tip"。 → 这就是"散户抢不过头部"的结构原因:竞争发生在 builder 层,看谁的块更赚 proposer。

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

名词 一句话 类比
PoW / PoS 烧电出块 / 押币出块 算力彩票 / 押金陪审团
Miner / Validator / Proposer PoW 矿工 / PoS 押币人 / 本 slot 被选中出块的 validator 彩民 / 陪审员 / 本轮执笔人
Attester / Committee PoS 中对块投票的见证 validator 见证陪审员
Stake / Slashing 押 32 ETH 当 validator / 作恶被罚销毁押金 押金 / 没收
Slot / Epoch Eth 12 秒一 slot;32 slot 一 epoch(6.4 分钟) 一笔轮值 / 一次大对账
Beacon Chain 以太坊 PoS 共识层 主裁判系统
The Merge 2022-09 以太坊从 PoW 切 PoS 全村换了出块规则
Fork choice "选哪条链"的规则(最重链 / LMD-GHOST) 全村默认认更长那本
Reorg 短分叉、几块被回滚 两版账本临时打架
Finality(probabilistic / economic) 不能反转的程度(概率 / 经济) 这页被焊死的牢固度
Uncle / Orphan 没被采纳的有效块 输掉那一版页
EIP-1559 base fee / priority fee 基础费销毁 + 小费给 proposer 工本费烧掉 + 加急费给执笔人
block.coinbase.transfer 合约直接转 ETH 给本块 proposer bundle 给执笔人塞小费
PBS (Proposer-Builder Separation) proposer 不亲自排交易,盲选 builder 出价 执笔人外包给出价最高的"块工"
Builder / Relay / mev-boost 构块者 / 中介 / proposer 接 builder 的客户端(现 90%+ ETH 块走它) 块工 / 中介 / proposer 的官方接单器
Searcher 找 MEV 机会、构造 bundle 给 builder 的人/bot 给块工提供"加价交易包"的猎手
私有 orderflow 不广播到公开 mempool、直接给特定 builder 私洽订单不进公示栏
MEV "谁排序谁拿钱"产生的可提取价值 排序权变现

6. 端到端:以太坊 PoS 一个 12 秒 slot 完整发生了什么

把上面零件串起来。这恰好是我们 Phase 5 所有动作的真实背景:

T = 0  s   ┃ Slot N 开始
            │ Beacon Chain 用 RANDAO 伪随机选出本 slot 的 proposer V

T = ~0–4 s ┃ V(其实是它跑的 mev-boost 客户端)向多个 relay 询价:
            │   "本 slot 谁能给我最赚的块?"
            │ Builders(如 beaverbuild / rsync 等)平时一直在做的事:
            │   · 监听公开 mempool + 各家私有 orderflow(搜聚集来的 bundle)
            │   · 用本地 EVM 试排所有可能组合(其中包括 Searcher 投递的
            │     bundle——我们 Arbitrageur 那种),找出"最赚 proposer 的块"
            │   · 这个块尾部通常给 V 一笔 coinbase.transfer 的 tip
            │ Builders 把出价(含 block hash + 价格)签名发给 relay

T = ~4 s   ┃ V 让 mev-boost 在所有 relay 拿到的出价里选最高
            │ V 签名"我承诺出这个 hash 的块",**还没看到内容**(盲选)
            │ relay 收到承诺后才把完整块体发给 V → V 广播全网

T = 4–12 s ┃ 全网节点收到块、验证(state root / Merkle 根 / 签名等,见 02/03)
            │ Slot N 的 committee 投票(attest)该块

T = 12 s   ┃ Slot N+1 开始,新的 proposer 重复以上

~2 epoch 后┃ 累计票够 → 该块进入 **economic finality**(再反转要烧 1/3 总质押)

这一节直接解释了我们项目里几件具体事

  • bundle 投 block N+1:因为下一个 slot 的 proposer 已经定了,我们能精确瞄准一个槽。
  • Flashbots resolution "block passed":你的 bundle 在那 slot 没被任何 builder 选中 组进胜出块(可能被别人更高 tip 的 bundle 挤掉,或那一 slot 的 proposer 没跑 mev-boost)。
  • "散户抢不过":竞争是 builder 层的 bundle 锦标赛——你和老练 searcher 同台 竞价同一个 proposer 的注意力,最高 tip 赢。这与"看懂某地址"无关。
  • block.coinbase.transfer 在 BundleExecutor.sol 的意义:这就是直接给 proposer 塞钱的语法实现(见 notes-simple-arbitrage.md §2)。

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

误区 实情
"共识就是大家投票多数决" 不是直接投票。是"每个诚实节点本地跑同一条 fork-choice 规则,结果自然收敛"。Sybil 代价让"多数"才有意义
"PoW 公平,PoS 让有钱人更富" PoW 大算力厂 + 矿池集中度更高;PoS 至少把作恶代价显式化(slashing)且不耗电。两者都有集中化问题,没有干净答案
"PoS 没消耗就不安全" 安全来自质押被 slash 的经济威胁,不是"消耗"本身。以太坊当前总质押 ETH 数千万、攻击成本数百亿 USD
"矿工/验证者完全自由选择交易" 名义上是。但 PoS 后约 90%+ 块通过 mev-boost = proposer 盲选 builder 现成块,实际排序权在 builder 手里。这是为什么"竞争发生在 builder 层"
"reorg 不会发生" 1–2 块浅 reorg 是日常;finality 后近不可能(要烧 1/3 总质押)
"Gas 全给矿工/验证者" EIP-1559 之后:base fee 被 burn,priority fee(tip)给 proposer。MEV 还可通过 coinbase.transfer 直接付
"MEV 是 bug 应该消灭" 不是。任何有"排序权 + 经济价值不对称"的系统都会出现 MEV(传统金融的 PFOF、暗池、HFT 同类)。MEV 不会消失,只会改变分配(PBS 把它从黑市搬到公开市场,让更多人分到一杯)
"Flashbots 是中心化的,所以违背了去中心化" Flashbots relay 是中心化的单点,这点本身是承认的;但它是 PBS 演进期的临时实现,多家 relay(bloXroute / Eden / Aestus / Agnostic / Ultra Sound 等)并存,是开放市场。长期方向是去信任化的 PBS
"Searcher = Builder = Proposer" 三个不同角色。我们项目里我们是 searcher(找机会、产 bundle);不是 builder(构块);不是 proposer(出块)

8. 与本项目实践的对应

  • "每 12 秒一块" → §3.2 PoS slot;mempool.ts 撞墙的"HTTP 轮询比出块慢"就是这个 12s 的紧迫
  • bundle 投 block N+1 → §6 时间线:我们瞄准下一 slot 的 proposer
  • relay.flashbots.net → §4.5 PBS 中的 relay 角色;demo-flashbots.ts 的握手是我们以 searcher 身份接入这套机器
  • X-Flashbots-Signature → searcher 身份指纹,让 relay/builder 跨次请求识别同一 searcher 做信誉积累
  • BundleExecutor.solblock.coinbase.transfer → §5 EIP-1559 之外的直接 tip 通道,是 Flashbots 模式的标志
  • "散户抢不过"为什么 → §6 真正的竞争场在 builder 层;与"看某个地址"无关。这是 docs 2026-05-19 自我更正的精确机制
  • anvil --block-time 2 → 本地模拟出块节奏(不是真 PoS,但模拟 slot 紧迫感)
  • 0x65A8 4 年盈利运营 → 在 PoS proposer/builder 经济里真正占位的人;他要么是 searcher(赚 bundle 价差)、要么是 builder/MM/做空投——具体不可知,但他的位置在这套结构里

→ 04 是 Phase 5 一切 watcher / mempool / Flashbots 工作的——读完回头看那些代码, 从"它在做什么"升级到"它为什么在 PBS 这个市场结构里这么做"。


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

  1. 共识机制要同时解决哪两件事?为什么"投票多数决"在开放网络里直接行不通?
  2. PoW 和 PoS 的 Sybil 抗性各靠什么?为什么说两者都是"作恶代价 > 收益"?
  3. Fork choice 规则是怎么让全网"不投票就自发一致"的?
  4. 概率性 finality 和经济终局有什么区别?以太坊 PoS 反转 finalized 块需要付出什么具体代价?
  5. PBS 把"出块"拆成哪三个角色?为什么说真正的排序权在 builder 而不在 proposer?
  6. "MEV 是 bug 应该消灭"哪里错了?PBS 改变了 MEV 的什么、没改变什么?
  7. 我们项目里"bundle 被 relay 接收但 block passed",在 §6 时间线上具体卡在哪一步?

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

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

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

  • (2026-07-26) 问:详细补充哈希函数的算法细节,包括 hash 过程怎么"求解"出前面几位固定值。

    答(补充 §3.1 PoW 那句"不断尝试不同 nonce"背后的精确机制,未更正原文;SHA-256/Keccak-256 内部算法细节见 02-密码学三原语.md 同日条目):

    矿工要做的事,一句话:反复换一个叫 nonce 的字段,重新完整跑一遍确定性的哈希算法(比特币是 SHA256(SHA256(...)),以太坊 PoW 时代是 Ethash),直到算出的哈希数值小于协议规定的目标值(target)

    1. target/前导零位数是协议外部设定的门槛,跟哈希算法内部计算完全无关——把 256 位哈希输出当成一个巨大二进制数,协议规定"必须小于目标值 T";T 通常远小于 2²⁵⁶,等价说法是"至少 d 个前导零比特"。d 不是哈希算法算出来的,哈希算法根本不知道有难度这回事,它只是老老实实按固定步骤把输入变成 256 位数字。

    2. 为什么必须暴力试、没有捷径:哈希函数的单向性(无法从想要的输出反推能产生它的输入)+ 雪崩效应(输入变 1 比特输出近乎全变)意味着输入输出之间不存在任何代数关系,不能像解 x+3=7 那样解出 x=hash⁻¹(目标值)。唯一已知方法:

      nonce = 0
      while True:
          h = SHA256(SHA256(区块头 with nonce))
          if int(h, 16) < target:
              break  # 找到合法区块!
          nonce += 1
      

      每次尝试都是换 nonce、完整重跑一遍哈希算法——这才是"求解"的真正含义:穷举搜索,不是解方程。"工作量证明"这个名字就来自"能拿出满足条件的 nonce,本身就是确实算了很多次哈希的证明"。

    3. 概率推导:哈希输出视为 [0, 2²⁵⁶) 上均匀分布,命中概率 p = target/2^256;若难度要求 d 个前导零,target ≈ 2^(256-d),代入得 p = 2^-d。每次尝试独立(几何分布、无记忆性),期望尝试次数 E[尝试次数] = 1/p = 2^d——直观类比连续抛硬币要求连续 d 次正面。每多 1 位前导零,平均算力需求翻倍,这是"难度"的数学本质,也是比特币每 2016 块根据实际出块速度自动调整 target 维持 10 分钟出块的原理。

    4. 可运行验证(几秒跑完,不需要真的挖矿):

      import hashlib
      def leading_zero_bits(h: bytes) -> int:
          n = int.from_bytes(h, "big")
          return 256 - n.bit_length() if n else 256
      target_zero_bits = 16   # 期望约 2^16 = 65536 次
      nonce = 0
      while True:
          data = f"block-header-{nonce}".encode()
          h = hashlib.sha256(hashlib.sha256(data).digest()).digest()
          if leading_zero_bits(h) >= target_zero_bits:
              print(f"找到!nonce={nonce}, hash={h.hex()}"); break
          nonce += 1
      

      实测命中所需 nonce 次数在 2¹⁶ 附近波动,且没有规律可提前预测——直接实证"暴力搜索、无捷径"。

    5. 纠正问题里的表述:"前面几位是固定值"不准确——不是算法让输出前几位固定,是矿工靠运气撞中满足门槛的输出,纯暴力搜索、无捷径(除非哈希函数本身被攻破,那是行业级灾难,是另一回事)。

    完整原始记录见 ../total/Q&A/2026-07-26.md Q2、02-密码学三原语.md 同日条目。