TeachMeBitcoin

Building a Nakamoto Consensus Simulator in Pure Python

From TeachMeBitcoin, the free encyclopedia Reading time: 3 min

Building a Nakamoto Consensus Simulator in Pure Python

To visualize how the "Most Work" rule protects the network from double-spending, we can build a Consensus Race Simulator. This script simulates two competing entities: an Honest Network and an Attacker, each with a defined percentage of the total hashrate.


1. The Consensus Race Source Code

Save the following Python script as consensus_race_sim.py.

import random

class ConsensusRaceSim:
 def __init__(self, attacker_hashrate_pct: float, confirm_threshold: int):
 self.q = attacker_hashrate_pct / 100.0 # Attacker power
 self.p = 1.0 - self.q # Honest power
 self.z = confirm_threshold # Number of blocks to catch up

 def simulate_race(self):
 """
 Simulates a single race. Returns True if attacker catches up, 
 False if they fail after a reasonable number of blocks.
 """
 # Attacker starts z blocks behind
 attacker_blocks = 0
 honest_blocks = self.z

 # We cap the simulation at a high number to avoid infinite loops
 # though math says p > q will eventually converge to 0 probability.
 max_blocks = 1000

 while honest_blocks < max_blocks:
 # Roll for who finds the next block
 if random.random() < self.q:
 attacker_blocks += 1
 else:
 honest_blocks += 1

 # If attacker catches up or overtakes
 if attacker_blocks >= honest_blocks:
 return True

 return False

 def run_monte_carlo(self, trials: int = 10000):
 print(f"[*] Starting Monte Carlo Simulation...")
 print(f"[*] Attacker Hashrate: {self.q*100:.1f}%")
 print(f"[*] Honest Hashrate: {self.p*100:.1f}%")
 print(f"[*] Confirmations: {self.z}")

 successes = 0
 for _ in range(trials):
 if self.simulate_race():
 successes += 1

 prob = (successes / trials) * 100
 print(f"\n[✔] Results after {trials:,} trials:")
 print(f" └─ Attacker Successes: {successes}")
 print(f" └─ Success Probability: {prob:.4f}%")

if __name__ == "__main__":
 # Example 1: Attacker with 10% hashrate vs 6 confirmations
 sim1 = ConsensusRaceSim(attacker_hashrate_pct=10, confirm_threshold=6)
 sim1.run_monte_carlo()

 print("\n" + "="*40 + "\n")

 # Example 2: Attacker with 35% hashrate vs 6 confirmations
 sim2 = ConsensusRaceSim(attacker_hashrate_pct=35, confirm_threshold=6)
 sim2.run_monte_carlo()

️ 2. Interpreting the Results

When you run this script, you will see how sensitive the network is to the confirmation threshold:

  1. Low Hashrate Attacker (10%): Even with 10,000 trials, an attacker with only 10% hashrate will almost never catch up after 6 blocks. The probability is typically $<0.1\%$.

  2. High Hashrate Attacker (35%): An attacker with 35% hashrate has a much better chance. You will likely see a success probability around 10-15%. This is why for extremely high-value transactions, waiting for 10 or 20 confirmations is recommended.

Key Takeaways

☕ 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!