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

在源码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.以太坊的四个阶段

以太坊的创始人们为它设定了4个发展阶段:Frontier,Homestead,Metropolis,Serenity,阶段之间的转换需要通过硬分叉的方式实现。

Frontier是2015年7月以太坊发行初期的试验阶段,那个时候的软件还不太成熟,但是可以进行基本的挖矿,学习,试验。系统运行之后,吸引了更多的人关注并参与到开发中来,以太坊作为一个应用平台,需要更多的人去开发自己的去中心化应用来实现以太坊本身的价值。随着人气渐旺,以太坊的价值也水涨船高。

Homestead是以太坊第一个正式的产品发行版本,于2016年3月发布。目前以太坊仍运行在该阶段,100%采用PoW挖矿,但是挖矿的难度除了因为算力增长而增加之外,还有一个额外的难度因子呈指数级增加,这就是难度炸弹(Difficulty Bomb)。由于PoS的运用将会降低挖矿的门槛,因为你不需要再去购买价格高昂的硬件矿机,只需要购买一定数量的ETH,将其作为保证金通过权益证明的方式验证交易有效性,即可拿到一定的奖励。因此,对矿工来说他们花高价购买的矿机将无用武之地,这势必会引起矿工的不满。为了防止PoW转PoS的过程中矿工联合起来抵制,从而分叉出两条以太坊区块链,难度炸弹被引入。难度炸弹指的是计算难度时除了根据出块时间和上一个区块难度进行调整外,加上了一个每十万个区块呈指数型增长的难度因子。计算公式如下,最右的相加项即为难度炸弹:

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年9月2日数据)。由于出块越来越艰难,到最后区块将被完全冻结,这个过程又被称作“冰川时代”(Ice Age)。有了这个预期,那么转PoS引起的硬分叉就不会是一个困难的选择,毕竟没有人会继续待在那条将要走向凛冬的区块链。

然而PoS的机制设计中有很多问题需要解决,开发时间比原本计划的要长。根据最近的以太坊改进建议EIP-649(2017年8月26日被接受 ), 转换到权益证明(PoS)的时间节点将被延迟约一年半,工作量证明(PoW)将会继续担当大任。为了不堵塞交易,维持系统稳定运行,难度炸弹也需要被相应地延迟,实现方式是将挖矿难度按照回退300万个区块的高度去计算,因此出块时间又将回到15秒左右,如果不采取任何行动,则ETH的供应量会明显超出按原本难度炸弹时间表规划的供应量,这会导致通货膨胀,降低ETH的价值,为了使ETH的供应量与原本计划的数量相当,于是需要减少每个区块的奖励,从原本的5个ETH减少为3个ETH,叔块的奖励也将相应减少。

Homestead的下一阶段Metropolis又被分成了两个阶段:Byzantium和Constantinople。Byzantium预计在9月下旬发布,届时难度炸弹延迟和区块奖励减少将被执行。Constantinople的规划与开发预计将在今年晚些时候进行。

Byzantium的区块高度计算调整:

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

Byzantium的区块奖励计算调整,3*10e18 wei,即3ETH:

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

乐观估计,以太坊的最后一个阶段Serenity,即转成PoS的软件版本至少要到2018年底发布了,具体实施要到2019年春季后。到时PoS的实行将会吸引更多分布式节点的加入,为各种分布式应用(Dapp)的运行打下物理基础,以太坊将有希望成为去中心化领域的app store,互联网的新时代也将到来。从软件开发的性质来说,总是会有各种意想不到的问题和难度出现,所以谁也不知道以太坊设想的乌托邦Serenity最终将在何时到来,不过这是一个值得期待的事件。如果说比特币是数字加密货币开创性的先驱,那么以太坊就是继往开来的主将,它有着更宏伟的蓝图。

***简单来说,
Frontier(前沿)实验阶段
Homestead(家园)加入了难度炸弹
Byzantium(大都会)拆除了难度炸弹,修改区块奖励
Serenity(宁静) POS
现在正处于Byzantium阶段


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

Byzantium难度调整算法

// 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
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容