TeachMeBitcoin

Building a Block Subsidy and Halving Simulator in Pure Python

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

Building a Block Subsidy and Halving Simulator in Pure Python

To understand how the Bitcoin consensus protocol enforces the 33-epoch halving schedule and calculates the exact final coin supply of $20,999,999.9769\text{ BTC}$, we can implement a custom Reward and Halving Simulator in Python.

By writing this simulator from scratch using only Python's standard libraries, we can model how the C++ consensus code executes bitwise right-shift divisions and track the total circulating supply down to the individual satoshi.


1. The Block Subsidy Simulator Source Code

Save the following standard-library Python script as python_reward_simulator.py.

class BitcoinRewardSimulator:
 def __init__(self):
 self.blocks_per_epoch = 210000
 # Starting block subsidy: 50 BTC in Satoshis (5,000,000,000 Satoshis)
 self.initial_subsidy_sats = 50 * 100000000

 def calculate_block_subsidy(self, height: int) -> int:
 """
 Calculates the maximum allowable block subsidy in satoshis for a given block height.
 Emulates Bitcoin Core's C++ bitwise right-shift operator (>>).
 """
 # Calculate how many halvings have occurred
 halvings = height // self.blocks_per_epoch

 # In C++, shifting a 64-bit signed integer by 64 or more positions is undefined or 0
 if halvings >= 64:
 return 0

 # Perform C++ style bitwise right-shift division
 # This divides the initial reward by 2^halvings and truncates decimals
 return self.initial_subsidy_sats >> halvings

 def run_supply_simulation(self) -> dict:
 """
 Simulates the entire 33-epoch issuance schedule.
 Calculates the exact total coin supply in Satoshis.
 """
 total_supply_sats = 0
 epoch_details = []

 # Iterate through the 33 valid epochs (Epoch 0 to 32)
 # Epoch 33 drops the reward to 0 satoshis.
 for epoch in range(34):
 # Calculate height at the start of this epoch
 start_height = epoch * self.blocks_per_epoch

 # Query subsidy for a block in this epoch
 subsidy_sats = self.calculate_block_subsidy(start_height)

 # Total blocks mined in this epoch is blocks_per_epoch (210,000)
 blocks_mined = self.blocks_per_epoch

 # Total coins created in this epoch
 epoch_mint = subsidy_sats * blocks_mined
 total_supply_sats += epoch_mint

 epoch_details.append({
 "epoch": epoch,
 "start_height": start_height,
 "subsidy_sats": subsidy_sats,
 "subsidy_btc": subsidy_sats / 1e8,
 "epoch_mint_btc": epoch_mint / 1e8,
 "total_supply_btc": total_supply_sats / 1e8
 })

 # If the subsidy reaches 0, we can stop
 if subsidy_sats == 0:
 break

 return {
 "total_supply_sats": total_supply_sats,
 "total_supply_btc": total_supply_sats / 1e8,
 "epochs": epoch_details
 }

if __name__ == "__main__":
 simulator = BitcoinRewardSimulator()

 print("=== Block Subsidy Query ===")
 test_heights = [100, 210000, 420000, 630000, 840000, 6930000]
 for h in test_heights:
 subsidy = simulator.calculate_block_subsidy(h)
 print(f"[*] Block Height {h:,} -> Subsidy: {subsidy:,} Satoshis ({subsidy / 1e8:.8f} BTC)")

 print("\n=== Programmatic Supply Schedule Simulation ===")
 results = simulator.run_supply_simulation()

 print(f"[*] Total Circulating Supply Cap: {results['total_supply_btc']:,.8f} BTC")
 print(f"[*] Total Satoshis Created: {results['total_supply_sats']:,} Satoshis\n")

 print("=== Epoch-by-Epoch Issuance Logs ===")
 print(f"{'Epoch':<6} | {'Start Height':<12} | {'Subsidy (BTC)':<15} | {'Coins Created':<15} | {'Circulating Supply':<18}")
 print("-" * 76)
 for ep in results["epochs"][:6]: # Show first 6 epochs
 print(f"{ep['epoch']:<6} | {ep['start_height']:<12,} | {ep['subsidy_btc']:<15.8f} | {ep['epoch_mint_btc']:<15,.4f} | {ep['total_supply_btc']:<18,.4f}")

 print("...")
 # Show the final epochs where bitwise shift division hits the 0 threshold
 for ep in results["epochs"][-3:]:
 print(f"{ep['epoch']:<6} | {ep['start_height']:<12,} | {ep['subsidy_btc']:<15.8f} | {ep['epoch_mint_btc']:<15,.4f} | {ep['total_supply_btc']:<18,.4f}")

As displayed, the simulator calculates block heights, implements bitwise shift boundaries, and proves that Bitcoin's supply ends at exactly $20,999,999.9769\text{ BTC}$ inside Epoch 32.

☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!