0

Transaction #59500 has 045c670f1c02c919 as its coinbase. Transaction 1 is 6653ad77d695752cff9fe63bbb5702a53807be534c537251d53de06aac5ca093. Transaction 2 is 72e8781092c01e9eb1c21ba33d52ad6abc42f3807601bcd8b8074d583446346e.

Double SHA256 of Coinbase

import hashlib
header_hex = ("045c670f1c02c919")
header_bin = header_hex.decode('hex')
hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
hash.encode('hex_codec')
'6eafdb5c504ed7e70536d70c666503f4435205f367f21d2960ff2262ca2acf0b'
hash[::-1].encode('hex_codec')
'0bcf2aca6222ff60291df267f3055243f40365660cd73605e7d74e505cdbaf6e'

Double SHA256 of Transaction 1

header_hex = ("6653ad77d695752cff9fe63bbb5702a53807be534c537251d53de06aac5ca093")
header_bin = header_hex.decode('hex')
hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
hash.encode('hex_codec')
'b2e28ac8528477c0c3c7978ee29479ae9ca1aed9cb2e58e6b910f17142f6c53d'
hash[::-1].encode('hex_codec')
'3dc5f64271f110b9e6582ecbd9aea19cae7994e28e97c7c3c0778452c88ae2b2'

Would I then combine the double hash of the coinbase with the double hash of transaction 1? Like so: ("0bcf2aca6222ff60291df267f3055243f40365660cd73605e7d74e505cdbaf6e" + "3dc5f64271f110b9e6582ecbd9aea19cae7994e28e97c7c3c0778452c88ae2b2) and then double hash that?

The double hash of the coinbase and transaction 1 is d77fefa4fd82afdf1780f84dae5dc30be2f3b53bc8db2c40db6d17687324dc48

Double SHA256 of Transaction 2

header_hex = ("72e8781092c01e9eb1c21ba33d52ad6abc42f3807601bcd8b8074d583446346e")
header_bin = header_hex.decode('hex')
hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
hash.encode('hex_codec')
'c9f7032f5df64761e74ad4bc7cb653db8c78aed331926382ca37ec3b8d8625a9'
hash[::-1].encode('hex_codec')
'a925868d3bec37ca82639231d3ae788cdb53b67cbcd44ae76147f65d2f03f7c9'

Would I then hash a925868d3bec37ca82639231d3ae788cdb53b67cbcd44ae76147f65d2f03f7c9 with itself?

header_hex = ("a925868d3bec37ca82639231d3ae788cdb53b67cbcd44ae76147f65d2f03f7c9" + "a925868d3bec37ca82639231d3ae788cdb53b67cbcd44ae76147f65d2f03f7c9")
header_bin = header_hex.decode('hex')
hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
hash.encode('hex_codec')
'4075e4ac60dd8a52ed3eb69520ad71d660c8c2bcbf4073c87fd633a276cb2921'
hash[::-1].encode('hex_codec')
'2129cb76a233d67fc87340bfbcc2c860d671ad2095b63eed528add60ace47540'

Lastly when I try to combine that hash of the coinbase and transaction 1 with the hash of transaction 2 with itself... ''d77fefa4fd82afdf1780f84dae5dc30be2f3b53bc8db2c40db6d17687324dc48' + ''2129cb76a233d67fc87340bfbcc2c860d671ad2095b63eed528add60ace47540"

I got this 012853eb35789c270fc72dc11b4b9e24710f6f02793344860bdcad7f25e771e1 when the merkle root is :

ff682ef66cd1b56213fd4db9462fb138f6d8c16d706d41969a7eacc819528038

What did I do wrong?

2

There are multiple things that you have done wrong.

First, you hashed just the coinbase part of the coinbase transaction. You are supposed to hash the entire coinbase transaction.

Second, you have hashed the transaction ids of the transactions, not the transactions themselves. Hashing the transaction themselves will result in the txid (ignoring segwit). So instead of hashing the txids again, you just take those as the first hash in the merkle tree and combine them and hash the combination for the second level of hashes.

Third, you reversed the hash hexadecimal representation. You should not be reversing those hashes. However, if you start with the txids instead of the transactions themselves, you need to byteswap the twids first. Byteswapping is different from reversing the hex of the string as two hex characters represent one byte. It is easier to do this when the hex has already been decoded into a byte string.

For combining hashes, you just concatenate them. For the last transaction, if it is by itself, you copy its hash and concatenate the copy to the original. It is just the txid concatenated to itself.

  • You can get the hexstring for the transaction by using a block explorer with their raw tx API. For example, using blockcypher, you can get the raw coinbase transaction with the link api.blockcypher.com/v1/btc/main/txs/…. The hex field is the raw transaciton. However, you don't need this because you have the txid of the coinbase from the block explorer, so you can just use that. – Andrew Chow Jul 7 '18 at 6:26
  • Thank you Andrew! So if I was given the transaction ID of 72e8781092c01e9eb1c21ba33d52ad6abc42f3807601bcd8b8074d583446346e. How would I go about byteswapping this? When you say byte string is that the same as binary? – Ben Stolman Jul 7 '18 at 6:46
  • Yes, a bytestring is the same as binary. Byteswapping a hex string means that ever two characters (representing one byte) is swapped with the two characters in the same position at the end of the string. So byteswapping that txid gives you 6e344634584d07b8d8bc017680f342bc6aad523da31bc2b19e1ec0921078e872 – Andrew Chow Jul 7 '18 at 7:35
  • I'm sorry I keep asking questions I just want to get this right. How would I derive the coinbase transaction from the raw data under hex? If transaction 1 is the coinbase transaction I would byteswap that which would give me 93a05cac6ae03dd55172534c53be0738a50257bb3be69fff3c7595d677ad5366. Transaction 2 is the one that you byteswapped which is 6e344634584d07b8d8bc017680f342bc6aad523da31bc2b19e1ec0921078e872. So then do I just combine them 93a05cac6ae03dd55172534c53be0738a50257bb3be69fff3c7595d677ad53666e344634584d07b8d8bc017680f342bc6aad523da31bc2b19e1ec0921078e872 and double hash them? – Ben Stolman Jul 7 '18 at 19:07
  • Yes, that is correct. – Andrew Chow Jul 7 '18 at 19:28
0

I messed up many many things. First, transaction 1 is the Coinbase transaction, which means that there are only 2 transactions to be hashed together. Second, I didn't byte-swap the TXID's before hashing them together. After getting the double hashed hex string you have to byte-swap it to get the correct Merkle Root.

Transaction 1 is 6653ad77d695752cff9fe63bbb5702a53807be534c537251d53de06aac5ca093 Byteswapped = 93a05cac6ae03dd55172534c53be0738a50257bb3be69fff2c7595d677ad5366

Transaction 2 is 72e8781092c01e9eb1c21ba33d52ad6abc42f3807601bcd8b8074d583446346e Byteswapped = 6e344634584d07b8d8bc017680f342bc6aad523da31bc2b19e1ec0921078e872

import hashlib

header_hex = "93a05cac6ae03dd55172534c53be0738a50257bb3be69fff2c7595d677ad53666e344634584d07b8d8bc017680f342bc6aad523da31bc2b19e1ec0921078e872"

header_bin = header_hex.decode('hex')

hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()

hash.encode('hex_codec') '38805219c8ac7e9a96416d706dc1d8f638b12f46b94dfd1362b5d16cf62e68ff'

hash[::-1].encode('hex_codec') 'ff682ef66cd1b56213fd4db9462fb138f6d8c16d706d41969a7eacc819528038'

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.