Image credit: cointelegraph
Bitcoin is decentralized meaning there’s no central Authority like the Federal Reserve or Central Bank that controls its issuance and stability. The proof-of-work method of general consensus implemented suffices for some key functions.
Proof-of-work as the name suggests involves providing a proof that you have done a piece of work (solved a computational problem), the process of doing this work is called mining. It’s analogous to the conventional mining process because new coins are discovered in the process and awarded to whoever first finds a solution to the computational problem. Each node involved in mining is a miner.
The miners verify transactions, create blocks and add these blocks to the bitcoin blockchain. With this they prevent double spending and secure the bitcoin blockchain. The new coins mined and the transaction fees serve as an economic incentive. Anyone can mine and get rewarded it isn’t restricted to any group except maybe your country or state laws forbid you from mining.
To mine you’ll need the bitcoin client software, Bitcoin Core and mining hardware, Application Specific Integrated Circuit (ASIC). The hardware helps to solve the computational problem which involves lots of hashing. Hashing is a one way encryption (asymmetric cryptography) which generates a new string (output called hash, digest or fingerprint) from any string input. It’s called asymmetric because the output cannot be used to generate the original input. A small change in the string input causes the hash function to produce a completely different hash. ASICs used for bitcoin mining are specifically created to do SHA256 (the hash function used in bitcoin) hashing faster with less electricity consumption.
Calculating the Hash.
To calculate the hash we need a string, the Block Header. The string is formed using six arguments concatenated together. They are:
1. Version Number
This is the version of the block the miner wants to add to the blockchain, currently there are 4 versions. Its 4 bytes in size.
2. Previous Block Hash
All blocks being mined have a block before them except the genesis block, the first block in the blockchain. As the name implies it’s a chain of blocks, each new block to be mined includes the hash of the just mined block into itself this helps to form the chain that links each block to its adjacent mates and down to the genesis block or to the latest block on the chain. All this is possible because each block contains a summary of the one before it. Its 32 bytes (256 bits) in size.
3. Merkle Root Hash
Merkle tree, image credit: hacker noon
Transactions must be included in the block. Each block contains lots of transactions identified with a “Transaction Id” (TxId). Calculating the hash of each transaction and adding it to a block would take up space. Then comes in the Merkle Tree which makes it possible to add a single hash, merkle root hash representing all the transactions.
The merkle tree has leaves representing each transaction. Each transaction is hashed with an adjacent transaction and their parent hash is hashed with another transaction or parent hash. This goes on until a single hash of all transactions remains. The hash is called the root of the merkle tree and is what is included in the block.
Its 32 bytes (256 bits) in size.
The time in which the miner begins to mine the block is also included. The time is included in epoch or Unix time format. This is the number of seconds since January 1st, 1970. You can convert from the normal GMT time format to epoch time here.
Its 4 bytes in size.
The bits gives us the target in a compact format. The target is also known as the difficulty target, the hash of the block header must be less than this target. The bits is 4 bytes in size meaning it can be represented by 8 hexadecimal values. The first 2 hex values represent the “exponent” and the remaining six represent the “coefficient”. The coefficient is represented in base 256.
target = coefficient * 256^(exponent -3)
This little guy which is 4 bytes (32 bits) long is the usually the cause of competition in mining. The block header when calculated is first started with the nonce at its lowest value, 0. The miner can choose any value he wants to start from. The nonce can hold 232 possible values.
When the block header is first calculated and the hash is greater than the target the nonce is incremented and the hash is calculated again. This is done until the block header hash is less than the target which means the miner has solved the problem or until nonce wraps or overflows.
When all possible values of the nonce field have been tried, an extra field can be added to the coinbase transaction. The coinbase transaction also called generation transaction is first transaction included in the block and added to the merkle root. It pays the block reward (new coins generated) to the address specified by the miner. The extra nonce field is added here and when it is incremented once which changes the merkle root hash, the nonce field is made to pass through all its possible values again to achieve a value less than the target. The nonce and extra nonce values work like the second and minute hands of a wall clock respectively.
The following illustrations will contain python code snippets following the texts. Don’t worry you don’t need to know python to understand them.
Let’s use block 502871 to play around a little bit. You can find the arguments here. Blockchain explorers are sites that are used to surf the blockchain analogous to the internet explorer used to surf the internet. They show information about every transaction, address or block on the blockchain.
Block 502781 mining data well illustrated by blockchain.com explorer
The parameters are then concatenated (added together) in this order to form the block header. Attention must be paid to the order else the hash will change.
Block header = version number + previous block hash + merkle root Hash + time + nonce
header = version + str(prevBlockHash) + str(merkleRoot) + time + bits + nonce
“00000020” + “66720b99e07d284bd4fe67ff8c49a5db1dd8514fcdab61000000000000000000” + “7829844f4c3a41a537b3131ca992643eaa9d093b2383e4cdc060ad7dc5481187” + “c7f5d74d” + “c1910018” + “42a14695”
The block header is now hashed to produce the block hash.
Header hash= Sha256(sha256(blockheader))
headerHash = hashlib.sha256(hashlib.sha256(headerByte).digest()).digest()
Header hash= Sha256(sha256(“0000002066720b99e07d284bd4fe67ff8c49a5db1dd8514fcdab610000000000000000007829844f4c3a41a537b3131ca992643eaa9d093b2383e4cdc060ad7dc5481187c7f5d74dc191001842a14695”))
The miner then compares this hash with the target and if it is less than the target he is good to go else he increments the nonce value and hashes the block header again.
Let’s note that the “header hash” will produce the block hash as seen on the block explorer because we are using the nonce of an already finished block. But trust me that miner sure utilized a huge amount of resources to prove he genuinely mined that block.
You can check out the full python code on my github page. Try out any block you want with the code, you can change the standard time given in the block explorers to epoch time here. Or you can get the big heels of the game (ASICs) and mine for real or join a mining pool could be a cloud or local mining pool.
Mining is a concept that has made decentralization possible since consensus can be made by network participants with it. It might seem hard to wrap your head around at first, don’t worry we were all in the same shoes once you will come to understand it as time goes by.
Please don’t forget to clap and if you find anything contradictory or you want to say something don’t forget to leave a comment.