在区块链的世界当中,怎样确保电子币稳定生成是一个关键问题,“难度”在这当中起着极为重要的作用,它到底是什么情形,接下来进行深度剖析。
难度的来源与本质
“难度”这个词来源于比特币,比特币是区块链技术的先行者。挖矿实际上是在解谜题,不同电子币的谜题不一样。比如说有一种电子币,它解的空间是从0到99这100个数字,挖矿就是在这个范围内找答案。难度通过控制合格解在空间里的数量,来控制平均求解尝试的次数,从而稳定区块产生的速度。
难度的动态调整
参与挖矿的人数增多时,单位时间内尝试的次数会增加,此时难度就会增大,若人数减少,尝试次数变少,难度就会降低,这样能保证产生一个区块所需的时间保持稳定,这情形如同一个天平,会在挖矿人力数量的多少与难度之间找寻平衡,进而让电子币区块稳定地产出。
确定难度值的算法
func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
next := new(big.Int).Add(parent.Number, big1)
switch {
case config.IsMetropolis(next):
return calcDifficultyMetropolis(time, parent)
case config.IsHomestead(next):
return calcDifficultyHomestead(time, parent)
default:
return calcDifficultyFrontier(time, parent)
}
}
除了难度概念,还需要借助算法来确定合理的难度值,并且对其进行调整。以太坊有独特的方法。它的代码是开源的。官方用Go语言实现的钱包Geth能够查看源代码。关于难度的代码在特定文件中。这里存在三种计算难度规则。它们对应不同版本。
func calcDifficultyHomestead(time uint64, parent *types.Header) *big.Int {
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2.mediawiki
// algorithm:
// diff = (parent_diff +
// (parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
// ) + 2^(periodCount - 2)
bigTime := new(big.Int).SetUint64(time)
bigParentTime := new(big.Int).Set(parent.Time)
// holds intermediate values to make the algo easier to read & audit
x := new(big.Int)
y := new(big.Int)
// 1 - (block_timestamp - parent_timestamp) // 10
x.Sub(bigTime, bigParentTime)
x.Div(x, big10)
x.Sub(big1, x)
// max(1 - (block_timestamp - parent_timestamp) // 10, -99)
if x.Cmp(bigMinus99) < 0 {
x.Set(bigMinus99)
}
// (parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99))
y.Div(parent.Difficulty, params.DifficultyBoundDivisor)
x.Mul(y, x)
x.Add(parent.Difficulty, x)
// minimum difficulty can ever be (before exponential factor)
if x.Cmp(params.MinimumDifficulty) < 0 {
x.Set(params.MinimumDifficulty)
}
// for the exponential factor
periodCount := new(big.Int).Add(parent.Number, big1)
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.Add(x, y)
}
return x
}
以太坊的计算规则
现在使用的难度计算规则是在特定文件里实现的,在具体计算之前,要先介绍一下会用到的运算符,比如计算a//b时,取的是不大于a/b的最大整数,计算一个区块的难度,需要这些输入,包括上一区块产生时间、上一区块难度、当前区块产生时间等。
示例计算
以以太坊区块链公开信息作为例子,依据已知区块的各类信息来计算难度,这如同我们拿到了一系列数据拼图,要借助难度计算规则将它们拼凑成完整的难度结果,比如查看某一区块的时间戳等信息,之后依据这些信息进行具体计算。
以太坊难度下限
同时,以太坊区块难度有下限,这个下限是创世区块的难度,它为整个电子币体系的稳定奠定了基础,就如同建筑有基石一样,这个下限确保了以太坊在难度调整体系方面有一个稳定的起始点。
各位读者,你们认为以太坊采用稳定产出的方式调整难度,这种方式在未来区块链发展进程中会一直适用吗,欢迎在评论区留言参与讨论,同时也别忘记点赞和分享本文。
暂无评论
发表评论