主页 > imtoken钱包最新版本 > 以太坊(Ethereum ETH)难度调整算法

以太坊(Ethereum ETH)难度调整算法

imtoken钱包最新版本 2023-03-06 05:47:07

在源码共识(consensus)模块中,ethash的实现,以及pow难度调整算法的实现位于consensus/ethash/consensus.go

进入方式:

// CalcDifficulty is the difficulty adjustment algorithm. It returns
// the difficulty that a new block should have when created at time
// given the parent block's time and difficulty.
func (ethash *Ethash) CalcDifficulty(chain consensus.ChainReader, time uint64, parent *types.Header) *big.Int {
    return CalcDifficulty(chain.Config(), time, parent)
}
// CalcDifficulty is the difficulty adjustment algorithm. It returns
// the difficulty that a new block should have when created at time
// given the parent block's time and difficulty.
func CalcDifficulty(config *params.ChainConfig, time uint64, parent *types.Header) *big.Int {
    next := new(big.Int).Add(parent.Number, big1)
    switch {
    case config.IsByzantium(next):
        return calcDifficultyByzantium(time, parent)
    case config.IsHomestead(next):
        return calcDifficultyHomestead(time, parent)
    default:
        return calcDifficultyFrontier(time, parent)
    }
}

可以看出,在eth的不同阶段,其调整算法不同,但算法的输入参数是一致的

time 新区块的生成时间
parent 上一个区块的参数

1. 以太坊的四个阶段

以太坊的创始人为其设定了四个发展阶段:Frontier、Homestead、Metropolis、Serenity。 阶段之间的过渡需要通过硬分叉来实现。

Frontier是2015年7月以太坊首次发布的实验阶段,当时软件还不成熟,但可以进行基本的挖矿、学习和实验。 系统运行后,将吸引更多人关注和参与开发。 以太坊作为一个应用平台,需要更多的人开发自己的去中心化应用,才能实现以太坊本身的价值。 随着其受欢迎程度的增长,以太坊的价值也在增长。

Homestead是以太坊的第一个正式产品发布,2016年3月发布,目前以太坊还在这个阶段运行,100%采用PoW挖矿。 但是,除了由于算力的增加导致挖矿难度增加之外,还有一个难度系数呈指数级增长,这就是难度炸弹(Difficulty Bomb))。 使用PoS会降低挖矿的门槛,因为你不需要购买昂贵的硬件矿机以太坊eth,只需要购买一定数量的ETH,作为保证金,通过证明来验证交易的有效性股权。 获得一定的奖励。 因此以太坊eth,对于矿工来说,他们花高价买来的矿机将毫无用处,这难免会引起矿工的不满。 为了防止矿工在PoW转PoS的过程中联合起来抵抗,从而分叉出两条以太坊区块链,引入了难度炸弹。 难度炸弹是指在计算难度时,除了根据出块时间和前一个区块的难度进行调整外,还增加了一个每100,000个区块呈指数增长的难度系数。 计算公式如下,最右边的加法项是难度炸弹:

block_diff = parent_diff + parent_diff / 2048 * max(1 - (block_timestamp - parent_timestamp) / 10, -99) + int(2^((block.number / 100000) - 2))

这有点像温水煮青蛙的过程。 额外的难度一开始并不明显,但随着区块高度的增加,指数级增加的难度系数所占比例会显着增加,使得出块变得更加困难。 矿工将很难开采新区块。 目前以太坊区块高度超过420万,难度炸弹开始发力。 出块时间从长期维持的平均15秒左右逐渐增加到25秒,每天新产生的ETH下降到19000个以下(2017年数据截至2009年9月2日)。 随着出块难度越来越大,到最后区块会被完全冻结。 这个过程也被称为“冰河时代”。 有了这样的预期,切换到 PoS 导致的硬分叉将不会是一个艰难的选择。 毕竟,没有人会继续留在即将进入寒冬的区块链中。

但是,PoS 的机制设计存在很多问题需要解决,开发时间比原计划的要长。 根据最近的以太坊改进提案EIP-649(2017年8月26日接受),切换到权益证明(PoS)的时间节点将延迟一年半左右,工作量证明(PoW)将继续发挥主要作用。 为了不阻塞交易,维护系统稳定运行,难度炸弹也需要相应延迟。 实现方式是按照300万个区块的高度来计算挖矿难度,所以出块时间会回到15秒左右,如果不采取任何措施,ETH的供应量将大大超过原计划的供应量难度炸弹时间表,这将导致通货膨胀并降低 ETH 的价值。 为了使ETH的供应量与原计划数量相等,因此需要将每个区块的奖励从原来的5个ETH减少到3个ETH,叔块的奖励也会相应减少。

Homestead 的下一阶段 Metropolis 已分为两个阶段:拜占庭和君士坦丁堡。 拜占庭预计将于 9 月下旬推出,届时将强制执行难度炸弹延迟和区块奖励减少。 君士坦丁堡的规划和开发预计将于今年晚些时候进行。

拜占庭区块高度计算调整:

fake_block_number = max(0, block.number - 3_000_000) if block.number >= BYZANTIUM_FORK_BLKNUM else block.number

拜占庭区块奖励计算调整,3*10e18 wei,即3ETH:

new_block_reward = 3_000_000_000_000_000_000 if block.number >= BYZANTIUM_FORK_BLKNUM else block.reward

乐观估计,以太坊的最后阶段,也就是转PoS的软件版本Serenity,至少会在2018年底发布,具体实施要等到2019年春季之后。届时,PoS的实施将吸引更多的分布式节点加入,为各种分布式应用(Dapp)的运行奠定物理基础。 以太坊有望成为去中心化领域的应用商店,互联网的新时代也将到来。 从软件开发的本质上来说,总会有各种意想不到的问题和困难,所以没有人知道以太坊所设想的宁静乌托邦何时会到来,但这是一件值得期待的事情。 如果说比特币是数字加密货币的开拓者,那么以太坊就是未来的主宰者,它拥有更宏伟的蓝图。

***简单的说,

Frontier(前沿)实验阶段

宅基地增加难度炸弹

拜占庭(大都会)揭穿难度炸弹,修改区块奖励

宁静POS

现在处于拜占庭阶段

我们现阶段只看难度调整算法

拜占庭难度调整算法

// calcDifficultyByzantium is the difficulty adjustment algorithm. It returns
// the difficulty that a new block should have when created at time given the
// parent block's time and difficulty. The calculation uses the Byzantium rules.
func calcDifficultyByzantium(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).Set(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)
    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)
    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))
    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)
    }
    // calculate a fake block number for the ice-age delay:
    //   https://github.com/ethereum/EIPs/pull/669
    //   fake_block_number = min(0, block.number - 3_000_000
    fakeBlockNumber := new(big.Int)
    if parent.Number.Cmp(big2999999) >= 0 {
        fakeBlockNumber = fakeBlockNumber.Sub(parent.Number, big2999999) // Note, parent is 1 less than the actual block number
    }
    // 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.Add(x, y)
    }
    return x
}