---
# System prepended metadata

title: 以太坊基础1-POS
tags: [以太坊基础]

---

# 以太坊POS

## 什么是权益证明POS?

**概念：** 验证者们将自己的资产质押到网络中，而后参与区块的验证，参与验证可获得奖励。如果验证者在工作过程中出现了失信行为，其质押的资产可能被罚没。

**验证者的工作：** 在以太坊中，验证者们主要验证区块的有效性。当验证者收到从网络中传播过来的区块时，需要模拟执行以验证其有效性，并投出选票（接收区块还是拒绝区块）。

**成为验证者的条件：** （1）质押32个ETH到以太坊，（2）同时允许执行客户端和共识客户端。

**成为验证者的过程：** 用户首先运行两个客户端，而后将32个ETH质押到ETH2.0质押合约中（质押多了没用）。在质押完毕后，ETH2.0质押合约将发出一个deposit事件，信标链会监听deposit事件并验证质押者的质押数量。如果质押者的质押数量达到32ETH，则将质押者加入验证者待激活队列中等待（不能直接让质押者成为验证者，想象大量验证者同时挤入网络中的情况，这将导致网络负载过重）。当质押者被激活后，他就成为了验证者。

**注意：** 单个验证者质押超过32个ETH也不能提高其被选中为区块提议者的概率。可看下图：
![image](https://hackmd.io/_uploads/SkeITp7jkx.png)

截图源于：https://etherscan.io/address/0x00000000219ab540356cBB839Cbe05303d7705Fa#code

该图中的所有区块都是LIDO协议的验证者们提出的，他们的index各不相同，因此如果想要提高被选中为区块提议者的概率，只能同时运行多个验证者。

## 简化的POS流程

1. 一名用户想要发送一笔交易A，那么首先他需要构造交易A，而后对交易A进行签名，完成上述后将已签名的交易A发送给验证者。
2. 验证者B在收到交易A后，在执行客户端执行以验证交易A的有效性。如果交易A有效则将其加入本节点的Mempool中。同时，验证者B可能将交易A广播给其他的验证者，其他验证者也会验证其有效性并加入自身的Mempool中。

	实际上，验证者可以选择不广播交易A。如果用户没有将交易A发送给其他任何验证者，那么交易A就是完全私密的。对于一些攻击者来说，它们可以贿赂验证者使其不广播自己的攻击交易。如果一笔攻击交易被发送到公用的Mempool中，则可能被一些有心人抢跑（通过提高gas）。

3. 在每个时隙（slot，12秒）中，信标链会根据随机算法选出一位验证者作为区块提议者。验证者B收到自己将成为区块提议者的消息后，从自己的Mempool中选出一部分交易（这个过程是全自动的，这意味着选择交易的规则是固定的），在执行客户端执行验证后，将生成的状态改变同步到本地数据库中，并将交易其打包成**执行负载**发送给共识客户端。共识客户端根据执行客户端发送过来的**执行负载**，附加上其他的区块信息组成**信标区块**。一个区块提议者可以从Mempool里面选出一部分交易打包为区块，这意味着验证者可以随意从内存池中挑选交易。有些验证者会从内存池中找出对其最有利的一条交易顺序，而后将这些交易打包为区块上链，从中获益。

	以下是执行负载的内容：
```rust
	pub struct ExecutionPayloadV1 {
    pub parent_hash: B256,
    pub fee_recipient: Address,
    pub state_root: B256,
    pub receipts_root: B256,
    pub logs_bloom: Bloom,
    pub prev_randao: B256,
    pub block_number: u64,
    pub gas_limit: u64,
    pub gas_used: u64,
    pub timestamp: u64,
    pub extra_data: Bytes,
    pub base_fee_per_gas: U256,
    pub block_hash: B256,
    pub transactions: Vec<Bytes>,
}
```

4. 同时，在一个epoch中，会选出**验证者委员会**，区块的有效性由验证者委员会的验证者们进行验证。在这些验证者们收到新的**信标区块**后，将其传输给自身的执行客户端以验证**信标区块**的有效性，并根据自身想法选择是否接收该区块（可投选票）。如果接收则将该区块导致的状态更改同步到本地数据库中。

**注意：** 
	1. 如果同步委员会中2/3的区块证明者都接收了该区块，那么区块将打包上链，但尚未最终确认。
	2. 验证者委员会的验证者们需要定时出示证明以确保在线。

**最终确认：** 一个时段（epoch）由32个时隙（slot）组成，每个时段的**第一个区块**将作为检查点。如果某一对检查点A,B获得验证者们2/3的赞成票，那么检查点B的状态将被升级为jusitified，检查点A的状态将被升级为finalized（检查点A早于检查点B被升级为jusitified）。


## POS的概念解析

### 同步委员会

**同步委员会**是由512名验证者组成的小组。这些验证者是通过随机抽选的方式每256个epoch（约27小时）更换一次的。它的主要职责是为区块头进行签名。每当一个新的区块被提议者（block proposer）生成时，同步委员会的每个成员会验证这个区块是否有效。如果验证通过，委员会成员会对该区块头进行签名。这些签名随后被广播到整个网络中。提议者收集这些签名并将其聚合为一个最终的同步委员会签名加入block header中。

同步委员会设立的目的主要是为了轻节点，轻节点通过验证block header中的同步委员会的签名是否有效即可验证区块的有效性，从而无需接收整个区块的信息。

### 以太坊节点的组成

以太坊节点包含：执行客户端，共识客户端以及验证者客户端。

执行客户端负责交易处理、交易广播、状态更新以及支持以太坊虚拟机。然而，它不负责区块构建、区块广播以及共识相关内容。

共识客户端负责从对等节点中接收区块，并根据分叉选择算法确定区块应该放置的位置。

验证者客户端是共识客户端的附加组件，开启后，共识客户端可参与区块的证明和提议。没有验证者组件的共识客户端只会追踪链头以确保节点同步。

### Mempool

一个以太坊节点可能在一瞬间就能收到上千笔交易，然而以太坊的交易处理能力大约为10-20笔/秒。因此，每个以太坊节点都需要一个缓冲区暂存这些收到的交易，这个缓冲区就是内存池，他存储了当前以太坊节点经过验证但尚未处理的交易。

称为内存池的原因是因为这些交易都是存储在RAM中。
内存池的默认大小为300MB。

### 信标链

信标链是 2020 年推出的原始权益证明区块链的名称。 它的创立是为了在以太坊主网上运行权益证明共识逻辑之前确保该逻辑是可靠且可持续的。 因此，它与原有的工作量证明以太坊一起运行。

信标链是一个由“空”区块组成的链，但在以太坊上停止工作量证明并启动权益证明后，需要指示信标链接受来自执行客户端的交易数据，将它们打包到区块，再将区块组织到一条运行权益证明共识机制的区块链上。与此同时，原有的以太坊客户端停止挖矿、区块传播及旧的共识逻辑，并将这一切转交给信标链。 这一事件称为[合并](https://ethereum.org/zh/roadmap/merge/)。

在合并发生后，就不再有两个区块链。 相反，只有一个权益证明以太坊，现在每个节点需要两个不同的客户端。 信标链现在是共识层，一个处理区块消息和共识逻辑的共识客户端的点对点网络，而原始客户端形成执行层，负责传播消息和执行交易，以及管理以太坊的状态。 这两层可以使用引擎应用程序接口相互通信。

### 分叉

正常来说（网络好，验证者诚实），链头始终只会有一个新区块，并且所有验证者都会证明它。然而，由于网络延迟或着区块提议者提出多个区块，验证者可能会看到不同的链头（分叉了，有两个新的区块摆在验证者面前），此时验证者需要根据LMD-GHOST算法来选择支持哪一个区块。

LMD-GHOST算法规定了以太坊的分叉规则，即当区块链出现分叉时，验证者应该将区块添加到哪条链上。
具体地说：LMD-GHOST算法选择：最新消息驱动的最贪婪、最重的观测子树。
[LMD-CHOST解析](https://www.fanwb.xyz/posts/lmdghost/)。

### 最终确定性

当一个区块收到2/3区块证明者的投票时，该区块及其之前的区块都将被标记为`justified`。每个时段的第一个slot的区块被称为检查点。如果当前检查点的状态被标记为了`justified`，那么前一个检查点的状态将被标记为`finalized`。前一个检查点之前的所有区块都被最终确认。

### 安全性

**拥有1/3验证者时可以进行的攻击：** 设当前有攻击者拥有ETH2.0质押合约总数的1/3，这意味着他控制着1/3的验证者。此时攻击者可以控制他的验证者集体消失，使得POS无法最终确定区块。对于上述攻击，以太坊使用Gasper机制中的Inactive Leak机制来解决，该机制主要是说：如果超过4个时段链都没有出现检查点被最终确认，则逐渐减少未参与投票的验证者的质押数量，直到他们占有的质押数量小于1/3。

**拥有1/2验证者时可以进行的攻击：** 设当前有攻击者拥有ETH2.0质押合约总数的1/2，这意味着他控制着1/2的验证者。拥有 50% 质押以太币的恶意验证者团队理论上可以将链分成两个相同大小的分叉，然后使用他们全部 50% 质押投出与诚实验证者团体相反的投票，以此来维持两个分叉以及阻止最终确定性。 对两个分叉的怠惰惩罚将导致两条链都会最终确定。

**拥有2/3验证者时可以进行的攻击：** 设当前有攻击者拥有ETH2.0质押合约总数的2/3，这意味着他控制着2/3的验证者，这意味着他们可以任意出块。

### 孤块与叔块

在以太坊中，即使出现了分叉，这些分叉的区块不会被剪除，而是被保留下来。

例如：
在B块出现时，同时又A、C两个块被挖掘出来，但是根据分叉规则并没有选择他们作为最长链的一部分，此时A、C两个块被称为孤块。这种情况称为软分叉。
![image](https://hackmd.io/_uploads/rymwpaQo1x.png)
在B块出现后，新的块D也出现了，此时块D可以接收孤块A、C作为自己的叔块。
![image](https://hackmd.io/_uploads/SyNOpTQikl.png)
收集叔块将获得奖励：
![image](https://hackmd.io/_uploads/SklFp6XiJl.png)
对于D来说，A，B都是第一代叔块。

### 验证者

**质押合约的地址：** 0x00000000219ab540356cBB839Cbe05303d7705Fa。

如果某个节点存入32eth到以太坊质押合约中，他将成为验证者。前面提到，不是质押完毕后就直接成为验证者。下面是一个验证者的生命周期：

1. **已存入：** 此时节点已存入32eth，而后节点将进入激活队列中
2. **激活待定：** 节点被分配指定的激活时期，而后节点从激活队列中移除
3. **激活：** 在指定的激活时期来到时，节点被激活为验证者

当验证者被激活后，他有可能遇到以下情况：

1. 提出区块，证明区块
2. 损害网络（例如提出两个相同区块），验证者遭到**削减**，其部分资产被销毁，并从活跃验证者集合中剔除，且其剩余资产将被返还。

验证者还可以自行提取资产，自行注销验证者身份。

验证者的共识奖励：在共识层获得的奖励与`base_reward`有关。

![](https://cdn.nlark.com/yuque/__latex/1138cbc1caf687a687a44212496416d9.svg)

其中，`base_reward_factor` 是 64，`base_rewards_per_epoch` 是 4，`sum(active balance)` 是所有活跃验证者的质押以太币总数。`effective_balance`是指验证者的有效余额。

如果验证者进行区块提议，可以获得`base_reward`。而验证者进行区块验证或参与同步委员会，最大可获得`7/8*base_reward`。如果不参与上述行为，最多可以获得`6.75/8*base_reward`。