死磕以太坊-2-挖矿难度和算力解释

磨链社区-死磕以太坊系列-2-

挖矿难度与算力解释

死磕以太坊,旨在分享区块链、以太坊相关内容,今天分享第二篇:

挖矿难度与算力解释

算力:

比特币挖矿形同猜数字谜,矿工要找出一个随机数(Nonce)参与哈希运算1Hash(Block+Nonce)

,使得区块哈希值符合难度要求。算力则指计算机每秒可执行哈希运算的次数,也称为哈希率(hashrate)。

下图是当前比特币算力图表2。到2017年时,比特币挖矿所需算力疯涨。这与不断研发出的新型矿机投入市场有关——这些矿机利用新的技术,拥有更强的运算能力,即单位成本下的算力在快速增长,由此带来了整体算力的提升。

————————


算力单位:

算力每隔千位划为一个单位,最小单位 H=1次,其他分部是:

1 H/s = 每秒可执行一次哈希运算。

1 KH/s =每秒1,000哈希(一千次)。

1 MH/s =每秒1,000,000次哈希(百万次)。

1 GH/s =每秒1,000,000,000次哈希(十亿次)。

1 TH/s =每秒1,000,000,000,000次哈希(万亿次)。

1 PH/s =每秒1,000,000,000,000,000次哈希。

1 EH/s =每秒1,000,000,000,000,000,000次哈希。

如果不清楚单位简称,可以查看下面国际单位的前缀表3:

挖矿难度计算:

动态调整挖矿难度 Difficulty

为什么算力会变化呢?这和比特币协议设计有关。中本聪设计比特币时,加入挖矿难度调整机制是为了使得比特币出块时间能理想的恒定在10分钟左右。比特币协议规定每隔2016个区块,将根据过去最近2016个区块出块总时间调整,自动调整下一个2016个区块的挖矿难度。理想情况下2016个块需要两周(2016*10s)时间,如果实际用时不到两周则增加难度,如果超过两周就降低难度。

原本中本聪设计的是一个公平的完全去中心化的一个数字货币系统,每个人都可以使用个人电脑进行挖矿。然而,有利可图时大量新算力不断加入,矿工竞争激烈,使得单个矿工的挖矿成功率几乎为零。2011年起矿池出现,大量矿工纷纷加入矿池,以稳定收入,摊薄成本。大量算力融入,使得比特币挖矿难度越来越大。数字货币挖矿业形同军事竞备,挖矿设备不断更新迭代,不再遵循摩尔定律。

专业矿机专门针对哈希算法、散热、耗能进行优化,这脱离了比特币网络节点运行在成千上万的普通计算中并公平参与挖矿的初衷。矿池的算力占据,也使得比特币风险一直存在:51%算力攻击。

————————

挖矿难度计算公式

需要多少算力才能找出一个随机数,由当前区块的挖矿难度决定,难度越大所需算力越多。但挖矿难度并不在区块信息中,只在网络节点中依据规则动态计算,公式如下:

D=T1T

T字母是 Target 的缩写,D字母是 DiFFiculty 缩写。T1和T均是一个256位的大数字(big number),其中T1为一个非常大的常数2256−32−1。依据公式,T越小,挖矿难度D越大

依据公式,当T=0时,D无穷大,标志着无法计算出结果。幸运的是,T不会为 0,最小值为 1,此时难度值最大,为2256−32−1=2224−1。当T=T1时,难度值为最小值 1。

目标值 Target 与挖矿难度转换:

为了方便人类直观估算难度,比特币协议将大数字T

压缩为一个浮点数记录在区块头中,字段为bits。

如果一个区块目标值是 0x1b0404cb,则转化成 Target 值为:0x0404cb×256(0x1b−3)。

T使用类浮点数的一种压缩表示法4进行压缩,压缩计算过程如下:

将数字转换为 256 进制。

如果第一位数字大于 127(0x7f),则前面添加 0。

压缩结果中的第一位存放该256进制数的位数。

后面三个数存放该256进制数的前三位,如果不足三位,从后补零。

例如,将数字1000压缩,先转换为256进制数:1000=0x03×2562−1+0xe8×2561−1

,结果为[0x03,0xe8]。第一个数未超过0x7f,则不需填 0。但长度两位低于三位,在后面补零,最终表示为:0x0203e800。

又比如数字2256−32−1

,转换为256进制为:

FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

第一位数字 0xFF 大于 0x7f,故前面添加零后,变成:

00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF

其长度等于 28+1=29 (0x1d),且长度超过三位,无需补零,则压缩结果为:0x1d00FFFF。因为压缩存储容量只有才4个字节,前两字节已经被长度和添加的 00 所占用,只剩下2个字节来存储数字,这样后面的26个 FF 值被丢弃。

如果我们将压缩结果 0x1d00FFFF 解压还会是原值吗? 实际上结果是:T=0x00FFFF×256×(0x1b−3)

=

0x00000000FFFF0000000000000000000000000000000000000000000000000000

解压时这个数字被截断了,不再是原来的2256−32−1

。比特币的T1

值就是这个 0x1d00FFFF ,如果区块中 bits 为 0x1d00FFFF 则说明该区块挖矿难度为最小挖矿难度 1。

实际上,专业的矿池程序会保留被截断的FF:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

称上面数字为矿池难度 1(pool diFFiculty 1)。因此根据公式,区块目标值为 0x1b0404cb 的挖矿难度在挖机上看到的是:

D = 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /  

     0x00000000000404CB000000000000000000000000000000000000000000000000

   = 16307.669773817162 (pdiFF)

称为 pdiFF。但是一些比特币客户端可能无法精确到这么大,所以不保留尾部的FF:

0x00000000FFFFFF0000000000000000000000000000000000000000000000000000

此时,该挖矿难度为:

D = 0x00000000FFFF0000000000000000000000000000000000000000000000000000 /

   0x00000000000404CB000000000000000000000000000000000000000000000000

 = 16307.420938523983 (bdiFF)

称为 bidFF。

在哪可以查看当前比特币挖矿难度

你可以在一些提供服务的网站上查看图表数据,如:

https://bitcoinwisdom.com/bitcoin/diFFiculty

https://data.bitcoinity.org/bitcoin/diFFiculty/5y?t=l

https://btc.com/stats/diFF

下图是写此文章时,比特币区块 546336 的摘要。

根据难度值如何计算算力

现在我们知道挖矿难度是如何计算的,那么为了挖出一个区块,需要执行多次哈希运算才能找到随机数,使得区块的哈希值小于目标值呢?

前面已确定T1=0x1d00FFFF,解压为0xFFFF×2208,对于 难度D的目标值:D=T1T⟹T=T1D=0xFFFF×2208D

因此,挖出难度为D的区块预计需要计算的哈希次数为:D×22560xFFFF×2208=D∗2480xFFFF

目前难度计算速度要求是在10分钟内找到,即在600秒内完全计算,意味着网络算力最低必须是:D∗2480xFFFF×600=D∗232600

依上计算,当D=1时,需要每秒计算7158278次哈希,即: 7.15 Mhahs/s。

目标值计算源代码

在调整难度时,调整的是目标值。目标值计算公式如下,但在实际计算时有些特别处理,将目标值控制在一定范围内。

新目标值= 当前目标值 * 实际2016个区块出块时间 / 理论2016个区块出块时间(2周)。

判断是否需要更新目标值( 2016的整数倍),如果不是则继续使用最后一个区块的目标值

计算前2016个区块出块用时

如果用时低于半周,则按半周计算。防止难度增加4倍以上。

如果用时高于8周,则按8周计算。防止难度降低到4倍以下。

用时乘以当前难度

再除以2周

如果超过最大难度限制,则按最大难度处理

计算过程,Go代码如下。

var (

   bigOne = big.NewInt(1)

   // 最大难度:00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF,2^224,0x1d00FFFF

   mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne)

   powTargetTimespan = time.Hour * 24 * 14 // 两周

)

func CalculateNextWorkTarget(prev2016block, lastBlock Block) *big.Int {

   // 如果新区块(+1)不是2016的整数倍,则不需要更新,仍然是最后一个区块的 bits

   if (lastBlock.Head.Height+1)%2016 != 0 {

       return CompactToBig(lastBlock.Head.Bits)

   }

   // 计算 2016个区块出块时间

   actualTimespan := lastBlock.Head.Timestamp.Sub(prev2016block.Head.Timestamp)

   if actualTimespan < powTargetTimespan/4 {

       actualTimespan = powTargetTimespan / 4

   } else if actualTimespan > powTargetTimespan*4 {

       // 如果超过8周,则按8周计算

       actualTimespan = powTargetTimespan * 4

   }

   lastTarget := CompactToBig(lastBlock.Head.Bits)

   // 计算公式: target = lastTarget * actualTime / expectTime

   newTarget := new(big.Int).Mul(lastTarget, big.NewInt(int64(actualTimespan.Seconds())))

   newTarget.Div(newTarget, big.NewInt(int64(powTargetTimespan.Seconds())))

   //超过最多难度,则重置

   if newTarget.Cmp(mainPowLimit) > 0 {

       newTarget.Set(mainPowLimit)

   }

   return newTarget

}

————————

  测试代码如下,计算的是对高度为497951+1出块时计算的新目标值。

func TestGetTarget(t *testing.T) {

   firstTime, _ := time.Parse("2006-01-02 15:04:05", "2017-11-25 03:53:16")

   lastTime, _ := time.Parse("2006-01-02 15:04:05", "2017-12-07 00:22:42")

   prevB := Block{Head: BlockHeader{Height: 497951, Bits: 0x1800d0f6, Timestamp: lastTime}}

   prev2016B := Block{Head: BlockHeader{Height: 495936, Bits: 0x1800d0f6, Timestamp: firstTime}}

   result := CalculateNextWorkTarget(prev2016B, prevB)

   bits := BigToCompact(result)

   if bits != 0x1800b0ed {

       t.Fatalf("expect 0x1800b0ed,unexpected %x", bits)

   }

}

————————

参考文章:

比特币哈希算法采用的是SHA256进行工作量证明。 ↩

在bitcoin实时查看比特币算力。 ↩

https://physics.nist.gov/cuu/Units/prefixes.html ↩

IEEE二进制浮点数算术标准(IEEE 754) ↩

-END -

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

推荐阅读更多精彩内容

  • 七月流火,天气已不再酷热,偶尔吹来习习微风,无比惬意,来到美丽的西安,走在陕西师范大学的校园里,感受着校园厚重的文...
    浅笑昨天阅读 372评论 0 0
  • 今天我们学习了情绪。我们了解到情绪的很多知识点,知道了情绪的来源,也了解到了处理情绪的一些办法。其实我们要鼓励把情...
    隽嫕阅读 100评论 0 0
  • 今天司司问我,她是不是白了,哈哈哈。 中午吃的酸辣拌,餐盒破了
    很开心见到你阅读 164评论 0 0
  • 这么长时间了,好像复习的乱七八糟的 基础没有记住,相当于没有掌握 所以做题也是没有思路 好像全都做了无用功 有点烦躁
    张懟懟阅读 143评论 0 0