Before you go, check out these stories!

Hackernoon logoHow Do Miners Mine A Block: A Proof of Work Deep Dive by@bitcoin-in-action

How Do Miners Mine A Block: A Proof of Work Deep Dive

Author profile picture

@bitcoin-in-actionBitcoin in Action

See on


We are very proud to announce that we have finally received a request from a woman!

Eli asks:

What is the Proof of work? How the miner mined a block?

The answer is not so easy!

First of all, the Proof of Work (We use to call it PoW), itโ€™s the consensus algorithm of Bitcoin protocol, and itโ€™s essential in order to validate blocks and secure the blockchain.

You can imagine the PoW like a miners race. The miners are nodes that search the solution of mathematic problem.

A miner tries to find the solution using the items block, it has to find a number less than a threshold established by the Bitcoin protocol. To find it, many test are carried out by the miner using the SHA256 algorithm. As we discuss in the article about SHA256, if the input of the function is the same, we get the same result, always. For that reason a miner uses a particular item, called nonce: its value changes randomly during the PoW in order to obtain the right solution (digestโ€™s SHA256).

When a miner finds the solution, the network (other nodes) check if it is correct: this is how the consensus works! If the nodes check the block and find the wrong, the system reject the block.

The miner will be then rewarded for his computational effort in finding the answer to the problem. This prize is called reward (which today, July 2020 itโ€™s 6,25 bitcoins for each block plus the fees of each transaction that has entered the block itself. This reward is halved every 210.000 blocks, approximately every 4 years, as explained in the Halving videoโ€Šโ€”โ€ŠCheck this video about Halving! ๐Ÿš€

The difficulty threshold is adjusted every 2016 blocks, approximately 2 weeks.

Ok, letโ€™s go to check the theory with the practice, like in our amazing book Bitcoin from Theory to practice ๐Ÿ’ช๐Ÿป

In Action

What is the Proof of work? How does the miner mine a block?

Letโ€™s use the block 1773164. Letโ€™s back its hash with the call getblockhash, and its information with getblock. We will use the sub-shell to make a single call.

$ bitcoin-cli getblock $(bitcoin-cli getblockhash 1773164)
"hash": "00000000000000eb74d096b83594d770f23d633e3a8b08813763489fbde7a0ef",
"confirmations": 2,
"strippedsize": 1704,
"size": 2722,
"weight": 7834,
"height": 1773164,
"version": 545259520,
"versionHex": "20800000",
"merkleroot": "75870dd46a503862af6fcf700be5e02e008db4521d96713bda51607ed05e2a18",
"tx": [
"time": 1592919152,
"mediantime": 1592917919,
"nonce": 3940145976,
"bits": "1a01a5f2",
"difficulty": 10178811.40698772,
"chainwork": "000000000000000000000000000000000000000000000160b51965fab057015d",
"nTx": 10,
"previousblockhash": "00000000000001249b9a4e000135acecec2dcd7385eba54639ff962f3883e861",
"nextblockhash": "0000000000000171c5c04355788d2531b349b55c6189e2e3719d2b5c82fa2026"

As you can see, the block contains some information, but not all of them are used to try to win the PoW race.

The miner had to find fewer numbers than the numbers reported in bits.

The bits is the encoded form (compressed representation) of the target of the candidate block.

The candidate block is the block that the mines use to carry out his tests and win the proof of work in order to insert it in the blockchain.

We can retrieve the current candidate block using the getblocktemplate method.

To retrieve the actual target, we can use jq in order to parse Json.

$ bitcoin-cli getblocktemplate '{"rules": ["segwit"]}'


At this time, the miner must find a number that must be below the hexadecimal just extracted.

However We are not miners. So Weโ€™ll replicate the minerโ€™s work that the miner has done on the block we have chosen.

The values the miner uses are:

Version hexPreviousblockhashmerkleroottimebitsnonce

For convenience, We use Env variables to save their value.

We Save in env variable ver, the versionhex in its little endian representation.

$ ver=`printf 20800000 | tac -rs ..| tr -d โ€˜\nโ€™`

We save in env variable prev, the previous blockhash in little endian.

$ prev=`printf 00000000000001249b9a4e000135acecec2dcd7385eba54639ff962f3883e861 | tac -rs .. | tr -d '\n'`

Save in env variable mkl, the merkle root hash in its little endian representation.

$ mkl=`printf 75870dd46a503862af6fcf700be5e02e008db4521d96713bda51607ed05e2a18 | tac -rs .. | tr -d '\n'`

Save in env variable time, the time in hexadecimal format and little endian.

$ time=`printf '%x\n' 1592919152 | tac -rs .. | tr -d '\n'`

Save in env variable bits, the bits in little endian.

$ bits=`echo 1a01a5f2 | tac -rs .. | tr -d '\n'`

Save in env variable nonce, the time in hexadecimal format and little endian.

$ nonce=`printf '%x\n' 3940145976 | tac -rs .. | tr -d '\n'`

Now, we need to concat all values and apply SHA256 twice.

$ printf $ver$prev$mkl$time$bits$nonce | xxd -r -p | sha256sum -b | xxd -r -p | sha256sum -b

and then we need to get little endian representation:

$ printf efa0e7bd9f48633781088b3a3e633df270d79435b896d074eb00000000000000 | tac -rs ..

The result obtained is the number that satisfies the difficulty of that time.

How we can be sure about that?

We Convert both the hash obtained and bits to base 10.

In order to obtain the bits in base10, itโ€™s necessary to divide it in two parts, respectively coefficient and exponent.

The current bits is:


The coefficient is 0x1a. itโ€™s represent the exponentโ€™s length
In this case 26 bytes, because 1a in base 10 is 26.

$ echo 'ibase=16; 1A' | bc

The coefficient 01a5f2 is the reminder of the bits.

We must therefore have a 52 hexadecimal character long string, including the exponent. Keep in mind, 1 byte can be represented by 2 hexadecimal characters.

We get, then:


We check that weโ€™ve written the correct length.

$ printf 01a5f20000000000000000000000000000000000000000000000 | wc -c

Excellent, letโ€™s convert it in base10 and save the value in env var BITS_10.

$ BITS_10="$(echo "obase=10; ibase=16; -u; $(echo 01a5f20000000000000000000000000000000000000000000000 | tr '[:lower:]' '[:upper:]')" |bc | sed -n 2p)"

Letโ€™s examine the result obtained:

$ echo $BITS_10

We also convert the hash obtained previously to base10 and save it in env var TARGET.

$ TARGET=โ€$(echo โ€œobase=10; ibase=16; -u; $(echo 00000000000000eb74d096b83594d770f23d633e3a8b08813763489fbde7a0ef | tr โ€˜[:lower:]โ€™ โ€˜[:upper:]โ€™)โ€ |bc | sed -n 2p)โ€

Now, $TARGET must be less than $BITS_10, which is the difficulty imposed by the protocol at that time.

$ echo โ€œ$TARGET<$BITS_10โ€|bc

YO! We get as the result 1, so true! The miner has successfully solved the mathematical problem.

How does the network replicate the result? Itโ€™s very simple, knowing the parameters, especially the nonce, verifies that the result is correct. If different values return the same results, as said in the video concerning the SHA256 (Check this article!) we are facing a kind of collision.

The result is the block hash.

With this slightly more technical article we have tried to demonstrate what the miner does to create a block, and to secure the blockchain. As you can imagine, itโ€™s a very broad topic: a few minutes are not enough to analyze every single nuance.

You can find more in our book Bitcoin from Theory to practice.

I hope I have answered your question!

See you next time! ๐ŸคŸ๐Ÿป

๐Ÿ™ GitHub:

๐Ÿ“– Book Bitcoin from theory to practice:

๐Ÿ“– Pocket Bitcoin 199 questions (Amazon):

In crypto we trust


Join Hacker Noon

Create your free account to unlock your custom reading experience.