https://tests.bitcoin.it/w/api.php?action=feedcontributions&user=RomanKnight&feedformat=atomBitcoin Wiki - User contributions [en]2023-02-05T18:31:50ZUser contributionsMediaWiki 1.30.0https://tests.bitcoin.it/w/index.php?title=Block_hashing_algorithm&diff=43698Block hashing algorithm2014-01-12T00:07:36Z<p>RomanKnight: </p>
<hr />
<div>When generating, you constantly hash the block header. The block is also occasionally updated as you are working on it. A block header contains these fields:<br />
{| class="wikitable"<br />
|-<br />
! Field<br />
! Purpose<br />
! Updated when...<br />
! Size (Bytes)<br />
|-<br />
|Version<br />
|Block version number<br />
|You upgrade the software and it specifies a new version<br />
|4<br />
|-<br />
|hashPrevBlock<br />
|256-bit hash of the previous block header<br />
|A new block comes in<br />
|32<br />
|-<br />
|hashMerkleRoot<br />
|256-bit hash based on all of the transactions in the block<br />
|A transaction is accepted<br />
|32<br />
|-<br />
|Time<br />
|Current timestamp as seconds since 1970-01-01T00:00 UTC<br />
|Every few seconds<br />
|4<br />
|-<br />
|Bits<br />
|Current [[target]] in compact format<br />
|The [[difficulty]] is adjusted<br />
|4<br />
|-<br />
|Nonce<br />
|32-bit number (starts at 0)<br />
|A hash is tried (increments)<br />
|4<br />
|}<br />
<br />
The body of the block contains the transactions. These are hashed only indirectly through the Merkle root. Because transactions aren't hashed directly, hashing a block with 1 transaction takes exactly the same amount of effort as hashing a block with 10,000 transactions.<br />
<br />
The compact format of target is a special kind of floating-point encoding using 3 bytes mantissa, the leading byte as exponent (where only the 5 lowest bits are used) and its base is 256.<br />
Most of these fields will be the same for all users. There might be some minor variation in the timestamps. The nonce will usually be different, but it increases in a strictly linear way. "Nonce" starts at 0 and is incremented for each hash. Whenever Nonce overflows (which it does frequently), the extraNonce portion of the generation transaction is incremented, which changes the Merkle root.<br />
<br />
Given just those fields, people would frequently generate the exact same sequence of hashes as each other and the fastest CPU would almost always win. However, it is (nearly) impossible for two people to have the same Merkle root because the first transaction in your block is a generation "sent" to one of ''your'' unique Bitcoin addresses. Since your block is different from everyone else's blocks, you are (nearly) guaranteed to produce different hashes. Every hash you calculate has the same chance of winning as every other hash calculated by the network.<br />
<br />
Bitcoin uses: SHA256(SHA256(Block_Header)) but you have to be careful about byte-order.<br />
<br />
For example, this python code will calculate the hash of the block with the smallest hash as of June 2011, [http://blockexplorer.com/block/00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d Block 125552]. The header is built from the six fields described above, concatenated together as little-endian values in hex notation:<br />
<br />
>>> import hashlib<br />
>>> header_hex = ("01000000" +<br />
"81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000" +<br />
"e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b" +<br />
"c7f5d74d" +<br />
"f2b9441a" +<br />
"42a14695")<br />
>>> header_bin = header_hex.decode('hex')<br />
>>> hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()<br />
>>> hash.encode('hex_codec')<br />
'1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000'<br />
>>> hash[::-1].encode('hex_codec')<br />
'00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'<br />
<br />
Note that the actual hash, which is a 256-bit number, has lots of leading zero bits. When stored or printed as a big-endian hexadecimal constant, but it has leading zero bytes and if stored or printed as little-endian, these are the trailing zero bytes. E.g. if interpretation as a string -- lowest (or start of) string address keeps lowest significant byte, thus little-endian.<br />
The output of [http://blockexplorer.com blockexplorer] displays the hash values as big-endians numbers as notation for numbers is usual -- leading digits are the most significant digits read from left to right.<br />
<br />
For another example, [http://pastebin.com/bW3fQA2a here] is a version in plain C without any optimization, threading or error checking.<br />
<br />
Here is the same example in plain PHP without any optimization.<br />
<br />
<?<br />
//This reverses and then swaps every other char<br />
function SwapOrder($in){<br />
$Split = str_split(strrev($in));<br />
$x='';<br />
for ($i = 0; $i < count($Split); $i+=2) {<br />
$x .= $Split[$i+1].$Split[$i];<br />
} <br />
return $x;<br />
}<br />
<br />
//makes the littleEndian<br />
function littleEndian($value){<br />
return implode (unpack('H*',pack("V*",$value)));<br />
}<br />
<br />
$version = littleEndian(1);<br />
$prevBlockHash = SwapOrder('00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81');<br />
$rootHash = SwapOrder('2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3');<br />
$time = littleEndian(1305998791);<br />
$bits =littleEndian( 440711666); <br />
$nonce = littleEndian(2504433986); <br />
<br />
//concat it all<br />
$header_hex = $version . $prevBlockHash . $rootHash . $time . $bits . $nonce;<br />
<br />
//convert from hex to binary <br />
$header_bin = hex2bin($header_hex);<br />
//hash it then convert from hex to binary <br />
$pass1 = hex2bin( hash('sha256', $header_bin ) );<br />
//Hash it for the seconded time<br />
$pass2 = hash('sha256', $pass1);<br />
//fix the order<br />
$FinalHash = SwapOrder($pass2);<br />
<br />
echo $FinalHash;<br />
?><br />
<br />
<br />
[[Category:Technical]]</div>RomanKnighthttps://tests.bitcoin.it/w/index.php?title=Talk:Block_hashing_algorithm&diff=43695Talk:Block hashing algorithm2014-01-11T15:24:25Z<p>RomanKnight: </p>
<hr />
<div>What is licensing/copyright information on that code? Public domain?<br />
<br />
"Because transactions aren't hashed directly, hashing a block with 1 transaction takes exactly the same amount of effort as hashing a block with 10,000 transactions."<br />
<br />
Doesn't it take more effort to calculate the Merkle root for 10,000 transactions than it does than for 1 transaction? Of course, you only have to do this once per block, but it's misleading. It seems you're using "hashing a block" to specifically mean the (iterative) hash calculation, not the process of block generation. I recommend rewording to :<br />
<br />
"These are hashed only indirectly through the Merkle root. Because transactions aren't hashed directly, hashing a block with 1 transaction takes exactly the same amount of effort as hashing a block with 10,000 transactions, once the Merkle root of those transactions is calculated." [[User:Therealplato|Therealplato]] 23:41, 28 January 2012 (GMT)<br />
<br />
I added PHP code this code will help beginners with what is going on. The code is simple and well documented anyone regardless of PHP knowledge should be able to read this and know how to hash Bitcoins. [[User:RomanKnight|RomanKnight]] 10:23, 11 January 2014 (EST)</div>RomanKnighthttps://tests.bitcoin.it/w/index.php?title=Block_hashing_algorithm&diff=43694Block hashing algorithm2014-01-11T15:20:17Z<p>RomanKnight: </p>
<hr />
<div>When generating, you constantly hash the block header. The block is also occasionally updated as you are working on it. A block header contains these fields:<br />
{| class="wikitable"<br />
|-<br />
! Field<br />
! Purpose<br />
! Updated when...<br />
! Size (Bytes)<br />
|-<br />
|Version<br />
|Block version number<br />
|You upgrade the software and it specifies a new version<br />
|4<br />
|-<br />
|hashPrevBlock<br />
|256-bit hash of the previous block header<br />
|A new block comes in<br />
|32<br />
|-<br />
|hashMerkleRoot<br />
|256-bit hash based on all of the transactions in the block<br />
|A transaction is accepted<br />
|32<br />
|-<br />
|Time<br />
|Current timestamp as seconds since 1970-01-01T00:00 UTC<br />
|Every few seconds<br />
|4<br />
|-<br />
|Bits<br />
|Current [[target]] in compact format<br />
|The [[difficulty]] is adjusted<br />
|4<br />
|-<br />
|Nonce<br />
|32-bit number (starts at 0)<br />
|A hash is tried (increments)<br />
|4<br />
|}<br />
<br />
The body of the block contains the transactions. These are hashed only indirectly through the Merkle root. Because transactions aren't hashed directly, hashing a block with 1 transaction takes exactly the same amount of effort as hashing a block with 10,000 transactions.<br />
<br />
The compact format of target is a special kind of floating-point encoding using 3 bytes mantissa, the leading byte as exponent (where only the 5 lowest bits are used) and its base is 256.<br />
Most of these fields will be the same for all users. There might be some minor variation in the timestamps. The nonce will usually be different, but it increases in a strictly linear way. "Nonce" starts at 0 and is incremented for each hash. Whenever Nonce overflows (which it does frequently), the extraNonce portion of the generation transaction is incremented, which changes the Merkle root.<br />
<br />
Given just those fields, people would frequently generate the exact same sequence of hashes as each other and the fastest CPU would almost always win. However, it is (nearly) impossible for two people to have the same Merkle root because the first transaction in your block is a generation "sent" to one of ''your'' unique Bitcoin addresses. Since your block is different from everyone else's blocks, you are (nearly) guaranteed to produce different hashes. Every hash you calculate has the same chance of winning as every other hash calculated by the network.<br />
<br />
Bitcoin uses: SHA256(SHA256(Block_Header)) but you have to be careful about byte-order.<br />
<br />
For example, this python code will calculate the hash of the block with the smallest hash as of June 2011, [http://blockexplorer.com/block/00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d Block 125552]. The header is built from the six fields described above, concatenated together as little-endian values in hex notation:<br />
<br />
>>> import hashlib<br />
>>> header_hex = ("01000000" +<br />
"81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000" +<br />
"e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b" +<br />
"c7f5d74d" +<br />
"f2b9441a" +<br />
"42a14695")<br />
>>> header_bin = header_hex.decode('hex')<br />
>>> hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()<br />
>>> hash.encode('hex_codec')<br />
'1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000'<br />
>>> hash[::-1].encode('hex_codec')<br />
'00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'<br />
<br />
Note that the actual hash, which is a 256-bit number, has lots of leading zero bits. When stored or printed as a big-endian hexadecimal constant, but it has leading zero bytes and if stored or printed as little-endian, these are the trailing zero bytes. E.g. if interpretation as a string -- lowest (or start of) string address keeps lowest significant byte, thus little-endian.<br />
The output of [http://blockexplorer.com blockexplorer] displays the hash values as big-endians numbers as notation for numbers is usual -- leading digits are the most significant digits read from left to right.<br />
<br />
For another example, [http://pastebin.com/bW3fQA2a here] is a version in plain C without any optimization, threading or error checking.<br />
<br />
Here is same example in plain PHP without any optimization.<br />
<br />
<?<br />
//This reverses and then swaps every other char<br />
function SwapOrder($in){<br />
$Split = str_split(strrev($in));<br />
$x='';<br />
for ($i = 0; $i < count($Split); $i+=2) {<br />
$x .= $Split[$i+1].$Split[$i];<br />
} <br />
return $x;<br />
}<br />
<br />
//makes the littleEndian<br />
function littleEndian($value){<br />
return implode (unpack('H*',pack("V*",$value)));<br />
}<br />
<br />
$version = littleEndian(1);<br />
$prevBlockHash = SwapOrder('00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81');<br />
$rootHash = SwapOrder('2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3');<br />
$time = littleEndian(1305998791);<br />
$bits =littleEndian( 440711666); <br />
$nonce = littleEndian(2504433986); <br />
<br />
//concat it all<br />
$header_hex = $version . $prevBlockHash . $rootHash . $time . $bits . $nonce;<br />
<br />
//convert from hex to binary <br />
$header_bin = hex2bin($header_hex);<br />
//hash it then convert from hex to binary <br />
$pass1 = hex2bin( hash('sha256', $header_bin ) );<br />
//Hash it for the seconded time<br />
$pass2 = hash('sha256', $pass1);<br />
//fix the order<br />
$FinalHash = SwapOrder($pass2);<br />
<br />
echo $FinalHash;<br />
?><br />
<br />
<br />
[[Category:Technical]]</div>RomanKnight