以太坊的目标不仅是做“去中心化的货币”,更是要做“去中心化的计算平台”。这就要求它在一个开放的点对点网络中,既要像比特币那样保证状态的一致性和安全性,又要支持更快的出块时间和复杂的智能合约执行。
共识机制和挖矿机制,是以太坊实现这一目标的核心。以太坊从早期的工作量证明(Proof of Work, PoW)起步,经历了 Ethash 算法、GHOST 协议、难度炸弹等一系列设计与演化,最终在 The Merge 升级后,完全切换到了权益证明(Proof of Stake, PoS)。
本文只聚焦这条演化线:以太坊是如何通过 PoW 挖矿来达成共识,又是如何一步步迁移到 PoS 的,以及背后关键算法和设计取舍。
概览
以太坊在不同阶段采用过两套共识思路:
- PoW 时代:
- 使用 Ethash 作为挖矿算法,通过算力竞争来选出新区块。
- 出块时间大约 12–15 秒,远短于比特币的 10 分钟,导致分叉更频繁。
- 采用GHOST 协议和叔块奖励来减轻频繁分叉带来的中心化偏向。
- 引入难度炸弹,为未来从 PoW 迁移到 PoS 埋下“倒计时”。
- PoS 时代:
- 共识由质押 ETH 的验证者驱动,不再依赖大量算力和电力消耗。
- Beacon 链负责共识和随机性,原来的 PoW 链变成执行层,专注于智能合约执行。
- 采用 LMD-GHOST 作为分叉选择规则,Casper FFG 提供终局性(finality),配合奖励与惩罚机制保证安全性。
理解这两套机制的关键,是搞清楚三件事:
1.谁来提出新区块(proposer / miner)? 2.全网如何决定哪条链是“主链”(fork choice)? 3.系统如何奖励诚实参与者、惩罚恶意行为?
区块与三棵树
在深入共识和挖矿之前,先把以太坊“区块里到底装了什么”讲清楚,这会反复出现在后面的内容里。
从抽象上看,以太坊是一个带记账本的状态机:
- 状态机的状态是“所有账户和合约当前的状态”;
- 输入是一批交易(转账、合约调用、部署合约等);
- 状态机执行完这批交易之后,从旧状态转移到新状态。
为了让所有节点都能验证“这条状态转移历史是不是合法的”,每个区块都会在区块头里记录三棵关键的树的根哈希(Root):
-状态树(stateRoot):
- 记录“世界状态”,即所有账户和合约的状态。
- 每个账户包含四个核心字段:
nonce(账户已经发出的交易次数)、balance(余额)、codeHash(合约字节码的哈希)、storageRoot(该合约存储的根哈希)。 - 这些账户被组织成一棵Merkle-Patricia Trie(MPT,一种把键值映射存成前缀树,并在每个节点加上哈希的结构),节点哈希通常使用 Keccak-256。MPT 的结构和实现细节会在后面的文章专门讲解,这里先有个整体印象即可。 -交易树(txRoot):
- 本区块中所有交易按顺序编号,作为 key 写入另一棵 MPT,value 是交易的 RLP 编码。
- 这棵树的根叫
txRoot,证明“这个区块里到底有哪些交易,以及它们的顺序”。 -收据树(receiptsRoot): - 每笔交易执行完之后会生成一条 receipt(收据),记录执行结果、消耗的 gas、日志(logs)、日志布隆过滤器(logsBloom,快速筛选“哪些区块里可能包含我关心的日志事件)、状态是否成功等。
- 所有收据也按顺序写入一棵 MPT,根哈希是
receiptsRoot。
和比特币相比:
- 比特币区块头里只有一棵“交易 Merkle 树”的根哈希,代表本区块所有交易;
- 以太坊则直接把“状态树 + 交易树 + 收据树”三棵树的根都放进区块头,描述更精细,也更方便后续做轻节点、日志过滤等功能。
从交易到区块头的大致流程可以画成这样:
flowchart LR T["交易列表"] --> E["EVM 执行"] E --> S["状态树 stateRoot"] E --> X["交易树 txRoot"] E --> R["收据树 receiptsRoot"] S --> H["区块头"] X --> H R --> H H --> POW["共识 / 挖矿"]
后面无论是 PoW 还是 PoS,都是在这个“已经包含三棵树根哈希的区块头”基础上做工作。
PoW 时代
Ethash 挖矿
以太坊早期采用工作量证明(PoW)共识,使用的挖矿算法叫Ethash。它和比特币的 SHA-256 PoW 在总体思路上类似——都是通过不断试 nonce 直到 hash 小于某个目标值——但在细节上做了很多改动。
设计目标(对比 BTC):
- 比特币使用纯计算密集型的 SHA-256,两轮哈希即可,挖矿很快演化为 ASIC 主导;
-Ethash 希望做到【这里是重点】:
- 通过memory-hard设计,让大容量、高带宽内存成为瓶颈,以此来抵制 ASIC;
- 对轻节点友好:轻节点无需完整存储几 GB 的挖矿数据,也能验证某个
nonce是否有效。
为此,Ethash 采用了 cache + DAG(dataset) 的结构
几个关键概念先记住:
epoch:区块高度被划分为若干个 epoch,每 30000 个区块一个 epoch;seed:每个 epoch 对应一个 32 字节的 seed,用来生成 cache;cache:约 16 MB 的数组,由 seed 生成,用来派生 DAG;DAG(dataset):几 GB 级别的大数组,挖矿时会多次随机访问;nonce:64 位随机数,由矿工自行选择和遍历,用来“尝试运气”,改变挖矿哈希的输入;mixHash:挖矿过程中对多次 DAG 访问结果混合后的中间哈希,写入区块头,供验证者检查。
下面分步展开。
Epoch 与 seed 计算
对于任意区块高度 blockNumber:
- 先计算 epoch:
epoch = floor(blockNumber / 30000); - 对于第 0 个 epoch,设定一个固定的初始 seed(例如 32 字节全 0);
- 对于后续的第
n个 epoch,seed 的计算可以理解为“在前一个 seed 上重复做 Keccak-256”:seed_0 = 0x0000...00seed_n = Keccak-256(seed_{n-1})
这样,每个 epoch 都有一个不可预先控制的 seed,任何节点只要知道 epoch 编号,都可以本地计算出该 epoch 的 seed。
Cache 的生成
有了 seed,就可以生成约 16 MB 的 cache。可以粗略理解为:
- 先用 Keccak-512 连续哈希 seed,生成一串 64 字节的块,填满整个 cache:
- 第
i个位置的初始值:cache[i] = Keccak-512(seed || i);
- 第
- 再对整个 cache 做多轮“搅拌”:
- 每一轮中,每个
cache[i]都会根据自身和其它位置的值重新计算,例如:- 取前一个元素
cache[(i-1) mod N]; - 再根据当前值算出一个索引,从 cache 的另一个位置取一个元素;
- 把这些数据按位异或(XOR,一种简单的比特运算)拼在一起,再过一轮 Keccak-512,作为新的
cache[i]。
- 取前一个元素
- 每一轮中,每个
这样,每个 cache[i] 都依赖于 seed 和cache 内其他条目,想伪造其中一小部分几乎不可能,必须整体按照规则生成。
DAG 的生成
DAG(也叫 dataset)是挖矿时真正要频繁访问的大数组,它的体积远大于 cache(GB 级 vs MB 级)。生成过程大致是:
- 对于第
i个 DAG 元素,先从 cache 中取一个“起点”:- 例如
data = Keccak-512(cache[i mod cacheSize] XOR i);
- 例如
- 然后进行多轮混合,每一轮都:
- 根据当前
data计算一个索引,从 cache 中取另一个元素; - 使用一种简单但高效的函数(FNV hash,一种快速的非密码学哈希函数)把
data和这个元素混合在一起;
- 根据当前
- 多轮混合后,对最终的
data再做一次 Keccak 哈希,得到固定长度的 DAG 节点。
整个 DAG 的每个元素都以这种方式生成,矿工通常会:
- 在挖矿前生成整个 DAG,存放在显存 / 内存中;
- 轻节点则不存 DAG,而是当需要验证某个挖矿结果时,根据 cache按需生成对应的 DAG 元素即可。
挖矿 puzzle:Hashimoto 流程
有了 DAG,Ethash 的挖矿流程(Hashimoto)大致如下:
- 矿工先构造好区块头(包括父块 hash、三棵树根哈希
stateRoot/txRoot/receiptsRoot、时间戳、难度等,不含nonce和mixHash)。 - 选择一个 64 位的候选
nonce,把区块头和nonce拼起来,做一次 Keccak-256,得到初始的headerHash:headerHash = Keccak-256(blockHeader || nonce)
- 用
headerHash初始化一个称为mix的状态向量,然后进行多轮循环:- 每一轮用 FNV hash 从 DAG 中选出一个位置:
index = FNV(mix, round) mod dagSize; - 读取
DAG[index],再用 FNV 把它和mix混合:mix = FNV(mix, DAG[index]); - 如此往复循环 64 轮
- 每一轮用 FNV hash 从 DAG 中选出一个位置:
- 循环结束后,压缩
mix得到mixHash,再对其做一次 Keccak-256 得到最终结果 hash:mixHash = Compress(mix)result = Keccak-256(mixHash)
- 检查
result是否小于当前难度目标target:- 如果
result < target,则认为挖矿成功,把nonce和mixHash写入区块头并广播; - 否则就换一个新的
nonce继续从第 2 步开始尝试。
- 如果
在这个过程中:
- Keccak 哈希提供了密码学上的抗篡改和不可预测性;
- FNV 提供了快速混合和索引计算,强调内存访问顺序的不可预测;
- 大量对 DAG 的随机访问,使得挖矿瓶颈在内存带宽,而不只是纯算力。
nonce 的角色(顺带澄清账户 nonce)
在 Ethash 挖矿里提到的 nonce 是“区块头的 PoW 随机数”,与账户里的 nonce 完全不同:
-账户 nonce:表示某个外部账户已经发出了多少笔交易,防止重放攻击(这点在你原始笔记“重放攻击”那一节会详细展开); -区块 nonce:只在 PoW 时代存在,用于挖矿 puzzle,矿工可以在合法范围内任意选择和遍历,用来改变区块头哈希的输入,从而“摇彩票”。
矿工在尝试时可以:
- 顺序递增
nonce(0,1,2,3,…); - 或者随机挑选
nonce; - 甚至在
nonce空间用完时(2^64 次尝试)调整区块里的其它可调字段(例如 coinbase 交易中的 extra nonce)来继续搜索。
总结
和比特币“先挑选交易、先算 PoW、后执行验证”的观感不同
以太坊的挖矿流程总结如下:
- 矿工从本地的交易池(mempool)中挑选一批尚未打包的交易(通常会优先选择 gas price 较高的交易,以获得更多手续费)。每个节点在挖矿期间的交易池内容可能略有不同,这不要紧,因为真正写进区块的“那一批交易”以后会成为共识的一部分。
- 在本地按固定顺序执行这些交易:
- 使用 EVM 按字节码规则执行合约;
- 更新世界状态树(stateRoot),并记录每笔交易对应的收据(写入 receiptsRoot),并把每笔交易写入交易树(txRoot);
- 如果交易结构是合法的,但是在执行过程中触发了
revert(例如require条件不满足、余额不够转账等),那么这笔交易仍然会被打包进区块:- 状态修改会回滚到执行前的样子;
- 但已经消耗掉的 gas 不会退还,收据里会标记执行失败。
- 之所以这样设计,是为了防止 DoS 攻击,让攻击有代价:如果执行失败的交易不消耗 gas,攻击者就可以大量发送“必定失败”的交易,使得正常交易无法执行。
- 计算出三棵树的根哈希
stateRoot、txRoot、receiptsRoot,连同父块哈希、时间戳、难度、gasLimit、gasUsed 等字段一起组成区块头(还缺nonce和mixHash)。 - 在这个固定的区块头上运行 Ethash 挖矿,遍历不同的
nonce,直到找到一个使结果 hash 小于target的解。 - 一旦某个节点 PoW 成功,区块里的交易和状态已经完全确定,可以立即广播;其他节点收到区块后,按同样顺序执行这些交易,并重建三棵 MPT,检查根哈希是否一致,就能验证区块是否正确
与比特币 PoW 的差异
- 从算法结构上看:比特币是“两轮 SHA-256 + 简单拼接”,Ethash 是“Keccak + DAG + FNV + 多轮随机内存访问”;
- 从硬件要求上看:比特币主要拼算力,Ethash 还需要看内存带宽和容量;
- 从数据结构上看:比特币只对本区块交易做一棵 Merkle 树,Ethash 挖的是“已经绑定了三棵 MPT 根哈希的区块头”;
- 从轻节点友好性上看:两者都可以做 SPV,Ethash 多了一层“cache + 按需生成 DAG 元素”的设计,方便轻节点验证挖矿结果。
难度调整
以太坊希望保持大约 12–15 秒的出块时间,从而比比特币有更快的确认速度、更好的交互体验。
以太坊的难度是区块级别动态调整的,每个新区块的 difficulty 都是根据父块的信息计算出来的,而不是矿工随便填的。
忽略难度炸弹时,可以把难度调整公式粗略理解为:
其中:
是父子块之间的时间间隔(秒);
与父区块的 uncle 数有关,下面会讲什么是 uncle 区块,如果父区块中包括了 uncle,则 y 为 2,否则 y 为 1
直观理解:
- 如果出块间隔 秒,那么 (不含叔块),adjFactor 为正,难度会略微上调;
- 如果 秒,adjFactor 为负,难度会下调,出块会变得稍微容易一点;
- 下调幅度有一个下限 ,也就是“每个区块最多只能把难度下调约 倍”,避免因某次时间戳异常导致难度瞬间暴跌。
和比特币的对比:
- 比特币每 2016 个区块才整体调整一次难度,反馈周期在小时级甚至天级;
- 以太坊则是每个区块都可以微调难度,对算力变化响应更快,更适合十几秒的高频出块节奏。
其他节点如何知道“新难度是多少”?
- 新区块的
difficulty字段写在区块头里,但它不是“矿工说多少就多少”; - 任意节点在验证新区块时,会拿到父块头和新区块的时间戳,自己在本地套同样的公式算出
expectedDifficulty; - 如果新区块头里的
difficulty和本地算出来的不一致,这个区块就会被视为非法、直接丢弃。
因此,难度调整逻辑本身就是共识的一部分,矿工如果不按规则来,就挖不出能被别人接受的区块。
难度炸弹
在常规难度调整之外,以太坊还引入了一个特殊的“难度炸弹”(Difficulty Bomb,也叫 Ice Age):
- 在难度计算公式中,除了上面的“按出块时间微调”的那一项之外,还有一项随区块高度指数增长的“额外难度”;
- 当区块高度足够高时,这个额外项会快速增大,使得总难度剧烈上升,出块时间越来越长,最终网络几乎停滞。
可以把炸弹项粗略写成:
其中 取决于区块高度:
bombDelay是一个“偏移量”,用来控制炸弹真正开始生效的高度;- 每经过 100000 个区块, 增加 1,炸弹项就大约翻一倍。
以太坊社区为了延缓难度炸弹生效,曾经把实际用于计算的区块号往后调过三百万个,这样在计算 时,就相当于“假装链还没走那么远”,炸弹项暂时回到 0 或者很小的值。随着时间推移, 继续增长,炸弹又会慢慢变强,如果社区再次想继续使用 PoW,就需要再做一次升级推迟它。
从治理角度看:
- 没有难度炸弹,社区在“到底要不要切 PoS”这样的议题上可能会无限拖延;
- 有了炸弹,如果不升级,出块时间会越来越长、用户体验越来越差,大家就有动力转成PoS;
- 也是防止转成 PoS 之后,还有矿工继续要用旧有 PoW 的机制挖矿
GHOST 共识
由于以太坊出块很快,区块在网络中的传播需要时间,多个矿工几乎同时挖出新区块是常态,这会自然产生临时分叉。
如果像比特币那样只采用简单的“最长链规则”,会有两个问题:
1.个体矿工更容易吃亏:
- 当一个个人矿工和一个大型矿池几乎同时挖出区块时,由于矿池拥有更多算力,它更容易在自己的那条链上快速接上下一块,使这条链成为最长链。
- 个人矿工挖出的那条分支会更容易变成孤块,工作量白费。 2.算力中心化偏向(centralization bias):
- 长期来看,大矿池的收益更稳定,小矿工不划算,大家会越来越倾向加入大矿池,导致算力集中。

为缓解这个问题,以太坊引入了GHOST 共识协议,让这些废弃的区块也能够获得一些安慰的奖励
不只看哪条链“最长”,而是看哪条链背后承载的“有效工作量”最多,即哪条链的子树(包含主链和旁枝)的总工作量更大。
- 给输在分叉竞争中的区块一定奖励(叔块奖励),把它们的工作量部分计入主链的安全性;
- 对包含叔块的主链区块也给一点额外奖励,鼓励矿工尽快把看到的叔块“收编”进主链。
叔块规则
- 当两个区块几乎同时接在同一个父块后,形成分叉,最终只有一条分支会成为主链,另一条分支上的区块就变成了“叔块候选”。
- 新的主链区块可以在自己的区块头中引用这些“叔块候选”,每个新区块最多可以包含 2 个叔块。
- 只有被主链区块引用的叔块,才会获得奖励;没被引用的就和普通孤块一样,只能算白挖了。
奖励方面:
-
R为当时的基础出块奖励 -
k = B.number − U.number(叔块与包含它的主链区块之间的高度差) -
叔块本身可以获得接近完整出块奖励的大部分(约 7/8),并且跨度越远奖励越少,只有高度差不超过 6(k=1..6)的叔块才可被包含并获奖。
-
奖励公式为:
-
引用叔块的新区块也能获得少量额外奖励,鼓励矿工积极把叔块包含进来,每包含 1 个叔块,可额外获得
R / 32 -
每个区块最多可包含 2 个叔块,一个叔块只能被包含一次
-
只有分叉之后的第一个区块才能获得uncle reward,后面的区块都没有奖励。
- 如果不这样设计,而是给侧链上的每个区块都发奖励的话,那么分叉攻击的代价就会很低
- 因为分叉攻击不成功,它们整条侧链的节点也能都够得到一些补偿,还不如去冒险发动攻击,成功了的话反而能够得到一大笔钱。
这种设计的效果是:
- 对个体矿工更友好:哪怕最终输在了分叉竞争中,只要自己的区块被包含为叔块,也能拿到大部分奖励;
- 减轻中心化偏向:大矿池不再在分叉竞争中拥有过于压倒性的优势,小矿工的“白挖风险”被降低。
叔块上链过程
假设主链高度这样增长(从左到右是时间):
时间 → 主链: B0 ─ B1 ─ B2 ─ B3 ─ B4 ─ B5 ─ B6 ─ B7 ─ B8
假设在 B2 之后:
- 矿工 A 挖出了
B3 - 几乎同时,矿工 C 也挖出了一个区块
U3
B2 │ ┌─────┴─────┐ B3 U3 ← 合法区块,但没赢主链
此时:
B3成为主链U3成为叔块候选(ommer candidate) -U3 已经存在了,但还没拿到任何奖励
后续区块继续正常出块,主链继续往前:
主链: B3 ─ B4 ─ B5 ─ B6
U3 一直“躺在网络里”,每个新矿工都有资格把 U3 引用进自己的区块
假设在挖 B6 时,矿工 D 做了两件事:
- 构造新区块
B6 - 在B6 的区块头里填上:
ommers = [U3]
于是关系变成:
主链: B3 ─ B4 ─ B5 ─ B6 ↘ U3
此时高度差 ,发生三件事:
1.U3 被正式承认为叔块 2.U3 的矿工立刻获得 (8-3)R/8 的叔块奖励 3.B6 的矿工获得 R/32 的 inclusion reward
PoW 到 PoS 过渡
为了实现向 PoS 的平滑迁移,以太坊社区采取了"分阶段、双链并行"的策略:
研发阶段(2014-2020)
- 早在 2014 年,Vitalik Buterin 等人就开始研究 PoS 共识,提出了 Casper 系列协议;
- 2017-2018 年,社区逐步将 Casper 设计细化为两部分: -Casper FFG(Friendly Finality Gadget):提供终局性保证,确保已确认的区块不可逆; -LMD-GHOST:提供分叉选择规则,决定哪条链是当前的主链。
- 2019 年底,以太坊 2.0(后改名为"共识层升级")的规范逐步冻结,Beacon 链的设计基本成型。
Phase 0:Beacon 链启动(2020 年 12 月)
- 2020 年 12 月 1 日,Beacon 链正式启动,标志着以太坊 PoS 的实质性开始;
- 此时 Beacon 链是一条完全独立的链,与原 PoW 主链并行运行,有自己的创世状态和区块;
- Beacon 链只负责:
- 管理验证者的注册、激活、退出;
- 运行 PoS 共识(LMD-GHOST + Casper FFG);
- 生成随机数(RANDAO)并为未来的 slot 分配 proposer 和委员会; -不执行任何用户交易,不运行 EVM,不维护账户状态。
如何成为 Beacon 链验证者
在 PoW 主链上,有一个特殊的智能合约叫Deposit Contract:
- 任何人都可以调用这个合约,向其中存入至少 32 ETH;
- 存款时需要提供:
- 一个 BLS 公钥(用于 Beacon 链上的签名和投票);
- 提款凭证(withdrawal credentials,用于未来取回质押);
- 对这些信息的 BLS 签名,证明私钥持有者确实同意质押。
- 一旦存款交易在 PoW 链上被确认,Beacon 链会监听这个合约的事件,把新的验证者登记到自己的候选队列中;
- 候选验证者按先后顺序排队,逐步被激活为"活跃验证者",开始参与出块和投票。
这种设计的巧妙之处在于:
- PoW 主链负责"锁定 ETH"这个经济行为,利用已有的链上状态和共识;
- Beacon 链负责"用这些质押来驱动新的 PoS 共识",两条链各司其职,互不干扰。
双链并行运行
在长达近两年的时间里,以太坊网络处于"双链共存"的状态:
PoW 主链(执行层)
- 继续使用 Ethash 挖矿,矿工提出新区块;
- 所有用户交易、智能合约执行、状态更新都在这条链上进行;
- 区块头中依然包含
stateRoot、txRoot、receiptsRoot、nonce、mixHash等字段; - 难度炸弹被多次推迟,以便给 Beacon 链的成熟争取时间。
Beacon 链(共识层)
- 按照 PoS 规则每 12 秒左右产生一个 slot;
- 验证者按 RANDAO 随机性被分配为 proposer 和委员会成员;
- 每个 slot 的 proposer 提出一个 Beacon 区块,包含:
- 对上一个 slot 的投票(attestations);
- 新的验证者存款、退出、slashing 等共识消息;
- RANDAO reveal(用于生成随机数); -不包含任何用户交易。
- Beacon 链的区块和状态完全独立于 PoW 主链,两者唯一的联系就是 Deposit Contract。
这种"分而治之"的设计让社区可以:
- 在真实环境中测试和完善 PoS 共识,积累验证者运营经验;
- 观察 Beacon 链的稳定性、终局性、抗攻击能力;
- 为最终的合并做好充分准备,同时不影响主网用户的日常使用。
The Merge
经过近两年的并行运行和多次测试网演练,以太坊在 2022 年 9 月 15 日完成了历史性的The Merge(合并)。
技术上如何合并
合并的核心是让 PoW 主链"停止自己的共识,接受 Beacon 链的共识":
1.Terminal Total Difficulty(TTD)
- 以太坊协议预先设定了一个"终端总难度"值,大约对应 2022 年 9 月中旬;
- 当 PoW 主链的累积总难度首次达到或超过这个 TTD 时,PoW 共识立即停止:
- 矿工不再继续挖矿;
- Ethash 算法、nonce、mixHash 等字段被废弃;
- 难度炸弹不再需要,因为链已经彻底切换到 PoS。
2.执行层与共识层的"插拔式"对接
- 在合并前,客户端软件已经被重构为两部分: -执行客户端(Execution Client):负责 EVM 执行、状态管理、交易池,对应原来的 PoW 客户端(如 Geth、Nethermind); -共识客户端(Consensus Client):负责 PoS 共识、验证者管理、分叉选择,对应 Beacon 链客户端(如 Prysm、Lighthouse)。
- 两个客户端通过一个标准的 JSON-RPC 接口(Engine API)通信:
- 共识客户端告诉执行客户端"现在应该基于哪个父区块构造新区块";
- 执行客户端执行交易、计算状态转移,把结果返回给共识客户端;
- 共识客户端把这个结果包装成 Beacon 区块,广播并收集投票。
3.区块结构的变化
- 合并后,以太坊区块分为两部分:
-Beacon 区块(Consensus Layer):包含 slot、epoch、proposer 索引、attestations、RANDAO、Casper FFG 投票等;
-执行负载(Execution Payload):包含原 PoW 区块头的大部分字段(
stateRoot、txRoot、receiptsRoot、gasUsed等)和交易列表,但不再有nonce和mixHash。 - 每个 Beacon 区块都嵌入一个执行负载,代表"这个 slot 里执行层发生的状态变化"。
对用户的影响
从最终用户角度看,合并前后几乎感觉不到变化:
- 所有账户余额、合约代码、合约存储、历史交易记录完全保留;
- 发送交易、调用合约、部署合约的方式和 API 完全不变;
- Gas 费用、交易确认时间在短期内也基本保持不变(出块时间仍然约 12 秒)。
真正改变的是底层:
-谁来提出新区块:从"算力最强的矿工"变为"被 RANDAO 随机抽中的验证者"; -如何达成共识:从"PoW 最长链"变为"PoS 的 LMD-GHOST + Casper FFG"; -安全性来源:从"算力很贵"变为"质押会被罚没"; -能耗:The Merge 使以太坊能耗下降了约99.95%,从 20+ TWh/年降至几乎可以忽略不计。
小结
回顾整个过渡过程,可以看出以太坊社区的几个关键考量:
-稳妥优先:通过 Beacon 链独立运行近两年,充分测试 PoS 共识的稳定性,避免直接在主网上做"大爆炸式"升级; -向后兼容:执行层(原 PoW 链)的状态、交易格式、EVM 语义完全不变,只是共识层被替换; -社区共识:难度炸弹提供了"倒计时压力",让社区有明确的迁移动力; -分层架构:合并后的"执行层 + 共识层"分离设计,为后续的扩容和客户端多样性提供了更清晰的模块边界。
PoS 时代
Slot 和 Epoch
为了组织 PoS 共识,Beacon 链把时间划分为精确的时间单位:
Slot(时隙)
- 每个 slot 约12 秒,是以太坊 PoS 的基本时间单位;
- 理论上每个 slot 产生一个区块,但如果 proposer 离线或恶意不出块,这个 slot 可以是“空的”;
- Slot 编号从创世开始递增:slot 0, slot 1, slot 2, ...
Epoch(时期)
- 每32 个连续的 slot组成一个 epoch;
- 1 个 epoch 约6.4 分钟(32 × 12 秒);
- Epoch 是 Casper FFG 处理终局性的基本单位,也是计算奖励和惩罚的周期。
时间线示例
Epoch N: Slot 0 [12s] proposer_A 出块 | 委员会_1 投票 Slot 1 [12s] proposer_B 出块 | 委员会_2 投票 Slot 2 [12s] proposer_C 出块 | 委员会_3 投票 ... Slot 31 [12s] proposer_Z 出块 | 委员会_32 投票 Epoch N+1: Slot 32 [12s] ... ...
在每个 epoch 开始时:
- 协议会为该 epoch 的每个 slot 预先分配好 proposer(从所有活跃验证者中随机抽取);
- 把所有活跃验证者均匀分配到 32 个 slot 对应的 32 个委员会(每个 slot 一个委员会);
- 这些分配基于 RANDAO 随机性,后面会详细讲解。
验证者与质押
在 PoS 时代,以太坊不再依赖算力挖矿,而是依赖验证者(validator)和质押的 ETH。
成为验证者
任何人都可以成为验证者,基本步骤如下:
1.准备质押
- 至少需要32 ETH作为一个验证者单元的质押量;
- 如果有更多 ETH,可以创建多个验证者(64 ETH = 2 个验证者,96 ETH = 3 个验证者,以此类推);
- 也可以通过质押池(Lido、Rocket Pool 等)参与,但底层仍然是以 32 ETH 为单位的验证者。
2.生成密钥对
- 需要生成两对密钥: -验证密钥(Validator Key):用于签名区块和 attestations,必须始终在线; -提款密钥(Withdrawal Key):用于未来取回质押,可以离线冷储储。
- 使用BLS 签名方案,支持签名聚合,下面有解释。
3.存入 Deposit Contract
- 在执行层调用 Deposit Contract,向其中转入 32 ETH;
- 提交验证公钥、提款凭证和签名;
- 这笔交易一旦被执行层确认,Beacon 链会监听到该事件。
4.等待激活
- 验证者首先进入“待激活队列”(activation queue);
- 为了网络稳定,每个 epoch 只能激活有限数量的验证者(大约是当前总验证者数的 1/65536,每个 epoch 最多能激活 4 个);
- 激活后,验证者状态变为“活跃”,开始参与共识。
5.持续运行
- 验证者需要运行一个节点(包括执行客户端 + 共识客户端);
- 在每个 epoch 中,验证者会被分配到不同的 slot 和委员会,负责投票或出块;
- 只要按要求完成任务,就能获得奖励;如果离线或作恶,就会被惩罚。
6.退出和提款
- 验证者可以主动发起退出,进入“退出队列”;
- 退出后,验证者不再参与共识,但质押还需要等待一段时间(约 27 小时)才能提取;
- 提款功能在 The Merge 之后的 Shanghai/Capella 升级(2023 年 4 月)中才正式启用。
验证者生命周期示例
以一个具体的验证者为例:
Slot 1000: Alice 向 Deposit Contract 存入 32 ETH ↓ Slot 1050: Beacon 链检测到存款,Alice 的验证者进入“待激活队列” ↓ Slot 1500: Alice 的验证者被激活,状态 = “活跃” ↓ Slot 1500-50000: Alice 持续执行以下任务: - 每个 epoch 至少投票一次(attestation) - 偶尔被选为 proposer,提出新区块 - 偶尔被选为聚合者(aggregator),聚合委员会签名 ↓ Slot 50000: Alice 决定退出,发送 Voluntary Exit 消息 ↓ Slot 50200: Alice 的验证者被标记为“已退出”,不再参与共识 ↓ Slot 51000: 等待期结束,Alice 可以提取 32 ETH + 奖励 - 惩罚
随机性:RANDAO
要做到“随机选择 proposer 和委员会”,系统需要高质量的随机数。以太坊 PoS 使用的是基于RANDAO的随机性:
RANDAO 原理
RANDAO 的基本思想是“多方贡献随机值,混合后难以预测”:
1.每个 proposer 提交 reveal
- 当验证者被选为 proposer 时,必须在自己的区块中包含一个RANDAO reveal;
- 这个 reveal 是用验证者私钥对 epoch 编号的 BLS 签名:
2.混合所有 reveals
- 在一个 epoch 内,所有 proposers 的 reveals 会被收集起来;
- 协议把这些 reveals 通过 XOR(按位异或)混合,得到一个“混合随机数”:
3.生成 epoch 的随机种子
- 每个 epoch 的
randao_mix会被用来为未来的几个 epoch 生成随机种子; - 具体来说,epoch N 的
randao_mix会影响 epoch N+2 和之后的 proposer/委员会分配; - 这样的延迟设计是为了防止 proposer 通过“不出块”来操纵随机数。
为什么这样设计
- 单个验证者无法预测最终的
randao_mix,因为它依赖于所有 proposers 的 reveals; - 即使某个验证者想“不出块来影响随机数”,也会损失出块奖励,并且只能影响一个 bit 位,对整体随机性影响很小;
- 只要绝大多数验证者诚实,单个验证者就很难预判“自己会在什么时候被选中、会跟谁分在一个委员会”,也就难以提前策划针对性的政击。
具体分配流程
Epoch N-2: 收集所有 proposer 的 RANDAO reveals ↓ 混合成 randao_mix_N-2 ↓ Epoch N: 使用 randao_mix_N-2 作为种子 ↓ 为 epoch N 的每个 slot 分配 proposer: - 用 hash(randao_mix, slot, "proposer") mod validator_count - 得到验证者索引,即为该 slot 的 proposer ↓ 把所有活跃验证者打乱并分配到 32 个委员会: - 用 hash(randao_mix, epoch, committee_index) 作为 shuffle 种子 - 对验证者列表进行 Fisher-Yates shuffle - 平均分成 32 份,每份对应一个 slot 的委员会
BLS 签名与聚合
PoS 下,每个 epoch、每个 slot 的投票数量都非常多。以太坊主网有超过90 万个活跃验证者(2024 年数据),如果所有签名都单独发送和存储,带宽和存储会被打爆。为此,以太坊采用了BLS 签名与聚合技术:
BLS 签名的特性
- BLS(Boneh-Lynn-Shacham) 是一种基于椭圆曲线配对的签名算法;
- 最大的特点是签名可聚合(aggregatable):
- 如果多个人对同一条消息签名,这些签名可以“加起来”形成一个聚合签名;
- 验证时,只需要一次配对运算,就能同时验证整个聚合签名的有效性;
- 公钥也可以聚合,聚合公钥对应聚合签名。
Attestation 的签名对象
在讲解聚合流程之前,先要明确验证者到底在签什么。
Attestation Data 结构
每个验证者在每个 epoch 中至少需要发出一次 attestation,包含以下数据:
AttestationData = { # 时间信息 "slot": 12345, # 该 attestation 所属的 slot "index": 5, # 委员会编号(0-31) # LMD-GHOST 分叉选择用 "beacon_block_root": "0xabc...", # 验证者认为的当前链头区块的根哈希 # Casper FFG 终局性用 "source": { "epoch": 100, "root": "0x123..." # 上一个已证明检查点的根哈希 }, "target": { "epoch": 101, "root": "0x456..." # 当前 epoch 的 checkpoint 的根哈希 } }
验证者签名的是这整个 AttestationData 对象:
- 首先对
AttestationData进行 SSZ 序列化(Simple Serialize,以太坊的标准序列化格式); - 再对序列化结果计算 hash tree root,得到一个 32 字节的哈希值;
- 最后用 BLS 私钥对这个哈希值签名:
为什么要签这些字段
beacon_block_root:表明验证者认为哪个区块是当前的链头,用于 LMD-GHOST 分叉选择;source和target:表明验证者认为哪条链是合法的,用于 Casper FFG 终局性;slot和index:证明这是哪个 slot 的哪个委员会的投票,防止重放攻击。
分叉选择:LMD-GHOST
PoS 下同样可能出现分叉:
- proposer 未能在 slot 内及时广播区块,导致部分节点暂时继续在旧链头上构建,从而产生短暂分叉
- 同一个区块在网络中传播不均,导致不同节点在同一时刻看到不同链头,形成视图不一致的分叉
- 节点同步或验证速度差异使部分节点短时间内滞后于最新链头,从而跟随不同分支
- 在区块刚被提议而投票尚未充分传播时,不同节点对权重优势的判断不同,可能引发极短暂分叉
- 等等其他一系列可能出现分叉的情况
以太坊 PoS 采用两层机制来处理分叉并给出终局性保证:
-LMD-GHOST 分叉选择规则:决定当前的“主链头部”,哪个区块是 head; -Casper FFG 终局性机制:给出“最终确认”保证,确保已确认的区块不可逆。
先来看LMD-GHOST(Latest Message Driven GHOST),它是 PoW 时代 GHOST 协议在 PoS 下的演化版本。
基本思想
- 每个验证者会周期性地对它认为的“最佳链头”投票(发出 attestation);
- 每个投票带有权重,权重等于该验证者质押的 ETH 数量(每个验证者都是 32 ETH,所以权重相等);
- 对于每个验证者,只看它最近一次投票(latest message),防止重复计数;
- 从创世区块开始,沿着子树“累计投票权重”最大的子节点一直往下走,直到再往下没有子节点为止,这个叶子节点就是当前头区块(head)。
具体算法
假设当前区块树如下:
A (justified checkpoint) │ ┌────┼────┐ B C │ │ ┌┼┐ ┌┼┐ D E F G
假设有 100 个验证者,他们的最新投票分布如下:
- 40 个验证者投给 D
- 20 个验证者投给 E
- 30 个验证者投给 F
- 10 个验证者投给 G
LMD-GHOST 算法执行步骤:
1.从 justified checkpoint A 开始
- A 有两个子节点:B 和 C
2.计算每个子节点的总权重
- B 的子树包括 D 和 E,总权重 = 40 + 20 =60
- C 的子树包括 F 和 G,总权重 = 30 + 10 =40
3.选择权重最大的分支
- B 的权重(60)> C 的权重(40),选择 B
4.继续在 B 的子节点中选择
- D 的权重 = 40
- E 的权重 = 20
- 选择 D
5.D 没有子节点,结束
- 当前 head =D
Attestation 的结构
每个 attestation 包含:
Attestation = { "slot": 12345, # 哪个 slot 发出的投票 "committee_index": 5, # 哪个委员会 "beacon_block_root": 0xabc..., # 投给哪个 beacon 区块(LMD-GHOST 用) "source": { # Casper FFG 用:上一个 justified checkpoint "epoch": 100, "root": 0x123... }, "target": { # Casper FFG 用:当前 epoch 的 checkpoint "epoch": 101, "root": 0x456... }, "signature": ... # BLS 签名 }
beacon_block_root:这是 LMD-GHOST 用来计算分叉选择的字段,指向验证者认为的当前链头;source和target:这是 Casper FFG 用来确认终局性的字段,后面会详细讲解。
效果
可以把它想象成:
- 整棵区块树上,每条边都背着“支持这条分支的总质押”;
- 共识规则总是沿着“权重最大”的路径向下走;
- 只要大多数质押诚实并且按时投票,所有节点最终都会认为同一个区块是 head。
终局性:Casper FFG
仅靠分叉选择规则,链的头部仍然可能回滚。为了给出更强的“最终确认”保证,以太坊引入了Casper FFG(Friendly Finality Gadget):
基本概念
- 每个 epoch 的第一个 slot 的区块被称为checkpoint 区块;
- 验证者在每个 attestation 中,除了投票给 LMD-GHOST 的 head,还要同时投票给两个 checkpoint: -source checkpoint:上一个已被 justified 的 checkpoint; -target checkpoint:当前 epoch 的 checkpoint。
- 这种投票可以理解为“我认为从 source 到 target 的这条链是有效的”。
Justified 和 Finalized
1.Justified(被证明)
- 当某个 checkpoint 获得 ≥ 2/3 有效质押的投票时,它会被标记为justified;
- 这意味着绝大多数验证者认为这个 checkpoint 是合法的。
2.Finalized(终局)
- 如果一个 justified checkpoint 的直接后继 checkpoint也被 justified,则前者升级为finalized;
- 用公式表示:如果 checkpoint B 在 epoch N,checkpoint C 在 epoch N+1,并且:
- B 是 justified
- C 也是 justified
- C 的 source 指向 B
- 那么 B 被 finalized。
具体例子
Epoch 98: Checkpoint A (finalized) ↓ Epoch 99: Checkpoint B (justified, source=A) ↓ Epoch 100: Checkpoint C (justified, source=B) ← B 现在被 finalized ↓ Epoch 101: Checkpoint D (正在收集投票...)
步骤拆解:
- Epoch 99 时:
- 验证者们投票
source=A, target=B - 当 B 获得 ≥ 2/3 投票,B 变为 justified
- 验证者们投票
- Epoch 100 时:
- 验证者们投票
source=B, target=C - 当 C 获得 ≥ 2/3 投票,C 变为 justified -同时,B 从 justified 升级为 finalized
- 验证者们投票
- Epoch 101 时:
- 验证者们投票
source=C, target=D - 当 D 获得 ≥ 2/3 投票,D 变为 justified -C 从 justified 升级为 finalized
- 验证者们投票
终局性的保证
一旦某个 checkpoint 被 finalized:
- 正常情况下,链不会再回滚到它之前;
- 如果有人试图构造一条与已 finalized 区块冲突的分叉链,至少有 1/3 的质押必须在两条链上给出相互矛盾的投票,这部分质押会被 slash(罚没)。
数学保证
假设总质押量为 N:
- 要让 checkpoint A finalized,需要 ≥ 2N/3 的投票;
- 要让与 A 冲突的 checkpoint B 也 finalized,也需要 ≥ 2N/3 的投票;
- 但是 2N/3 + 2N/3 > N,意味着至少有 N/3 的验证者必须在两条链上都投票;
- 这些验证者会被检测到并被 slash,损失至少 N/3 的质押。
因此,攻击 finalized checkpoint 的经济代价非常高,这就是 PoS 终局性的安全性来源。
与比特币的对比
- PoW(比特币):安全性来自攻击者必须维持 51% 算力很长时间,“6 个确认之后很安全”是概率性的;
- PoS(以太坊):安全性来自攻击者必须冒着被罚没大额质押的风险去破坏已经 finalized 的状态,终局性是经济上的“确定性”。
验证过程
现在我们详细讲解一个 attestation 从生成到最终被包含进区块并验证的完整过程。
第一阶段:验证者本地生成并广播
假设在 slot 1000,验证者 Alice 被分配到 committee 5。
1.构造 AttestationData
- Alice 的客户端运行 LMD-GHOST,判断当前链头是区块 B,记录其
beacon_block_root; - 查询当前 justified checkpoint (已证明检查点)作为
source; - 计算当前 epoch 的 checkpoint 作为
target; - 组装成完整的
AttestationData。
2.签名
- 对
AttestationData计算 signing root; - 用自己的 BLS 私钥签名:
3.广播到网络
-
Alice 把包含以下内容的消息发布到 P2P 网络的attestation subnet:
Message = { "data": AttestationData, # 投票数据 "signature": sig_Alice, # Alice 的签名 "aggregation_bits": [1], # 一个 bit 数组,表示只有 Alice 自己 "committee_index": 5 # 委员会 5 } -
这条消息会被路由到committee 5 对应的子网(attestation subnets,一种 P2P topic)。
第二阶段:委员会内聚合
在 committee 5 中,协议预先选出了16 个 aggregator(通过 RANDAO 随机性 + modulo 计算)。假设 Bob 是其中一个 aggregator。
1.Aggregator 监听子网
- Bob 的客户端订阅 committee 5 的 attestation subnet;
- 在 slot 1000 的时间窗口内(通常是 slot 开始后的前 4 秒),Bob 会收到来自同一委员会其他成员的 attestations。
2.验证单个 attestation
- 对于收到的每个 attestation,Bob 需要验证:
AttestationData是否合法(例如 slot 是否匹配,source/target 是否正确);- 签名是否有效:
- 发送者是否真的在 committee 5 中。
3.聚合签名
- 假设 Bob 收到了 5000 个来自 committee 5 的有效 attestations(包括 Alice 的);
-关键点:
- 所有被聚合的签名,必须是对“完全相同的消息”签的,因此这 5000 个 attestations 的
AttestationData必须完全相同 - 如果收到的
AttestationData有不一致的,那会按 AttestationData 分组
- 所有被聚合的签名,必须是对“完全相同的消息”签的,因此这 5000 个 attestations 的
- Bob 聚合这些签名:
- 同时构造一个
aggregation_bits位图:- 这是一个 bit 数组,长度等于 committee 5 的总人数(假设 28000 人);
- 第
i个 bit 设为 1 表示第i个验证者参与了这个聚合,设为 0 表示没有参与; - 例如:
[1,1,0,1,0,0,1,...]表示第 0,1,3,6,... 个验证者参与了。
4.广播聚合后的 attestation
-
Bob 把聚合后的结果发布到aggregated attestation subnet(另一个 P2P topic):
AggregatedAttestation = { "data": AttestationData, # 相同的投票数据 "signature": agg_sig, # 聚合签名(96 字节) "aggregation_bits": [1,1,0,1,...], # bit 数组(~3.5 KB) "committee_index": 5 } -
这个消息会被 proposers 监听并收集。
第三阶段:Proposer 收集并包含进区块
在 slot 1001,验证者 Charlie 被选为 proposer。
1.收集聚合后的 attestations
- Charlie 的客户端订阅所有 32 个 committee 对应的 aggregated attestation subnets;
- 从中收集尽可能多的聚合后的 attestations(通常来自多个 slot,不只是 slot 1000);
- 每个 slot 有 32 个 committee,每个 committee 可能有多个 aggregator,所以 Charlie 可能收到数百个聚合后的 attestations。
2.去重和选择
- 对于同一个 committee、同一个 slot 的多个聚合,Charlie 会选择包含验证者最多的那个(通过
aggregation_bits中 1 的数量判断); - 如果两个聚合有不同的验证者集合,Charlie 甚至可以在本地再次聚合它们(只要
AttestationData相同)。
3.包含进区块
- Charlie 构造 slot 1001 的 Beacon 区块,其中包含一个
attestations字段; - 这个字段是一个数组,每个元素是一个
AggregatedAttestation; - 每个区块最多能包含约 128 个聚合后的 attestations(协议限制)。
第四阶段:其他节点验证区块
其他验证者(David)收到 Charlie 提议的区块后,需要验证其中的所有 attestations。
1.对于每个 AggregatedAttestation
a.验证 AttestationData 的合法性
- 检查 `slot` 是否在允许的范围内(通常是当前 slot 前的 32 个 slot); - 检查 `source` 和 `target` 是否符合 Casper FFG 的规则; - 检查 `beacon_block_root` 指向的区块是否存在。
b.查询参与者列表
- 根据 `committee_index` 和 `slot`,查询该 slot 该 committee 的完整验证者列表(这个信息是由 RANDAO 确定性计算的,所有节点都能本地计算出相同结果); - 例如,committee 5 在 slot 1000 的成员是 `[validator_123, validator_456, ..., validator_28000]`。
c.根据 aggregation_bits 提取参与者公钥
- 遍历 `aggregation_bits`,如果第 `i` 位是 1,就把第 `i` 个验证者的公钥加入列表; - 假设提取出了 5000 个公钥:`[pubkey_Alice, pubkey_Bob, ..., pubkey_5000]`。
d.聚合公钥
- 使用 BLS 公钥聚合算法(本质上是椭圆曲线上的点加法):
- 这个计算非常快,因为只是点加法,不涉及配对。
e.验证聚合签名
- 计算 signing root:
- 执行 BLS 验证:
- 这个验证涉及一次椭圆曲线配对运算,是最贵的部分,但一次就能验证 5000 个签名。
f.检查是否有重复投票
- 确保同一个验证者没有在同一个 slot 对多个不同的 `AttestationData` 签名; - 记录每个验证者在每个 slot 的投票,检测重复。
2.所有 attestations 通过验证后
- 区块被认为有效;
- David 会接受这个区块,并将其中的投票信息用于更新 LMD-GHOST 和 Casper FFG 的状态。
整个流程的效率分析
假设一个 slot 有 32 个 committee,每个 committee 有 28,000 个验证者,总共 896,000 个验证者。
没有聚合的情况:
- 网络传输:896,000 个签名 × 96 字节 =86 MB
- 验证成本:896,000 次 BLS 验证(每次约 1-2ms) =数十分钟
- 区块大小:86 MB + 其他数据
有聚合的情况(16 aggregators/committee):
- 网络传输第一阶段(subnet):896,000 个单独 attestation,但只在小范围的 subnet 内传播
- 网络传输第二阶段(aggregated):32 committees × 16 aggregators = 512 个聚合,每个约 3.6 KB =1.8 MB
- 区块大小:最多 128 个聚合 × 3.6 KB =约 460 KB
- 验证成本:128 次 BLS 验证 =数百毫秒
压缩比:
- 网络传输:从 86 MB 降至 1.8 MB(约50倍)
- 区块大小:从 86 MB 降至 460 KB(约190倍)
- 验证时间:从数十分钟降至数百毫秒(约1000倍)
这就是为什么 BLS 签名聚合对于以太坊 PoS 至关重要——它使得上百万验证者的系统在工程上变得可行。
奖励与惩罚
在 PoS 中,安全性不再来自“算力很贵、难以伪造”,而是来自“质押很贵,被 slash 会很疼”。共识协议通过奖励和惩罚把“诚实行为”变成参与者的最优选择。
奖励机制
验证者的收益主要来自几部分:
1. 基础奖励(Base Reward)
- 每个活跃验证者都有一个“有效质押余额”(最多 32 ETH);
- 协议会根据全网总质押量计算一个基础利率:
- 全网质押越多,单个验证者的基础奖励越低(平方根关系),这样设计是为了平衡安全性和成本。
具体示例:
- 假设全网有 30,000,000 ETH 质押(大约 937,500 个验证者);
- Base Reward Factor = 64 (2024 年的协议参数);
- 单个验证者的每 epoch 基础奖励 ≈ 0.00004 ETH;
- 年化收益率(APR) ≈ 3.5-4.5%(不含 MEV 和小费)。
2. 投票奖励(Attestation Rewards)
验证者每个 epoch 至少需要提交一次 attestation,奖励由三部分组成:
-Source 投票奖励:正确投票给 source checkpoint; -Target 投票奖励:正确投票给 target checkpoint; -Head 投票奖励:正确投票给 LMD-GHOST 的 head 区块。
每部分的奖励计算公式:
直观理解:
- 如果 100% 的验证者都正确投票,你能得到完整的奖励;
- 如果只有 80% 的验证者投票,你只能得到 80% 的奖励;
- 这鼓励验证者尽快投票,因为别人不投会减少你的收益。
3. 提议奖励(Proposer Rewards)
当验证者被选为 proposer 时,可以获得额外奖励:
-包含 attestations 的奖励:
- 每包含一个有效的 attestation,proposer 能得到该 attestation 奖励的 1/8;
- 如果一个区块包含 128 个 attestations,proposer 能得到 128 × 1/8 = 16 份基础奖励。
-Sync Committee 奖励(后期升级增加):
- Sync committee 是一小组验证者(约 512 个),负责给轻客户端提供快速同步;
- Proposer 包含 sync committee 签名也能获得少量奖励。
-交易费用(Priority Fees):
- 用户交易的小费(基础费用被销毁,只有小费给 proposer);
- 在网络拥堵时,这部分可以很可观。
-MEV 收益:
- 通过 MEV-Boost 等机制,proposer 可以把区块构造权卖给专业的 builder,获得 MEV 提取值的大部分;
- 这部分收益可能是基础奖励的数倍甚至数十倍。
4. Inclusion Delay Penalty
- 如果你的 attestation 被延迟包含进区块:
- 在同一个 slot 包含:奖励 = Base Reward
- 延迟 1 个 slot:奖励 = 7/8 × Base Reward
- 延迟 2 个 slot:奖励 = 6/8 × Base Reward
- 以此类推,最多延迟 32 个 slot(1 个 epoch)
- 这鼓励验证者尽快发出 attestation,也鼓励 proposer 尽快包含 attestations。
惩罚机制
惩罚机制主要分两类:
1. 轻微惩罚:离线和低参与度
Inactivity Penalty(离线惩罚)
- 如果验证者没有提交 attestation:
- 每个 epoch 会损失一小部分质押(大约等于如果在线应该得到的奖励);
- 长期离线会逐步侵蚀质押的本金。
Inactivity Leak(不活跃泄漏)
在极端情况下(网络分区、大量验证者离线),如果链无法 finalize checkpoint 超过 4 个 epoch,会触发Inactivity Leak:
- 所有没有积极投票的验证者质押会被逐步“泄漏”掉;
- 泄漏率会随时间加快:
- 这样,即使现在有很多人离线或作壁上观,剩下那部分坚持在线投票的验证者仍然可以最终重新获得 ≥ 2/3 的有效质押,恢复 finality。
设计目的:
- 防止网络永久卡死:即使 1/3 以上的验证者离线,系统仍然能恢复;
- 但这个惩罚很重:如果离线 50 天,可能损失 50% 以上的质押。
2. 重罚:Slashing
针对明显的恶意行为,协议会直接罚没质押:
1.双重提议(Double Proposal)
- 在同一个 slot 提出两个不同的 beacon 区块,试图制造分叉攻击。 2.双重投票(Double Vote)
- 在同一个 epoch 对两个不同的 target checkpoint 投票; 3.环绕投票(Surround Vote)
- 同一个验证者在两次投票中,后一票的
source比前一票更早、而target却更晚,从而在时间上“包住”前一票。
Slashing 惩罚的三个阶段
1.初始罚没
- 一旦被检测到恶意行为,立即罚没1 ETH(或有效质押的 1/32);
- 验证者被标记为“已 slash”,不能再参与共识。
2.相关性罚没(Correlation Penalty)
- 在同一时间窗口内(18 天),如果有多个验证者被 slash,每个被 slash 的验证者还会额外罚没:
- 如果 1% 的验证者被同时 slash,每个被 slash 者额外损失 1% 的质押;
- 如果 33% 的验证者被同时 slash,每个被 slash 者额外损失 33% 的质押。 -这个设计的目的是使大规模攻击的成本极高:单个验证者出错损失小,但协同攻击损失巨大。
3.退出等待
- 被 slash 的验证者需要等待约 36 天才能提取剩余质押;
- 在这期间,质押继续受到 inactivity leak 的影响。
Slashing 总损失示例
-单个验证者出错(0.01% 被 slash):
- 初始罚没:1 ETH
- 相关性罚没:几乎为 0
- 总损失:约 1 ETH、损失率 ≈ 3%
-大规模攻击(33% 被 slash,试图破坏 finality):
- 初始罚没:1 ETH
- 相关性罚没:32 × 33% ≈ 10.5 ETH
- Inactivity leak:约 5+ ETH(36 天)
- 总损失:约 16.5 ETH,损失率 ≈ 50%+
余额更新
奖励和惩罚不是链上转账,而是“状态里直接修改余额”
每个共识节点都维护同一份 state.balances[](按验证者 index 存余额),并在每个 epoch 依据各验证者的履职情况(投票是否正确/及时、是否被包含、是否出块、是否被罚没等)先算出每人的“余额增量/减量”,然后直接修改其余额。没有一笔一笔的“转账交易”,状态更新是 O(n) 的内部计算。
之所以能形成共识,是因为这套计算规则是协议的一部分,如果有人“加错了”,它算出来的状态根会与网络多数不一致,该节点就会认为后续区块无效而被迫回到正确链上,因此错误不会变成“链上事实”
小结
从 PoW 到 PoS,以太坊在共识与挖矿(更准确地说,是区块产生和确认机制)上经历了一条清晰的演化路线:
- PoW 阶段通过 Ethash、快速难度调整、难度炸弹和叔块奖励,在保持较快出块和智能合约支持的同时,尽力降低算力中心化风险,并为未来升级留出了“倒计时开关”。
- 随着 PoS 技术成熟,以太坊通过 Beacon 链和 The Merge 完成了共识层的替换,用质押和投票取代了纯算力竞争,大幅降低能耗,并为后续的扩容路线(Rollup、分片)提供了更灵活的基础。
理解这条演化线,有助于你在学习以太坊其他部分(状态树、交易树、收据树、EVM、Gas 机制等)时,把它们放到一个统一的“分布式状态机 + 共识协议”的大框架下来看:
- 执行层决定状态如何变化;
- 共识层决定哪条状态变化历史被全网接受;
- 经济激励和惩罚机制,保证大多数参与者有动力保持诚实。
作者:加密鲸拓
版权:此文章版权归 加密鲸拓 所有,如有转载,请注明出处!