比特信用區塊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;

?>


分享到:


相關文章: