With all the hype around blockchain, cryptocurrencies, NFTs etc, you probably hear a lot about mining - in terms of how profitable this is, or how miners compete with each other to earn bitcoin (or any other crypto where proof-of-work concept is used).

But have you ever wondered what is mining process exactly? Further on I will use the example of crypto pioneer - Bitcoin. First allow me to quote a definition of bitcoin mining from www.bitcoin.org FAQ section:

Mining is the process of spending computing power to process transactions, secure the network, and keep everyone in the system synchronized together. It can be perceived like the Bitcoin data center except that it has been designed to be fully decentralized with miners operating in all countries and no individual having control over the network. This process is referred to as “mining” as an analogy to gold mining because it is also a temporary mechanism used to issue new bitcoins. Unlike gold mining, however, Bitcoin mining provides a reward in exchange for useful services required to operate a secure payment network. Mining will still be required after the last bitcoin is issued.

Sounds quite confusing and high-level, doesn’t it? Processing transactions, decentralization, and even analogy to gold mining has been used. The key point here is to understand that the minig process is important in order to keep the integrity of the blockchain in terms verifying transactions, keeping balances and controlling emission of new bitcoins. To put it very simply - if there were no miners and a process of providing them with incentive to keep track about all the transactions, anybody could just issue themselves any amount of crypto they would like.

Note: Forgive me for oversimplyfying. It is intentional in order to explain the process to wider audience. And in fact the process of bitcoin mining is indeed very simple as you will soon discover below.

Ok, but how does bitcoin mining actually work?

This is where it gets very interesting, bear with me for a while. Let me once again quote a FAQ section of www.bitcoin.org:

For new transactions to be confirmed, they need to be included in a block along with a mathematical proof of work. Such proofs are very hard to generate because there is no way to create them other than by trying billions of calculations per second. This requires miners to perform these calculations before their blocks are accepted by the network and before they are rewarded. As more people start to mine, the difficulty of finding valid blocks is automatically increased by the network to ensure that the average time to find a block remains equal to 10 minutes. As a result, mining is a very competitive business where no individual miner can control what is included in the block chain.

Now it is a good time to pause for a moment and clarify on how does the bitcoin block look look like. Here is a simple version of what values are always included in the block (among others, but we are skipping them for this demonstration to keep things simple):

Hash of previous block Transactions Timestamp Nonce value
0000…8a46 List of transactions Oct 18, 2022, 12:01:22 PM 1,322,084,641
  • Hash value of previous block is actually a sha256 hash value, for example 00000000000000000002504f321ef8005506869b58d41fde1c0fb908dabd8a46. I will not go that deep into hash functions, but the only thing you need to know about sha256 at this point, is that the function can take any input and based on this input it produces the hash of 256 bits long.
  • Transactions includes a list of transactions that will be added to the block. Transaction #1 is a reward transaction to the miner who will find (=mine) the block.
  • Timestamp is time when the block was mined, however definition of time is very relative in bitcoin as timestamps might be different among the miners who operate worldwide (because of latency etc).
  • Nonce value a random number that is added to a block. This is actually what miners are changing when trying to mine a block = solve a hash puzzle.

Ok, so now when we now how the bitcoin block looks like, let us figure out what are miners calculating in older to get the incentive of finding the new block. Let us once again look at www.bitcoin.org for explanation:

The proof of work is also designed to depend on the previous block to force a chronological order in the block chain. This makes it exponentially difficult to reverse previous transactions because this requires the recalculation of the proofs of work of all the subsequent blocks. When two blocks are found at the same time, miners work on the first block they receive and switch to the longest chain of blocks as soon as the next block is found. This allows mining to secure and maintain a global consensus based on processing power.

Bitcoin miners are neither able to cheat by increasing their own reward nor process fraudulent transactions that could corrupt the Bitcoin network because all Bitcoin nodes would reject any block that contains invalid data as per the rules of the Bitcoin protocol. Consequently, the network remains secure even if not all Bitcoin miners can be trusted.

Ok, this explanation is good, but once again very high-level. Basically all that miners are doing on a technical level is forming a new block by taking the hash value of last block, adding the some of the pending transactions (people sending crypto to each other, buying crypto on exchanges etc) + adding a random numeric value. Then the hash value of new block is calculated and if it matches the target

I probably have lost you here, let me try to explain the process using a short Python program I wrote. (You can find it on my Github and test for yourself if you wish).

Let’s code our own bitcoin mining simulator on Python

First we will import sha256 and time module that will be needed.

from time import time
from hashlib import sha256

Next we will compile our block and define variables:

max_nonce = 100000000000
network_difficulty = 7  
transactions = "Pete -> John 50 BTC"  
prev_block_hash = '0000008fd16ac7984995098fdfdd5a705154773b18aa207ce92dd68b0a81fadf'
  • max_nonce refers to maximum nonce value.
  • network_difficulty is the difficulty of the network which in bitcoin is measured simply by the amount of prefix zeros in the hash value. Yes, you read it currently basically all the miners are doing is trying to calculate the new hash value that starts with certain amount of zeros! Remember this next time when you hear about how “miners are competing against each other by solving the complex mathematical problem” and I guarantee that you will have a grin on your face :)
  • transactions here we can add a list a transaction. Normally a bitcoin block has a few thousand of them. But for illustrative perspective we will have only 1 transaction where Pete is sending John 50 BTC.
  • prev_block_hash is a hash value of previous block.

Next in my code I have defined two functions the first one simply used to calculate the hash value of the new composed block:

def sha256_encode(block):
    return sha256(block.encode('utf-8')).hexdigest()

And the next one is where actual “mining is taking place”.

def mine_bitcoin(block_number, transactions, previous_hash, prefix_zeros):
    prefix_string = '0'*prefix_zeros

    for nonce in range (max_nonce):
       block = str(block_number) + transactions + previous_hash + str(nonce)
       new_hash = sha256_encode(block)

        if new_hash.startswith(prefix_string):
           print("[+++] Yahoo! I have mined some bitcoin with nonce value: "+str(nonce))
           return new_hash

    raise BaseException("[-] Could not find matching hash. Tried "+max_nonce+" times.")

As you can see the function takes block_number (forgot to mention it previously, but each block of course has its own running number), transactions (as we specified above), previous hash value and difficulty (amount of prefix zeros).

Next all we need to do is just run our program as follows:

if __name__ == "__main__":
   start_time = time()
   print("[+] Mining started ...")
   
   next_block_hash = mine_bitcoin(14354, transactions, prev_block_hash, network_difficulty)
   elapsed_time = str(time() - start_time)
   
   print("... mining ended. Time consumed: "+elapsed_time+" seconds.")
   print("New hash: "+next_block_hash)

We call our mine_bitcoin function providing a block number, transactions (only one in our case), previous block hash and network difficulty or amount of prefix zeros, which in our case is 7. I do not recommend to try more than 8-9 depending on your hardware. Current bitcoin network difficulty is 19 prefix zeros which makes it almost impossible to find next block for a single miner in the next hundreds of years or so.

Finally, let’s run our program:

evgeni@ubuntu-LTS:~/python-projects/bitcoin-mining$ python3 bitcoin-mining.py 
[+] Mining started ...
[+++] Yahoo! I have mined some bitcoin with nonce value: 285581249
... mining ended. Time consumed: 370.6464204788208 seconds.
New hash: 0000000fe980d38ed49b6fb1144a6ec9aec43580c8db3c5151afad5e9ad50914

As you can see, our mining process took us a little bit over 6 minutes. During this time we have tried 285581249 different nonce values to finally find a block, which hash starts with 7 zeros (new hash value: 0000000fe980d38ed49b6fb1144a6ec9aec43580c8db3c5151afad5e9ad50914).

This code can be found on my Github: https://github.com/evgeni-semenov/bitcoin-mining

Is it worth it?

You have now a good idea about how proof-of-work consensus mechanism works in Bitcoin blockchain - an enormous amount of trial and error calculations to find next block that has value starts with 19 or so prefix zeros.

However, this mechanism is crucial for Bitcoin’s network integrity and is crucial for its decentralized operation without the high authority party that validates all the transactions (similar to fiscal authorities and central banks in the traditional money).

Proof-of-work major problem is related to sustainability. A huge amount of energy is wasted on these calculation, there is a website that monitors Bitcoin Energy Consumption Index and at the moment of writing this post the total network consumption of 130,88 TWh annually. The consumption has dropped from its peak of over 200 TWh in the Spring of 2022, but still it is comparable to the power consumption of Argentina. Carbon footprint as well as electronic waste (broken, replaced components etc) is also huge. This is a topic of constant debate and urge to switch from proof-of-work consensus mechanisms to something else (like proof-of-stake, for example). But this switch, among other major changes in the protocol, requires the consensus within the majority of miners, that currently looks to be far from achievable in Bitcoin. However, things might change as Ethereum switched to use proof-of-stake recently.

Further reading and studying

If you want to dive deeper into bitcoin and cryptocurrency technologies, I highly recommend a book by Arvind Narayanan, Joseph Bonneau, Edward Felten, Andrew Miller, and Steven Goldfeder called “Bitcoin and Cryptocurrency Technologies: A Comprehensive Introduction”. There is also a free online course available on Coursera based on this book.