Mining Theory – Are my block headers valid?
I need help verifying that the order of issues in block headers is correct for mining. I’m building my own miner as a challenge, but I’m still struggling with the proper format.
data sent to me solo.ckpool.org
am:
"result":((("mining.notify","71ae8ae6")),"5324fa6e",8),"id":1,"error":null
"params":("64851638000ea04d","6a2be50e9bfb43f4973d1b2a84fc5fa27a11730b000209b00000000000000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3503a9d20c0004b8852666047a773e130c","0a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff03c432eb1b000000001976a914c987a18977a2139835193b3df2eea097f834966888ac76dc91000000000016001451ed61d2f6aa260cc72cdf743e4e436a82c010270000000000000000266a24aa21a9ed5c2c1c347c20b2c0818daeda78f4d407f55b405e5652265bbc0b5ab948c615cb00000000",("3d14cb3882afe1cdb6121b77a1c6fe1ace1cfb4f56796875c0e5dc7475d794e5","90107e0ab73bfb0cb540cf129823a3fdd4d2df2d1cfb8a50f2ec4f10da6e4e3f","ce46e565beea4882ea532dfaecb83cc879a60c36a298ab40ec2a3c4e5ae42d65","afbead8f037a81818082f0d276e4a438a3456f0dfcce87255c349264a77ffdf1","67dcbd833c2676450e1f388da5781f902c6c4ca423a88fac6cf2a16827ebd567","7ffff8567be6efa8acd37a27b3c60bd194ca990bca74c9e71dd673d3e0c3f621","53514468979f077ace9ba497d3fa44e5091150188d29ed3dcb80a89f36662839","ff0c843842dde895d2ee8e698d35240517de66bdd839ec3f88d7c3a2b2337724","81a08847bb764ec45481a3e491640d5557fc78276091b69534af71267d1610a5","fb60c793ec790c71bb5b54e93cd8db5f134d9730754ec7c88f71862e07151d7f","bcd9c2f483e5a422e735f23610a40d07790f0ef47bea1218a4fbc1489865202c","b9a275e502fab0f76cb10e9d791a16ef18cf8addbf2ebdc92ede9a07a62dee84"),"20000000","17034219","662685b8",true),"id":null,"method":"mining.notify"
The output I generate is:
Coinbase1 : 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3503a9d20c0004b8852666047a773e130c
Coinbase2 : 0a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff03c432eb1b000000001976a914c987a18977a2139835193b3df2eea097f834966888ac76dc91000000000016001451ed61d2f6aa260cc72cdf743e4e436a82c010270000000000000000266a24aa21a9ed5c2c1c347c20b2c0818daeda78f4d407f55b405e5652265bbc0b5ab948c615cb00000000
Extranonce1 : 5324fa6e
Extranonce2 : 000000008f6bc892
Extranonce2 size : 8
Merkle 0 :3d14cb3882afe1cdb6121b77a1c6fe1ace1cfb4f56796875c0e5dc7475d794e5
Merkle 1 :90107e0ab73bfb0cb540cf129823a3fdd4d2df2d1cfb8a50f2ec4f10da6e4e3f
Merkle 2 :ce46e565beea4882ea532dfaecb83cc879a60c36a298ab40ec2a3c4e5ae42d65
Merkle 3 :afbead8f037a81818082f0d276e4a438a3456f0dfcce87255c349264a77ffdf1
Merkle 4 :67dcbd833c2676450e1f388da5781f902c6c4ca423a88fac6cf2a16827ebd567
Merkle 5 :7ffff8567be6efa8acd37a27b3c60bd194ca990bca74c9e71dd673d3e0c3f621
Merkle 6 :53514468979f077ace9ba497d3fa44e5091150188d29ed3dcb80a89f36662839
Merkle 7 :ff0c843842dde895d2ee8e698d35240517de66bdd839ec3f88d7c3a2b2337724
Merkle 8 :81a08847bb764ec45481a3e491640d5557fc78276091b69534af71267d1610a5
Merkle 9 :fb60c793ec790c71bb5b54e93cd8db5f134d9730754ec7c88f71862e07151d7f
Merkle 10 :bcd9c2f483e5a422e735f23610a40d07790f0ef47bea1218a4fbc1489865202c
Merkle 11 :b9a275e502fab0f76cb10e9d791a16ef18cf8addbf2ebdc92ede9a07a62dee84
Version : 536870912 / 20000000
Merklehash : bc65e13b5f7c69e9ce91adbb063d46b9be2445805e6a2498e13863708d57392c
ntime : 662685b8 / 662685b8
nbits : 17034219 / 17034219
Nonce : 00
Block prevhash : 6a2be50e9bfb43f4973d1b2a84fc5fa27a11730b000209b00000000000000000
Block Header : 000000206a2be50e9bfb43f4973d1b2a84fc5fa27a11730b000209b000000000000000002c39578d706338e198246a5e804524beb9463d06bbad91cee9697c5f3be165bcb88526661942031700000000
Block hash(reversed): 03752b55669564dccb91e47cb1d5fe421fac014e1e9fb2d563d1bd8fe44c86f2
Target(reversed) : 0000000000000000000000000000000000000000194203000000000000000000
The pool is sending the previous hash like this: 6a2be50e9bfb43f4973d1b2a84fc5fa27a11730b000209b00000000000000000
So some parts are already inverted (but nowhere does it say if they are inverted and can be used as is).
Here’s how to construct blocks:
Configuration (connection)
- Do not revert versions in the pool.
20000000
- Don’t invert the previous hash (compared to https://en.bitcoin.it/wiki/Block_hashing_algorithm it looks like it’s inverted).
6a2be50e9bfb43f4973d1b2a84fc5fa27a11730b000209b00000000000000000
- Dash the merkle and flip it over.
- Do not return ntime from the pool.
662685b8
- Do not invert nbits in the pool.
17034219
- Don’t generate a random nonce and revert it.
Add all as usual: version+prev_block_hash+merkle_hash+ntime+nbits+nonce For clarity: version+prev_block_hash+reverse(merkle_hash)+ntime+nbits+nonce
hashing
After calculating the target from nbits, we return it like this:
0000000000000000000000000000000000000000194203000000000000000000
After DHashing the header, return it as follows:
03752b55669564dccb91e47cb1d5fe421fac014e1e9fb2d563d1bd8fe44c86f2
compare
Perform a comparison between the hash and the target using:
int littleEndianCompare(const unsigned char *a, const unsigned char *b, size_t byte_len)
for (size_t i = byte_len - 1; i < byte_len; --i)
if (a(i) < b(i))
return -1;
else if (a(i) > b(i))
return 1;
return 0;
Thank you in advance!