比特信用区块HASH算法(BITC Block hashing Algorithm)

当挖矿时,你会经常对区块头进行HASH,你正在挖的区块也会时常更新,一个区域头包含以下数据项:

比特信用区块HASH算法(BITC Block hashing Algorithm)

区块内包含许多交易,它们通过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;

?>


分享到:


相關文章: