当挖矿时,你会经常对区块头进行HASH,你正在挖的区块也会时常更新,一个区域头包含以下数据项:
区块内包含许多交易,它们通过Merkle根节点间接被HASH,因为所有交易不可能直接被HASH,HASH包含一个交易的区块所花的时间,和HASH包含1万个交易的区块一样。
目标HASH值的压缩格式是一个特殊的浮点编码类型,首字节是指数(仅使用了5个最低位),后3个字节是尾数,它能表示256位的数值。一个区块头的SHA256值必定要小于或等于目标HASH值,该区块才能被网络所接受,目标HASH越低,产生一个新区块的难度越大。
如果当前区块的时间戳大于前11个区块的的平均时间戳,并且小于“网络调整时间(Network-Adjusted Time)”+2小时,则认为该时间戳是有效的。其中的“网络调整时间”是指与你相连接的所有节点的平均时间。当节点A连接到节点B时,A从B处得到一个UTC标准的时间戳,A先转换成本地UTC标准时间保存起来,网络调整时间等于所有节点的本地UTC时间+所有相连节点的偏移量平均值,然而,该网络时间永远不会调整到超过本地系统时间70分钟以上。
Nonce随机数通常不同,但是它以严格的线性方式增长,从0开始,每次HASH时都会增长,当Nonce溢出时(此事经常发生),生产交易的extraNonce项会增长,将改变Merkle树的根节点。
假定针对这些数据项,人们经常会独自产生同样序列号的HASH值,最快的CPU通常会赢。然而,两人产生同样的Merkle根节点基本是(或近似)不可能的,因为区块中的第一个交易是生产交易并且“发送”到你的独一无二的比特信用地址。因为你的区块与其他人的区块不同,产生的HASH也肯定(近似肯定)不同,你计算的每个HASH和网络中的其他人一样,都有同样的获胜机会。
比特信用使用:SHA256(SHA256(区块头))计算HASH,但你要注意字节序。
例如:以下python代码用于计算某一区块的HASH值,使用2011年6月的区块号125552的最小HASH值。该区块头建立上述6个数据项之上,并且以十六进制的小端结尾方式连接在一起。
>>> import hashlib
>>> header_hex = ("01000000" +
"81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000" +
"e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b" +
"c7f5d74d" +
"f2b9441a" +
"42a14695")
>>> header_bin = header_hex.decode('hex')
>>> hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
>>> hash.encode('hex_codec')
'1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000'
>>> hash[::-1].encode('hex_codec')
'00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'
注意:实际的HASH值是一串256位的数值,首部有许多零。当以大头端十六进制常数方式打印或存贮时,它的首部有许多零;如果它以小头端打印或存贮,零就会变换到尾部。例如:如果表示成字节串-最低(或者开头)的字节串地址显示最小位的数,这样就是小头端表示。blockexplorer的输出把HASH值显示为大头端表示的数值,因为数字的表示通常是-首部数字是最大数字,从左向右读。
举另外一个例子:这儿是纯C版本,未进行任何优化、线程化和错误检查。
以下是同样的例子,用PHP写,没有任何优化。
//This reverses and then swaps every other char
function SwapOrder($in){
$Split = str_split(strrev($in));
$x=;
for ($i = 0; $i < count($Split); $i+=2) {
$x .= $Split[$i+1].$Split[$i];
}
return $x;
}
//makes the littleEndian
function littleEndian($value){
return implode (unpack('H*',pack("V*",$value)));
}
$version = littleEndian(1);
$prevBlockHash = SwapOrder('00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81');
$rootHash = SwapOrder('2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3');
$time = littleEndian(1305998791);
$bits =littleEndian( 440711666);
$nonce = littleEndian(2504433986);
//concat it all
$header_hex = $version . $prevBlockHash . $rootHash . $time . $bits . $nonce;
//convert from hex to binary
$header_bin = hex2bin($header_hex);
//hash it then convert from hex to binary
$pass1 = hex2bin( hash('sha256', $header_bin ) );
//Hash it for the seconded time
$pass2 = hash('sha256', $pass1);
//fix the order
$FinalHash = SwapOrder($pass2);
echo $FinalHash;
?>
閱讀更多 區塊鏈世界點評 的文章