Bitcoin miners technically must find a blockhash which satisfies the requirements of the protocol. So it can be really very interesting to check a block header of an already mined block and manually calculate the hash to see what is normally verified by nodes after receiving blocks by miners. This is very useful to see if the procedure is correctly understood.
Let’s take the block of height 577316. This block has nothing special, we just use this as an example.
What we are going do to is: 1) retrieve the blockhash from the blockchain, 2) retrieve the block header and 3) calculate the blockhash from the blockheader and check if it is really matching what we expected.
The calculation of the hash is going to be performed with a little python script because we need to change formats to data. What follows has been calculated on a bitcoin core full node, which was installed on an ubuntu distribution machine.
1) first of all get the blockhash of that block with height 577316
dev@zulu:~$ bitcoin-cli getblockhash 577316
0000000000000000001d476635098d9eda148caae22965044380bb74c78ca80a
2) now get the blockhash in raw format:
dev@zulu:~$ bitcoin-cli getblockheader 0000000000000000001d476635098d9eda148caae22965044380bb74c78ca80a false
00e0ff3f59c876cb02b160123b8f6190a000525e16dda75be0fd1c0000000000000000005a025984c7e0056707e76adc8f9ebc48cb31ce129bb0eb8bc08b70451be8d82217dae55c45fb29178731e962
3) now I retrieve the same header in json format (easily human readable)
dev@zulu:~$ bitcoin-cli getblockheader 0000000000000000001d476635098d9eda148caae22965044380bb74c78ca80a
{
“hash”: “0000000000000000001d476635098d9eda148caae22965044380bb74c78ca80a”,
“confirmations”: 26175,
“height”: 577316,
“version”: 1073733632,
“versionHex”: “3fffe000”,
“merkleroot”: “22d8e81b45708bc08bebb09b12ce31cb48bc9e8fdc6ae7076705e0c78459025a”,
“time”: 1558567447,
“mediantime”: 1558565241,
“nonce”: 1659449735,
“bits”: “1729fb45”,
“difficulty”: 6704632680587.417,
“chainwork”: “000000000000000000000000000000000000000006571678a5d9043c4182dbff”,
“nTx”: 2466,
“previousblockhash”: “0000000000000000001cfde05ba7dd165e5200a090618f3b1260b102cb76c859”,
“nextblockhash”: “000000000000000000005e185f418cbf14be64002a9dc9020fd898dea724aa52”
}
4) Now we want to check that the sha256 hash of the block header is really the blockhash shown in data. So we want to calculate it ourselves. For this purpose we execute commands using python
dev@zulu:~$ python3
Python 3.6.8 (default, Jan 14 2019, 11:02:34)
>>>
a=”00e0ff3f59c876cb02b160123b8f6190a000525e16dda75be0fd1c0000000000000000005a025984c7e0056707e76adc8f9ebc48cb31ce129bb0eb8bc08b70451be8d82217dae55c45fb29178731e962″
>>> import binascii, hashlib
>>> binascii.b2a_hex(hashlib.sha256(hashlib.sha256(binascii.a2b_hex(a)).digest()).digest()[::-1])
b’0000000000000000001d476635098d9eda148caae22965044380bb74c78ca80a’
>>>
as we can see the blockhash is as expected, infact the value of calculated hash is
0000000000000000001d476635098d9eda148caae22965044380bb74c78ca80a
that matches with the blockhash from the blockchain. For making calculations we used the hashlib in python with those few lines of code. This calculation has been easy to verify because we already had a confirmed block. Infact the miner had to try many and many times billions of different header combinations (changing the nonce) and then hash the resulting header, in order to find a blockhash satisfing the rules of POW. So what we have just done is more similar to verifications done by nodes but different from what is performed by hashing machines which have to identify the correct values creating the right hash result.