Understanding Bitcoin Halving in Code
March 22nd, 2024

As is well known, Bitcoin halving is scheduled in end of April 2024. But most people only are aware of Bitcoin halving every four years. They may not know the reason behind the for-year circle or why new Bitcoin blocks are minted every 10 minutes. The article will delve into the reasons behind the 10-minute interval for new Bitcoin blocks minting and and the occurrence of Bitcoin halving every four years. Bitcoin Github repo: https://github.com/bitcoin/bitcoin

How did the 10-minute interval for minting new Bitcoin blocks come about ?

We can find the following code snippet in the src/pow.cpp file of Bitcoin Github repo:

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
	if (params.fPowNoRetargeting)
		return pindexLast->nBits;
		
	// Limit adjustment step
	int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
	if (nActualTimespan < params.nPowTargetTimespan/4)
		nActualTimespan = params.nPowTargetTimespan/4;
	if (nActualTimespan > params.nPowTargetTimespan*4)
		nActualTimespan = params.nPowTargetTimespan*4;
		
	// Retarget
	const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
	arith_uint256 bnNew;
	bnNew.SetCompact(pindexLast->nBits);
	bnNew *= nActualTimespan;
	bnNew /= params.nPowTargetTimespan;
	if (bnNew > bnPowLimit)
		bnNew = bnPowLimit;
	return bnNew.GetCompact();
}

The main function of the code snippet above is calculate next block work difficulty. params.fPowNoRetargeting is false in mainnet and true in testnet. pindexLast->nBits refers to the number of trimmed-zero bits in the block hash. The lower the value of bits, the greater the difficulty in mining.

The main function of the code snippet above is calculate next block work difficulty. params.fPowNoRetargeting is false in mainnet and true in testnet. pindexLast->nBits refers to the number of trimmed-zero bits in the block hash. The lower the value of bits, the greater the difficulty in mining.

Calculate actual timespan

The code under comment Limit adjustment step is used to calculate actual timespan. pindexLast->GetBlockTime() is the time of last block. nFirstBlockTime is the time of first block height in timespan. The calculation nFirstBlockTime is as follows. nFirstBlockTime = time of nHeightFirst nHeightFirst = lastHeight - nPowTargetTimespan / nPowTargetSpacing nPowTargetTimespan = 14 * 24 * 60 * 60, which is equivalent to two weeks. nPowTargetSpacing = 10 * 60, which is equivalent to 10 minutes. Thus, it can be concluded. nPowTargetTimespan / nPowTargetSpacing is the block height increase. nHeightFirst is the block height two weeks ago. So nActualTimespan is actual timespan for minting blocks over a two-week period. But nActualTimespan is limited to [nPowTargetTimespan / 4, nPowTargetTimespan * 4]. This represents a maximum increase in mining difficulty of 4*2=8 times or a decrease to 1/4/2=1/8 of the mining difficulty.

Retarget mining difficulty

The code under comment Retarget is used to calculate new mining difficulty. bnNew is next block mining difficulty. bnNew is initialized to pindexLast->nBits, which is the mining difficulty of last block. bnNew = bnNew * nActualTimespan / nPowTargetTimespan means change the mining difficulty of next block. If nActualTimespan is more than nPowTargetTimespan, the mining difficulty will decrease; Reversely, if nActualTimespan is less than nPowTargetTimespan, the mining difficulty will increase.

Conclusion

Based on the algorithm above, Bitcoin adjusts its mining difficulty by comparing the actual time taken to mine blocks over a two-week period with the target mining time. This adjustment ensures that Bitcoin blocks are minted approximately every 10 minutes.

The code for Bitcoin halving

We can find the following code snippet in the src/validation.cpp file of Bitcoin Github repo:

CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
{
	int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
	// Force block reward to zero when right shift is undefined.
	if (halvings >= 64)
		return 0;
	CAmount nSubsidy = 50 * COIN;
	// Subsidy is cut in half every 210,000 blocks which will occur approximately every 4 years.
	nSubsidy >>= halvings;
	return nSubsidy;
}

Based on consensusParams.nSubsidyHalvingInterval=210000 and 10 minutes for mining Bitcoin blocks, we have the Bitcoin halving time interval is 210000 * 10min = 2100000 mins = 1458 days = 4 years。 From the function code, the reward of Bitcoin block mining will be halved every time the Bitcoin block height increases by 210,000. After 64 halvings, the reward for mining Bitcoin block will reach zero, and miners will only receive transaction fees for mining Bitcoin blocks.

After four halving events, starting with the original reward of 50 BTC, the reward for mining a block decreases to 3.125 BTC.

Subscribe to zhongxuqi
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from zhongxuqi

Skeleton

Skeleton

Skeleton