区块链的挖矿演进(区块链,挖矿)
你知道区块链的挖矿演进吗?今天小编就给大家整理一些相关信息,希望对大家有所帮助哦!
正文共:5335字预计阅读时间8分钟挖矿的演进主要集中于几个方向:矿池的设计优化与稳定运行,矿场的科学部署,以及矿机工艺升级,提升算力,降低功耗等。
挖矿是作算法运算的过程,从计算机和代码的角度来说,是反复执行Hash函数并检测执行结果的具体过程。
与讨论算法一样,挖矿也是在采用POW共识机制前提下讨论。
大家已经非常清楚挖矿是由最开始的CPU挖矿,过度到GPU挖矿,最终演化到当前的ASIC(专业矿机)挖矿时代,本篇解析其中的逻辑设计和技术实现。
挖矿的演进是硬件的演进过程,同时也是软件的演进过程,尤其是软硬件对接协议的改进过程,因此本文直接将与挖矿有关的几个核心协议作为小标题,一步步深入讨论。
MINING本小节讨论挖矿原理,首先解析比特币区块头(Blockheader)结构,我们说挖矿本质是执行Hash函数的过程,而Hash函数是一个单输入单输出函数,输入数据就是这个区块头。
比特币区块头共6个字段:如上,比特币每一次挖矿就是对这80个字节连续进行两次SHA256运算(SHA256D),运算结果是固定的32字节(二进制256位)。
以上6个字段情况又各不相同, nVersion,区块版本号,只有在升级时候才会改变。
hashPrevBlock,由前一个区块决定。
nBits,由全网决定,每2016个区块重新调整,调整算法固定。
因此以上3个字段可以理解为是固定的,对于每个矿工来说都一样。
矿工可以自由调整的地方是剩下的3个字段, nNonce,提供2^32种可能取值 nTime,其实本字段能提供的值空间非常有限,因为合理的区块时间有一个范围,这个范围是根据前一个区块时间来定,比前一个区块时间太早或者太超前都会被其他节点拒绝。
值得一提的是,后一个区块的区块时间略早于前一个区块时间,这是允许的。
一般来说,矿工会直接使用机器当前时间戳。
hashMerkleRoot,理论上提供2^256种可能,本字段的变化来自于对包含进区块的交易进行增删,或改变顺序,或者修改Coinbase交易的输入字段。
根据Hash函数特性,这3个字段中哪怕其中任意1个位的变化,都会导致Hash运行结果巨大变化。
在CPU挖矿时代,搜索空间主要由nNonce提供,进入矿机时代,nNonce提供的4个字节已经远远不够,搜索空间转向hashMerkleRoot。
比特币挖矿的逻辑过程如下:打包交易,检索待确认交易内存池,选择包含进区块的交易。
矿工可以任意选择,甚至可以不选择(挖空块),因为每一个区块有容量限制(当前是1M),所以矿工也不能无限选择。
对于矿工来说,最合理的策略是首先根据手续费对待确认交易集进行排序,然后由高到低尽量纳入最多的交易。
构造Coinbase,确定了包含进区块的交易集后,就可以统计本区块手续费总额,结合产出规则,矿工可以计算自己本区块的收益。
构造hashMerkleRoot,对所有交易构造Merkle数。
填充其他字段,获得完整区块头。
Hash运算,对区块头进行SHA256D运算。
验证结果,如果符合难度,则广播到全网,挖下一个块:不符合难度则根据一定策略改变以上某个字段后再进行Hash运算并验证。
合格的区块条件如下:SHA256D(Blockherder) < F(nBits)其中,SHA256D(Blockherder)就是挖矿结果,F(nBits)是难度对应的目标值,两者都是256位,都当成大整数处理,直接对比大小以判断是否符合难度要求。
为了节约区块链存储空间,将256位的目标值通过一定变换无损压缩保存在32位的nBits字段里。
具体变换方法为拆分利用nBits的4个字节,第1个字节代表右移的位数,用V1表示,后3个字节记录值,用V3表示,则有:F(nBits)=V_3 * 2^(8*(V_1-3) )此外难度有最低限制,也就是说 F(nBits) 有个最大值,比特币最低难度取值nBits=0x1d00ffff,对应的最大目标值为:0x00000000FFFF0000000000000000000000000000000000000000000000000000因此挖矿可以形象的类比抛硬币,好比有256枚硬币,给定编号1,2,3……256,每进行一次Hash运算,就像抛一次硬币,256枚硬币同时抛出,落地后要求编号前n的所有硬币全部正面向上。
SETGENERATESetgenerate协议接口代表了CPU挖矿时代。
中本聪在论文里描述了“1 CPU 1 Vote”的理想数字民主理念,在最初版本客户端就附带了挖矿功能,客户端挖矿非常简单,当然,需要同步数据结束才可以挖矿。
现在有很多算力很低的山寨币还是直接使用客户端挖矿,有两种方式可以启动挖矿:在配置文件设置gen=1,然后启动客户端,节点将自行启动挖矿。
客户端启动后,利用RPC接口setgenerate控制挖矿。
如果使用经典QT客户端,点击“帮助”菜单,打开“调试窗口”,在“控制台”输入如下命令:setgenerate true 2,然后回车,客户端就开始挖矿,后面的数字代表挖矿线程数,如果想关闭挖矿,在控制台使用如下命令:setgenerate false,可以使用getmininginfo命令查看挖矿情况。
节点挖矿过程也非常简单:构造区块,初始化区块头各个字段,计算Hash并验证区块,不合格则nNonce自增,再计算并验证,如此往复。
在CPU挖矿时代,nNonce提供的4字节搜索空间完全够用(4字节即4G种可能,单核CPU运算SHA256D算力一般是2M左右),其实nNonce只遍历完两个字节就返回去重构块。
GETWORKgetwork协议代表了GPU挖矿时代,需求主要源于挖矿程序与节点客户端分离,区块链数据与挖矿部件分离。
使用客户端节点直接挖矿,需要同步完整区块链,数据和程序紧密结合,也就是说,如果有多台电脑进行挖矿,需要每台电脑都单独同步一份区块链数据。
这其实没有必要,对于矿工来说,最少只需要一个完整节点就可以。
而以此同时,GPU挖矿时代的到来,也需要一个协议与客户端节点交互。
getwork核心设计思路是:由节点客户端构造区块,然后将区块头数据交给外部挖矿程序,挖矿程序遍历nNonce进行挖矿,验证合格后交付回给节点客户端,节点客户端验证合格后广播到全网。
如前所述,区块头共80个字节,由于没有区块链数据和待确认交易池,nVersion,hashPrevBlock,nBits和hashMerkleRoot这4个字段共72个字节必须由节点客户端提供。
挖矿程序主要是递增遍历nNonce,必要时候可以微调nTime字段。
对于显卡GPU来说,其实不用担心nNonce的4字节搜索空间不足,而且挖矿程序从节点客户端那里拿到一份数据后,不应该埋头工作太久,不然很有可能这个块已经被其他人挖到,继续挖只能做无用功,对于比特币来说,虽然设计为每10分钟一个区块,良好的策略也应该在秒级内重新向节点申请新的挖矿数据。
对于显卡来说,运行SHA256D算力一般介于200M~1G,nNonce提供4G搜索空间,也就是说再好的显卡也能支撑4秒左右,调整一次nTime,又可以再挖4秒,这个时间绰绰有余。
以上就是小编为您介绍的关于区块链的挖矿演进的相关信息,本文到此结束。