0

I am trying to go through the code to check the merkle tree hash computation done by BlockMerkleRoot in bitcoin core. The hash computed using online tools by appending transaction hashes is different from the ones computed by SHA256D64 of BlockMerkleRoot. I am sure I am missing something. Could someone throw light on this?

Details: Looking at block 500000:

appending coinbase hash 2157b554dcfda405233906e461ee593875ae4b1b97615872db6a25130ecc1dd6 with the first transaction hash fe6c48bbfdc025670f4db0340650ba5a50f9307b091d9aaa19aa44291961c69f and computing sha256 gives 0387276cdb563dc923e945f8e68596e3556756d2f2119b9b67905658b73afcb2 and doing another sha256 gives 1c0a7630e70d2b39b15585ec19c13c6f0a729a6501f5396dd75f75cb3aa4d110 which is different from the one returned by SHA256D64 which is 1024e63a6bdab1efb75aae1dd065c11a97cf94e978e6aed9adb2f04d08887164.

2 Answers 2

0

The tool you are linking to is hashing text, Bitcoin hashes are of bytes.

2
  • I used hex version in the tool
    – explore
    Jun 24, 2021 at 1:44
  • I used shasum and I get a different result :) I am definitely missing something fundamental. ``` x@instance1:~/backup$ echo -n 2157b554dcfda405233906e461ee593875ae4b1b97615872db6a25130ecc1dd6fe6c48bbfdc025670f4db0340650ba5a50f9307b091d9aaa19aa44291961c69f|xxd -r -p | shasum -b | awk '{print $1}' 41ca9dd2793aa443509251d3c90f1a3669d1b65e x@instance1:~/backup$ echo -n 41ca9dd2793aa443509251d3c90f1a3669d1b65e |xxd -r -p | shasum -b | awk '{print $1}' 54daec3b996b6fcd0d04f70bdac2067b86e44e55 x@instance1:~/backup$ ```
    – explore
    Jun 24, 2021 at 1:51
0

The strings you posted are technically transaction IDs not transaction hashes and have to be reversed to get that "actual hash". In bitcoin when hashes are printed as strings they are reversed. The actual hashes you should use are d61dcc0e13256adb725861971b4bae753859ee61e406392305a4fddc54b55721|9fc661192944aa19aa9a1d097b30f9505aba500634b04d0f6725c0fdbb486cfe When this is hashed twice it gives the following result: 647188084df0b2add9aee678e994cf971ac165d01dae5ab7efb1da6b3ae62410 since we print hashes in reverse it becomes "1024...7164" which is what you got from SHA256D64.

4
  • Thank you. You are right. The GetHex is doing the reverse of the hash to be printed using ToString. May I know the rationale behind why the transaction ID/ToString is reverse of the actual transaction hash?
    – explore
    Jun 24, 2021 at 14:40
  • I suppose this is the case for blockhash as well, which is 00000000000000000024fb37364cbf81fd49cc2d51c09c75c35433c3a1945d04 . If this is byte reversed to get the "actual hash", it starts with 045d..0000. How does CheckProofOfWork work? How is this "actual hash" less than the target difficulty set for the block? I see UintToArith256 copying word by word without much change other than endian-ness. Could you please provide clarity?
    – explore
    Jun 24, 2021 at 15:32
  • 1
    I got part of the answer here
    – explore
    Jun 24, 2021 at 23:49
  • The reason is this: SHA256 outputs a byte array, but in early versions of the Bitcoin software, that byte array was interpreted as a number - in little endian (least significant digit first). In the RPC output, those numbers are printed for human consumption in hex, with the most significant digit first (which matters; otherwise, block hashes would have their 0s at the end, which wouldn't look like "small" numbers). Jul 24, 2021 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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