Bitcoin Forum
November 01, 2024, 10:47:39 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: What is wrong with this little python code to hash a header?  (Read 124 times)
Sha256explorer (OP)
Jr. Member
*
Offline Offline

Activity: 47
Merit: 18


View Profile
April 10, 2023, 08:48:37 PM
Last edit: April 10, 2023, 09:53:56 PM by Sha256explorer
 #1

I wrote a short piece of software to check if I understood correctly how the block hash calculation is done.
I started from the python code published here: https://bitcointalk.org/index.php?topic=5439273.0
I analyzed a random block, namely block 784697
the program generates a wrong hash.
please, where am I wrong?

Code:
import binascii
import hashlib

# block 784697    
# decoded_raw_block":{"hash":"000000000000000000044b32a02685122ddef6a1a54990a7f0883577ae67128e","confirmations":5,"height":784697,"version":577257472,"versionHex":"22684000","merkleroot":"97cbf0be2eb628cd1548d3b755f0e04b0fe4f06c15b4882ea90b7a2ae93728c0","time":1681074323,"mediantime":1681068560,"nonce":3518743859,"bits":"1705e0b2","difficulty":47887764338536.25,"chainwork":"0000000000000000000000000000000000000000451ad1754406a7d5e02bdd08","nTx":3932,"previousblockhash":"000000000000000000010550de6754269ccb5adeed388581cfc84f5aea6f45a1","nextblockhash":"0000000000000000000271ea86cffc855dc61554ed66b3b824d6e9f7778b5ce9","strippedsize":797005,"size":1601732,"weight":3992747,"tx":
#hash":"000000000000000000044b32a02685122ddef6a1a54990a7f0883577ae67128e
version="22684000"
prevhash="000000000000000000010550de6754269ccb5adeed388581cfc84f5aea6f45a1"
merkle_root="97cbf0be2eb628cd1548d3b755f0e04b0fe4f06c15b4882ea90b7a2ae93728c0"
# "time":1681074323,"mediantime":1681068560,"nonce":3518743859,"bits":"1705e0b2"
nbits="1705e0b2"
ntime="1681074323"
nonce="3518743859"
blockheader = version + prevhash + merkle_root + nbits + ntime + nonce +\
            '000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000'
      
# print('blockheader:\n{}\n'.format(blockheader))
      
hash = hashlib.sha256(hashlib.sha256(binascii.unhexlify(blockheader)).digest()).digest()
hash = binascii.hexlify(hash).decode()
print('hash: {}'.format(hash))

Edit:
I used this link for the node:
https://api.blockchair.com/bitcoin/raw/block/000000000000000000044b32a02685122ddef6a1a54990a7f0883577ae67128e
ymgve2
Full Member
***
Offline Offline

Activity: 161
Merit: 230


View Profile
April 10, 2023, 09:35:52 PM
Last edit: April 10, 2023, 09:53:11 PM by ymgve2
Merited by ABCbits (3), NotATether (2), odolvlobo (1), Sha256explorer (1)
 #2

Well, mainly that is absolutely not a valid block header you're building.

Time and nonce are in decimal format when they should be hex and you add some garbage on the end after the nonce which is not part of Bitcoin. And every single value has the wrong endianness. Literally every single piece of your block header is wrong. Whoever made that original code you linked have no idea what they're doing.

edit: Here's the actual raw data for the block header:
00406822a1456fea5a4fc8cf818538edde5acb9c265467de500501000000000000000000c02837e 92a7a0ba92e88b4156cf0e40f4be0f055b7d34815cd28b62ebef0cb9793283364b2e0051733c5bb d1

breaking it down (note all are lowest significant byte first (LSB) and might "seem" reversed from what you expect):
00406822 - version
a1456fea5a4fc8cf818538edde5acb9c265467de500501000000000000000000 - prevhash
c02837e92a7a0ba92e88b4156cf0e40f4be0f055b7d34815cd28b62ebef0cb97 - merkle root
93283364 - timestamp
b2e00517 - nbits
33c5bbd1 - nonce
odolvlobo
Legendary
*
Offline Offline

Activity: 4494
Merit: 3400



View Profile
April 10, 2023, 10:11:09 PM
Merited by ABCbits (1)
 #3

Another potential problem is that each field has a fixed size. So, when you generate the hex for the values, you need to ensure that leading 0s are included.

Join an anti-signature campaign: Click ignore on the members of signature campaigns.
PGP Fingerprint: 6B6BC26599EC24EF7E29A405EAF050539D0B2925 Signing address: 13GAVJo8YaAuenj6keiEykwxWUZ7jMoSLt
witcher_sense
Legendary
*
Offline Offline

Activity: 2450
Merit: 4415


🔐BitcoinMessage.Tools🔑


View Profile WWW
April 11, 2023, 08:22:09 AM
 #4

The key thing to realize here is that all hashes are stored as big-endian hexadecimal numbers, and all numbers (such as version, time, etc.) are in little-endian by default. When you download raw block data, you should convert both the Merkle root hash and the previous block hash back to little-endian and only then use them for calculation. All other decimal values should be converted to hexadecimal representation, but endianness should be preserved. When you calculate the final hash, you need to convert it to hexadecimal and swap the endianness, so that all trailing zeroes become leading. If you are unsure which value should be converted and which do not, it is always a good idea to consult this page: https://en.bitcoin.it/wiki/Block_hashing_algorithm

█▀▀▀











█▄▄▄
▀▀▀▀▀▀▀▀▀▀▀
e
▄▄▄▄▄▄▄▄▄▄▄
█████████████
████████████▄███
██▐███████▄█████▀
█████████▄████▀
███▐████▄███▀
████▐██████▀
█████▀█████
███████████▄
████████████▄
██▄█████▀█████▄
▄█████████▀█████▀
███████████▀██▀
████▀█████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
c.h.
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▀▀▀█











▄▄▄█
▄██████▄▄▄
█████████████▄▄
███████████████
███████████████
███████████████
███████████████
███░░█████████
███▌▐█████████
█████████████
███████████▀
██████████▀
████████▀
▀██▀▀
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!