Bitcoin (Nakamoto) Consensus Interview Questions

Bitcoin consensus algorithm interview questions covering Proof-of-Work (PoW) and Nakamoto consensus.

Q1: How does Bitcoin (Nakamoto) consensus work?

Answer:

Bitcoin uses Proof-of-Work (PoW) consensus, also known as Nakamoto consensus.

Sequence Diagram:

Overall Flow Diagram:

Individual Node Decision Diagram:

Bitcoin Consensus Process:

1. Transaction Collection:

  • Miners collect transactions from mempool
  • Select transactions (prioritize fees)
  • Create block candidate

2. Block Structure:

1Block Header:
2- Previous Block Hash
3- Merkle Root (transactions)
4- Timestamp
5- Difficulty Target
6- Nonce

3. Mining (Proof-of-Work):

  • Calculate hash: SHA256(SHA256(BlockHeader))
  • Check if hash < target difficulty
  • If not: Increment nonce, repeat
  • If yes: Block found!

4. Block Propagation:

  • Broadcast block to network
  • Other nodes validate
  • If valid: Add to chain

5. Chain Selection:

  • Always extend longest valid chain
  • Fork resolution: Longest chain wins
  • Orphaned blocks: No reward

Key Properties:

  • Security: Computational security
  • Decentralization: Anyone can mine
  • Finality: Probabilistic (6 confirmations)
  • Energy: High energy consumption

Example:

 1import hashlib
 2import time
 3
 4class BitcoinMiner:
 5    def __init__(self, difficulty_target):
 6        self.difficulty_target = difficulty_target
 7    
 8    def mine_block(self, transactions, previous_hash):
 9        # Create block
10        block = {
11            'previous_hash': previous_hash,
12            'merkle_root': self.calculate_merkle_root(transactions),
13            'timestamp': int(time.time()),
14            'nonce': 0,
15            'transactions': transactions
16        }
17        
18        # Mine (find nonce)
19        while True:
20            block['nonce'] += 1
21            block_hash = self.hash_block(block)
22            
23            if int(block_hash, 16) < self.difficulty_target:
24                return block, block_hash
25    
26    def hash_block(self, block):
27        header = (
28            block['previous_hash'] +
29            block['merkle_root'] +
30            str(block['timestamp']) +
31            str(block['nonce'])
32        )
33        return hashlib.sha256(
34            hashlib.sha256(header.encode()).digest()
35        ).hexdigest()
36    
37    def calculate_merkle_root(self, transactions):
38        # Simplified Merkle tree calculation
39        if len(transactions) == 0:
40            return "0" * 64
41        
42        # Hash all transactions
43        hashes = [hashlib.sha256(str(tx).encode()).hexdigest() 
44                  for tx in transactions]
45        
46        # Build Merkle tree
47        while len(hashes) > 1:
48            if len(hashes) % 2 == 1:
49                hashes.append(hashes[-1])  # Duplicate last if odd
50            
51            hashes = [
52                hashlib.sha256((hashes[i] + hashes[i+1]).encode()).hexdigest()
53                for i in range(0, len(hashes), 2)
54            ]
55        
56        return hashes[0]

Difficulty Adjustment:

  • Every 2016 blocks (~2 weeks)
  • Target time: 10 minutes per block
  • Adjust difficulty to maintain rate

Use Cases:

  • Bitcoin
  • Litecoin
  • Many PoW blockchains

Related Snippets