1️⃣ 参考
- 北京大学肖臻老师《区块链技术与应用》
- P20 - ETH挖矿难度调整篇
- P21 - ETH权益证明篇
2️⃣0️⃣ ETH挖矿难度调整
-
在ETH中最长合法链也是最难合法链(
Total Difficulty
)
-
比特币与以太坊难度的宏观比较
比特币 | 以太坊 | |
---|---|---|
调整难度 | 隔2016个区块 | 每个区块都有可能 |
平均出块时间 | 10min | 13s |
① 整体算法
一些说明
- 公式是从代码中总结出来的,看懂共识更有利于看懂后面代码实现
- 父区块:当前正在挖的区块的上一个区块
- 基础部分目的:是为了维持出块时间
- 时间炸弹目的:向POS过度
①① 自适应难度
注意是向下取整, 1 9 \frac{1}{9} 91和 8 9 \frac{8}{9} 98向下取整后为0
①② 难度炸单
不难看出这炸弹是指数的,后期难度上升会很大,这也是想迫使矿工转入POS
当指数炸弹比POS计划先来临时,也只能继续挖矿,因为只有这一个共识机制
①③ 关于ETH的去中心化补充
尽管以太坊是一个去中心化的网络,但它仍然需要通过社区驱动的治理流程来进行重大更改,例如修改难度炸弹。该流程涉及以下几个步骤:
- 提案阶段:
社区成员提出变更建议,通常以Ethereum Improvement Proposal
(EIP) 的形式发布。EIP 应包含对更改的详细描述,其理由以及潜在影响。EIP 提交给以太坊核心开发人员团队进行审查和讨论。
- 讨论阶段:
开发人员团队评估 EIP 的技术可行性和对网络的影响。社区成员对 EIP 进行公开讨论,并提供反馈。可能有多次修订 EIP,以解决疑虑并达成共识。
- 投票阶段:
一旦 EIP 准备就绪,将对其进行投票表决。投票由以太坊矿工和节点运营商进行。为了使 EIP 被接受,需要达到大多数(通常为 2/3)的投票权同意。
- 实施阶段:
如果 EIP 获得批准,则将其纳入以太坊协议的下一个版本。新版本发布后,它将自动在所有节点上激活。
② 难度调整代码
②① 自适应难度
// makeDifficultyCalculator creates a difficultyCalculator with the given bomb-delay.
// the difficulty is calculated with Byzantium rules, which differs from Homestead in
// how uncles affect the calculation
func makeDifficultyCalculator(bombDelay *big.Int) func(time uint64, parent *types.Header) *big.Int {
// Note, the calculations below looks at the parent number, which is 1 below
// the block number. Thus we remove one from the delay given
bombDelayFromParent := new(big.Int).Sub(bombDelay, big1)
return func(time uint64, parent *types.Header) *big.Int {
// 上面的计算公式
// https://github.com/ethereum/EIPs/issues/100.
// algorithm:
// diff = (parent_diff +
// (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
// ) + 2^(periodCount - 2)
bigTime := new(big.Int).SetUint64(time)
bigParentTime := new(big.Int).SetUint64(parent.Time)
// holds intermediate values to make the algo easier to read & audit
x := new(big.Int)
y := new(big.Int)
// (2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9
x.Sub(bigTime, bigParentTime)
// 时间戳相减后除以9
x.Div(x, big9)
// 判断叔父区块
if parent.UncleHash == types.EmptyUncleHash {
x.Sub(big1, x)
} else {
x.Sub(big2, x)
}
// max((2 if len(parent_uncles) else 1) - (block_timestamp - parent_timestamp) // 9, -99)
// 防止"黑天鹅",不能小于99
if x.Cmp(bigMinus99) < 0 {
x.Set(bigMinus99)
}
// parent_diff + (parent_diff / 2048 * max((2 if len(parent.uncles) else 1) - ((timestamp - parent.timestamp) // 9), -99))
// DifficultyBoundDivisor = big.NewInt(2048) 在params/protocol_params.go文件中
// 难度单位
y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
x.Mul(y, x)
x.Add(parent.Difficulty, x)
// minimum difficulty can ever be (before exponential factor)
// minimumDifficulty = 131072
// 也就是难度最小值D0
if x.Cmp(params.MinimumDifficulty) < 0 {
x.Set(params.MinimumDifficulty)
}
②② 难度炸弹(ice-age delay)
// calculate a fake block number for the ice-age delay
// Specification: https://eips.ethereum.org/EIPS/eip-1234
// 实际比较应该减1,因为是父区快与正在挖的区块差一个
fakeBlockNumber := new(big.Int)
if parent.Number.Cmp(bombDelayFromParent) >= 0 {
fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, bombDelayFromParent)
}
// for the exponential factor
periodCount := fakeBlockNumber
periodCount.Div(periodCount, expDiffPeriod)
// the exponential factor, commonly referred to as "the bomb"
// diff = diff + 2^(periodCount - 2)
if periodCount.Cmp(big1) > 0 {
y.Sub(periodCount, big2)
y.Exp(big2, y, nil)
// x指的基础部分难度
x.Add(x, y)
}
return x
}
}
// https://github.com/ethereum/go-ethereum/blob/master/consensus/ethash/consensus.go
https://eips.ethereum.org/EIPS/eip-1234
ice-age delay
回退500万的区块难度
2️⃣1️⃣ ETH权益证明
① POW的问题
- 不环保
- 比特币的消耗能源情况:Bitcoin Energy Consumption Index
- 以太坊的消耗能源情况:Ethereum Energy Consumption Index
说明
- 可以看到非常耗电
- 可以看到ETF在2022年末已经转向POS
- 为什么以太坊智能合约比单纯转账的比特币复杂却耗电少呢?
- 因为出块时间短,计算消耗少
- 想想看,矿工的收益是由什么决定的?
- 由算力决定,算力由是由投入资金决定,那直接“拼”投入资金不就行了,这就是权益证明的基本思想
- 由算力决定,算力由是由投入资金决定,那直接“拼”投入资金不就行了,这就是权益证明的基本思想
② POS权益证明
一般来说,采用权益证明的货币,会先预留一些货币给开发者,而开发者也会出售一些货币换取开发所需要的资金,在系统进入稳定状态后,每个人都安装持有货币的数量进行投票。
-
优点:
- 环保
- 维护区块链安全的资源形成闭环
- 在POW中维护其安全的资源需要通过现实中流通的货币购买矿机等设备进去区块链的,这也就导致只要有人想要攻击,只需要外部聚集足够资金就可以攻击成功(小型币种很容易被攻击,也就是在摇篮里就扼杀掉(
Infanticide
) - 在POS如果想要发动攻击也需要大量资金,但大量资金的注入同时也会太高ETF的价格,机制可以有效防御这种情况。
- 在POW中维护其安全的资源需要通过现实中流通的货币购买矿机等设备进去区块链的,这也就导致只要有人想要攻击,只需要外部聚集足够资金就可以攻击成功(小型币种很容易被攻击,也就是在摇篮里就扼杀掉(
- 说明:POW和POS是可以结合的并不互斥
- 比如有些币种根据持有币的权益进行挖矿难度调整,持有越多挖矿难度越小,为了避免马太效应,所有其中会设置冻结刚刚投入挖矿的币一段时间,也是
Proof of Deposit
- 比如有些币种根据持有币的权益进行挖矿难度调整,持有越多挖矿难度越小,为了避免马太效应,所有其中会设置冻结刚刚投入挖矿的币一段时间,也是
②① 权益证明的难题:双边下注
由于不确定哪条链会是最终合法链,所以在A和B同时进行了下注。最终A区块胜出,那么他能够获得A区块相应收益,而在B区块进行投票放入的“筹码”也会被退还,这也就导致其每次都能获得收益,也称为nothing of stake
但在POW中双边下注使算力分散可能都得不到收益
③ 以太坊拟采用的权益证明
以太坊中,准备采用的权益证明协议为Casper the Friendly Finality Gadget
(FFG),该协议在过渡阶段是要和POW结合使用的。
在比特币系统中,一个交易在其后出6个区块才认为安全。但实际上,这种安全只是概率意义上的安全,仍然可能会被拥有强大算力的用户在其前面发动分叉攻击进行回滚,也就是缺乏Finality
(不可改变性)
Casper
协议引入一个概念:Validator
(验证者)
Validator
的职责是推动系统达成共识,投票决定哪一条链成为最长合法链,投票权重取决于保证金数目。
一个用户想要成为Validator
,需要上交一笔“保证金”,这笔保证金会被系统锁定。
原始Casper协议中,规定每100个区块为一个epoch
,采用两阶段投票的方式(two-phase commit
):Prepare Message
和Commit Message
,都需要超2/3票才算通过。
在实际优化后,两次投票在实际中只需要一次即可,对于刚挖的区块是Commit Message
,对于下一个区块是Prepare Message
,且epoch
为50
- Casper协议
规定矿工挖矿会获得出块奖励,而验证者也会得到相应奖励。
当然,为了防止验证者的不良行为,规定其被发现时要受到处罚。
例如某个验证者“行政不作为”,不参与投票导致系统迟迟无法达成共识,这时扣掉部分保证金;如果某个验证者“乱作为”,给两边都进行投票,被发现后没收全部保证金。没收的保证金被销毁,从而减少系统中货币总量。
验证者存在“任期”,在任期结束后,进入“等待期”,在此期间等待其他节点检举揭发是否存在不良行为,若通过等待期,则可以取回保证金并获得一定投票奖励。
以太坊系统设想,随着世界推移,挖矿奖励逐渐减少而权益证明奖励逐渐增多,从而实现POW到POS的过渡,最终实现完全放弃挖矿(当然现在早已经实现了)
④ 对挖矿消耗大量电能的其他看法
前面的基本观点都是“挖矿消耗大量电能,而这是不好的”
但有人认为其所消耗的电能所占比值并不大,而且其对于环境的影响是有限的。挖矿提供了将电能转换为钱的手段,而电能本身难以传输和存储,一般来说,白天所发的电不足,晚上所发的电又多于实际需求。因此,挖矿为将多余的电能转换为有价值的货币提供了很好的解决手段。也就是说挖矿消耗电能可以有效消耗过剩产能,带动当地经济发展。