This question has been asked many times, but none of the answers I have found describe a reproduceable algorithm that I can use to actually create a valid block header that hashes to a reasonable hash value. In fact, all attempts produce hashes that both start and end with a nonzero hex digit. I am using JSON data from an S19 Bitmain Antminer connected to a mining pool. The shares are not only being submitted, but accepted as shown in the JSON exchange. Furthermore, the web interface to the pool agrees with the results. The only conclusion from that is that these exchanges MUST result in a valid acceptable hash which I cannot reproduce.
There are many issues – the endian-ness of the data, whether the merkle root should be calculated using a binary tree, or linearly. I’ve heard it is different for a share than it is for mining an actual block. Do I use the “sixth” field, the “extranonce3” or ignore it?
I’ve been lucky enough to find a share that was submitted with relatively few entries in the merkel branch:
[
“070369f3b9e71bd07eba58ecee5f7769f5882a137dba7ace7aa315e546d2a355”,
“17df59c62159f5092d8eb3c67242111ce2278c60c534a100ed59dee5af251f9b”,
“e61529af81428a67d0a2a0e25d5b244ebfb67249704126526990d3284fc12a61”,
“2f783fd110ec6920f9f974a6ffe2af347906835fa590adfc9854bca1135a9f6e”,
“104233a89763f6a3d2df844d028bda3e60bfa300a0527edce1728ae208513381”,
“c4975154acf6646147041945c72792e0df34db75dfacbc3af78e3f6f903d77f1”,
“8fd8b923680fad7fd3cd87cce33261ebeeaa7ac50526e5d621cf72643cfc2c44”,
“f0ac98ac08f29c37bad7ee3506d584a39ff1856766770bfb008268600502b8d5”,
“2a74468e8ee8b02328b15097301c20f283290812007796a96ac2f30d4dc027ca”
]
now I THINK these are all currently showing in big-endian, but how can we even tell?
Here are the other parameters that can be deduced from the miner/pool exchange:
prevhash:”b672ef88428684ba8f9afd4f79dc17a7250204520001df9a0000000000000000″
coinbase1:”01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff5a030c8a0d1d506f7765726564206279204c75786f72205465636868007105e1f5bcd6fabe6d6d8f91c003e19a377112ca3b0e19f15a5cc26ba53d696e6bd482a0693a90b79be91000000000000000000080cf”
coinbase2:”ffffffff05220200000000000017a914bf73ad4cf3a107812bad3deb310611bee49a3c7987c17cb7120000000017a914056adde53ebc396a1b3b678bb0d3a5c116ff430c870000000000000000266a24aa21a9eddddbc02a37f33c0fb04b32af121bd6892e481307b36f224f2aae103d44584fbb00000000000000002f6a2d434f524501a21cbd3caa4fe89bccd1d716c92ce4533e4d4733f459cc4ca322d298304ff163b2a360d756c5db8400000000000000002b6a2952534b424c4f434b3abfe8db1d3e3c680c9a9bf1623eb701ca3279a6a025f9d9f8e563fb12006fda0200000000″
and the rest:
version=’20000000′;
nbits=”17028bb1″;
ntime=”67c28154″;
nonce=”16384721″;
extranonce1=’00’;
extranonce2=’ec100000000000′;
extranonce2_size=”07″;
and the mysterious sixth field from mining.submit:
extranonce3??=’09b66000′;
I have successfully been able to take similar bits and pieces from an actual mined block and calculate the hash of the coinbase, hash out the merkel root (using binary tree hash) and produce a valid blockheader. I know I am doing this right, because when I take the final 80 byte result and double sha256 it, I get the exact same hash that exists for the block in blockchain explorer. BUT this is with a mined block from the blockchain.
I’ve tried this with the data given above from the miner/pool exchange, and I cannot come up with a decent hash. I already know that the first merkle entry is backwards and I have to reverse endian it to find the block it corresponds to in the blockchain. The other entries are intermediate hashes that are not associated with a block, so I can’t verify them, but I assume if I have to flip the first, then I have to flip them all. DO I include or exclude the sixth field when I try to make the coinbase? Who knows?
As for the merkel tree, I’ve tried the same binary tree hash that I use with a real mined block, but I’ve tried the linear method as well. The only part of the 80 byte header that is in question is the merkel root.
So, I say all that to ask, is there anyone who knows precisely how to do this and get a hash that is proper? Maybe a crytpo mining engineer that actually works with these low level details? I have spent three weeks, going on four, exploring the internet and I cannot find a complete worked example end-to-end showing exactly how to do this.
-gt-