While trying to calculate the merkle root in python from the data i got from the mining pool.... i found there are 2 different codes.

code 1:

def build_merkle_root(coinbase_hash_bin, merkle_branch):
    merkle_root = coinbase_hash_bin
    for h in merkle_branch:
        merkle_root = hashlib.sha256(hashlib.sha256(merkle_root + binascii.unhexlify(h)).digest()).digest()
    return binascii.hexlify(merkle_root).decode('utf-8')

This is explained in shlushpool stratum document here and also in an altcoin sia mining protocol here . So i think it should be correct. But there is another piece of code below,

code 2:

def build_merkle_root(hash_list):
if len(hash_list) < 2:
    return hash_list[0]
new_hash_list = []

# Process pairs. For odd length, the last is skipped
for i in range(0, len(hash_list) - 1, 2):
    new_hash_list.append(hash2(hash_list[i], hash_list[i + 1]))

# odd, hash last item twice
if len(hash_list) % 2 == 1:
    new_hash_list.append(hash2(hash_list[-1], hash_list[-1]))

return build_merkle_root(new_hash_list)
def hash2(a, b):
     # Reverse inputs before and after hashing due to big-endian / little-endian nonsense
     a1 = binascii.unhexlify(a)[::-1]
     b1 = binascii.unhexlify(b)[::-1]
     h = hashlib.sha256(hashlib.sha256(a1 + b1).digest()).digest()

     return binascii.hexlify(h[::-1])

This one looks more logical from the merkle tree structure point of view which is hashing each pair separately.

For testing them, Taking below as an example of the job obtained from a pool....

[{'id': None,
  'method': 'mining.notify',
  'params': ['59bc8dfc00003829',

Code 1 gives me merkle root as 7cbd55a748aa8e778e0795e33d5bd5a07c9f465cd3de1fef3bf36ea3ac4d56f9 while Code 2 gives as 6681ae1409685d71a51ced80ae0c7eacb78d5facb401ece2287543b6cc17e4cf Since both are not same, so which one is wrong ? I needed merkle root for block header.

In both the above cases, I took extranonce2 all zeros as 0000000000000000 and build coinbase as 01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff3503226b07000455abc259040bf12d090cff47c35900000000000000000a636b706f6f6c112f736f6c6f2e636b706f6f6c2e6f72672fffffffff035976a953000000001976a914fc6123f4bfd3a840b4387ab90e9801e98fb17cf888ac8756d800000000001976a914f4cbe6c6bb3a8535c963169c22963d3a20e7686988ac0000000000000000266a24aa21a9edc963e012cb380138e3d16283a094454782879557714d3b0d73fecfe612d01f0600000000 which gives a coinbase hash of 20d0b9a72f1e940e29b064e428f5e037f948c9ede27dfb7e77b1df7d289d1861


The stratum protocol gives you some hashes of specific branches in the merkle tree. They may not be at the same depth in the tree (and I don't think they are). They are only provided so that the miner can change the coinbase transaction by incrementing the extranonce and then incorporating it into the merkle root. The Code 1 merkle root should be the correct one since that is the method that the Stratum protocol docs tells you to do. The other code is for creating the merkle root from a list of transactions, not a list of branch hashes as Stratum provides.

| improve this answer | |
  • So the merkle_root obtained from Code1 "7cbd55a748aa8e778e0795e33d5bd5a07c9f465cd3de1fef3bf36ea3ac4d56f9" will be used directly in Block Header or it is in display format same as blockchain.info and i will need to reverse the bytes to put it in Block Header. – Santan Sep 20 '17 at 21:45
  • It should be usable directly in the block header. – Andrew Chow Sep 21 '17 at 4:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.