比特币 六、挖矿

挖矿就是不断地尝试block header里的nonce,使block header里的hash值小于等于给定的目标阈值,target就是目标阈值,target越小,挖矿难度越大,调整挖矿难度就是调整目标空间在整个输出空间中所占的比例,比特币用的哈希算法是SHA-256,产生的哈希值是256位的,所以整个输出空间是2的256次方可能个取值,调整的目标空间占输出空间的比例,通俗的说就是哈希值前面要多少个0,比如256位的哈希值,合法的区块要求算出来的哈希前面至少有70个0,当然这是一种通俗的说法,不是特别的准确,因为目标阈值,并不是说前面都是0,从某一个位置开始后面都变成1。所以严格来说还是要按照定义来看,我们听到的另外一种概念就是挖矿难度,挖矿难度和目标阈值是成反比的(difficulty),挖矿难度最小就是1,这个时候对应的目标阈值是一个非常大的数,target越大,挖矿越容易,因为目标空间占的比例非常大
 
那么为什么要调整挖矿难度呢?如果不调整的话会有什么问题?系统中的总算力越来越强,挖矿难度如果保持不变的话,出块时间越来越短。一开始的时候,没用多少人参与比特币游戏的时候,按照设计是十分钟出一个区块,后来参与的人多了变成一分钟出一个区块,再到后来挖矿的人越来越多,用的设备越来越先进,可能十秒钟就出一个区块,甚至到最后不到一秒就出一个区块。当然可能有的人觉得这是一个好事,出块时间越来越短,说明发布一个新的交易的话很快就会被写到区块链里,提高了系统的响应时间,如果要是好事的话那实际上没必要把出块时间设置为十分钟了,因为这十分钟本来也是人为设置的参与,出块时间如果过短,这个区块在网络上传播的时间可能需要几十秒,在底层的比特币网络可能需要几十秒才能让其他结点都收到,别的结点在没收到区块之前还是继续沿着已有的区块链往下扩展,如果有两个结点差不多同时都收到区块,这个时候会出现分叉
出块时间如果越来越短的话,这种分叉会成为常态,而已就不仅仅是二分叉,可能会出现很多的分叉,比如说有十个区块差不多同时被挖出来,那么系统中就会出现十分叉。分叉如果过多,对于系统达成共识,是没有好处的,而且也危害到了系统的安全,比特币协议是假设大部分算力掌握在诚实的矿工手里,系统当中总算力越强,安全性就越好,因为你要发动51%攻击所需要的算力就越大,意思就是说有恶意的结点掌握了系统当中51%的算力,这时候他就可以干各种各样的坏事,包括我们前面说的分叉攻击,大部分算力是掌握在诚实的矿工手里的时候,如果想从某一个位置分叉,想让分叉的链比最长合法链要长,这个难度是比较大的,但是如果出现了很多个分叉,这个时候系统里的总算力就被分散了,结点根据在网络中位置的不同,可能会选择沿着很多分叉中的某一个继续往下扩展,而有恶意的结点可以集中算力就扩展他这一部分分叉,这样很快就可以使这一个分叉变成最长合法链,因为好人的算力被分散了,这时候就不需要51%的算力发动攻击了,可能百分之十几就够了,所以出块时间不是越短越好。
 
当然了,出块时间不是越短越好,那么是不是说,比特币协议中设计的十分钟的出块间隔就是最优的?这个不一定,比如说把他改成八分钟、五分钟,也都是可以的,这个只是说出块时间要有一个常数的波动范围,不能无限的减少下去,有些人觉得比特币中十分钟的出块间隔有点太长了,对于一个支付系统来说,做一个支付,要等那么长时间才能得到确认,这个时间太长了。以太坊里的出块时间就降低到了15秒,所以以太坊的出块速度是比特币的40倍,出块时间大幅度下降之后,以太坊就需要设计一个新的共识机制,叫做GHOST。在这个协议当中,这些分叉产生的orphan block,就不能简单的丢弃掉,而是也要给他们一些奖励(uncle reward),以太坊中同样需要调整挖矿难度使得出块时间保持稳定,所以平均出块时间到底设计成多长,这个没有一定的规定,但是不论设定成多长,都要保持稳定,而不能无限的减少下去。
 
下面讲一下具体怎么调整挖矿难度。比特币协议中规定的是每隔2016个区块要重新调整一下目标阈值,一个区块的出块时间是十分钟,因此这2016个区块大概是两个星期。具体是如何调整的?
target= target * (actual time/expected time)
 
expected time=2016* 10min=2个星期
 
注意:目标阈值和挖矿难度成反比
 
如果实际时间超过2个星期,说明平均下来出块的间隔超过了十分钟,这时候挖矿的难度就应该调的低一点,让出块更容易,(actual time/expected time)大于1 ,target变大,挖矿难度低;反之同理。
 
实际代码中,上调和下调都是有四倍的限制,比如实际时间非常长,超过了八个星期,那么我们算的时候也只按照八个星期来算,这主要是为了避免系统中出现意外情况目标阈值而产生的巨大波动,反之最小减少四倍
 
怎么才能让所有的矿工同时调整目标阈值呢?计算target的方法是写在比特币系统的代码里的,每挖到2016个区块会自动进行调整。这个代码是开源的,所以某个有恶意的结点,到这个时候故意不调整挖矿难度,会产生什么后果?
 
如果不调整,诚实的矿工是不会认可的,block header里的nBits域是target值编码后的结果,检查区块的合法性就无法通过,每一个结点要独立验证发布区块的合法性,检查的内容之一就是检查nBits目标阈值是否合法,如果你投机取巧设一个过大的目标阈值,使得你自己挖矿容易了,但是别人算出来你的nBits设置的不对,这个区块是不会被接受的
 
有些人觉得没有买比特币特别可惜,比特币当初那么便宜的时候怎么没有买,现在回过头你可以说比特币是一个多么伟大的发明,当时多么具有革命性。其实如果你了解历史的话,在比特币之前有很多加密货币都是失败的,比特币出现之前大概有20多年对加密货币的研究历史,这期间的一些研究都没有成功,比特币的成功其实并不是因为它更实用,从某种意义上说是因为它更不实用,以前那些失败的加密货币都是怎么设计的?是设计成它是现实货币的电子支付渠道(网上支付的方法),有一些真的货币,然后这些货币线下流通可以,线上不方便,设计了一个线上的版本。比特币是没有任何真正法币背书的,完全是凭空造出来的货币,中本聪设计这个加密货币的时候,里面有很多参数,出块时间设置成十分钟是不是最好的?每个块最多1M字节是不是合适的?为什么是2016个区块调一次挖矿难度?这些参数是经验参数还是怎么来的?这些参数是合理的,但不一定是最优的,整个比特币系统设置的还是比较保守的,从出块时间、区块大小、支持的脚本语言来说,都是很保守的,比特币社区获得的支持者也是比较保守的,他可能是因为自己有了很多比特币,不愿意危机到他自己的财富
 
下面看一下比特币系统中的一些实际情况
 
下面这张图显示了比特币系统中总算力的变化情况
 
在比特币还没有流行起来之前,有很长一段时间,算力没有什么增长,前面这些年的hash rate看上去几乎是0,贴着x轴,其实这些年算力也是在增长的,只不过是后面这几年算力增长的太快了,所以前面这部分看上去像是一条直线。这几年是加密货币涨的非常猛的一年,这也体现在了hash rate的增长,这几年算力呈现指数级的增长。注意即使是在这段黄金时期,算力也不是单调递增的,中间也是有很多波动,但总的来说是增长的非常快的
 
下面这张图是挖矿难度的变化情况
跟算力的增长基本是同步的,这也符合难度调整的设计目标,通过调整挖矿难度,使得出块时间保持稳定,注意这个图显示的是挖矿难度,不是目标阈值
 
这是最近半年的难度调整曲线,可以看出很明显是一段一段的,每隔两个星期难度上一个台阶,说明挖矿的人越来越多,用的设备越来越先进,反映出大家对比特币的热情越来越高。如果出现相反的情况,比如某个加密货币的难度越调越小,说明挖矿变得越来越容易了,但这不是好事,说明大家对这个币的热情是逐渐减少的,如果持续出现这种情况,一般来说这个币就慢慢不行了
 
 
下图显示的是2010-2018年比特币系统的出块时间
从图中可以看到,总的来说出块时间稳定在十分钟上下震动,说明难度调整达到了预期目的
 
 
 
 


posted @ 2021-02-17 14:56  lazy远  阅读(274)  评论(0)    收藏  举报