Menu
Bitcoin Intermediate 12 min read

Bitcoin Blocks

Understanding Bitcoin block structure for agents. Headers, merkle trees, proof-of-work, and block propagation.

blocks headers merkle-tree proof-of-work

Bitcoin Blocks

Blocks are the fundamental unit of Bitcoin’s blockchain. Each block contains a batch of transactions and links to the previous block, forming an immutable chain.

Block Structure

┌─────────────────────────────────────────────────────────┐
│ Block Header (80 bytes)                                 │
│   ├── Version (4 bytes)                                 │
│   ├── Previous Block Hash (32 bytes)                    │
│   ├── Merkle Root (32 bytes)                            │
│   ├── Timestamp (4 bytes)                               │
│   ├── Difficulty Target (4 bytes)                       │
│   └── Nonce (4 bytes)                                   │
├─────────────────────────────────────────────────────────┤
│ Transaction Count (varint)                              │
├─────────────────────────────────────────────────────────┤
│ Transactions                                            │
│   ├── Coinbase Transaction                              │
│   ├── Transaction 1                                     │
│   ├── Transaction 2                                     │
│   └── ...                                               │
└─────────────────────────────────────────────────────────┘

Block Header Fields

FieldSizeDescription
Version4 bytesBlock version for protocol upgrades
Previous Hash32 bytesSHA256d of previous block header
Merkle Root32 bytesRoot of transaction merkle tree
Timestamp4 bytesUnix timestamp (seconds)
Bits4 bytesCompact difficulty target
Nonce4 bytesValue miners adjust for PoW

Version Field

Version bits signal protocol support:
- Bit 0: Reserved
- Bit 1: BIP-341 (Taproot) signaling
- Bits 2-28: Available for future soft forks

Block Hash

The block hash is computed by double-SHA256 of the 80-byte header:

import hashlib

def block_hash(header_bytes):
    return hashlib.sha256(
        hashlib.sha256(header_bytes).digest()
    ).digest()[::-1]  # Reverse for display

Note: Block hashes are displayed in reverse byte order by convention.

Merkle Tree

Transactions are organized in a binary hash tree:

                    Merkle Root
                   /           \
               H(AB)           H(CD)
              /     \         /     \
           H(A)    H(B)    H(C)    H(D)
            |       |       |       |
          Tx A    Tx B    Tx C    Tx D

Merkle Proof

Agents can verify transaction inclusion without downloading the full block:

def verify_merkle_proof(tx_hash, proof, merkle_root):
    current = tx_hash
    for (sibling, is_left) in proof:
        if is_left:
            current = sha256d(sibling + current)
        else:
            current = sha256d(current + sibling)
    return current == merkle_root

Proof of Work

Mining requires finding a nonce such that the block hash is below the target:

hash(header) < target

Difficulty Calculation

# Target from compact "bits" format
def bits_to_target(bits):
    exponent = bits >> 24
    mantissa = bits & 0x007fffff
    return mantissa * (256 ** (exponent - 3))

# Difficulty relative to genesis
def difficulty(bits):
    genesis_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
    return genesis_target / bits_to_target(bits)

Difficulty Adjustment

Every 2016 blocks (~2 weeks), difficulty adjusts:

new_target = old_target * (actual_time / expected_time)
# Clamped to max 4x increase or 4x decrease

Block Size and Weight

Legacy Size Limit

Pre-SegWit: 1 MB maximum block size

SegWit Weight

Post-SegWit uses “weight units”:

weight = base_size * 3 + total_size
max_weight = 4,000,000 WU

Effectively allows ~2-4 MB blocks depending on transaction types.

Coinbase Transaction

First transaction in every block:

  • No inputs (creates new bitcoins)
  • Output includes block reward + fees
  • Contains arbitrary data in coinbase field
{
  "txid": "...",
  "vin": [{
    "coinbase": "03a5b8170456...",  // Block height + arbitrary data
    "sequence": 4294967295
  }],
  "vout": [{
    "value": 3.125,  // Current block reward
    "scriptPubKey": {...}
  }]
}

Block Reward Schedule

EraBlock RangeReward
10 - 209,99950 BTC
2210,000 - 419,99925 BTC
3420,000 - 629,99912.5 BTC
4630,000 - 839,9996.25 BTC
5840,000+3.125 BTC

Block Timing

  • Target interval: 10 minutes average
  • Adjustment period: 2016 blocks (~2 weeks)
  • Variance: Individual blocks can take seconds to hours

Timestamp Rules

  • Must be greater than median of last 11 blocks
  • Must be less than network time + 2 hours

API Access

Get Block by Hash

curl https://mempool.space/api/block/{hash}

Get Block by Height

# Get hash at height
curl https://mempool.space/api/block-height/{height}

# Then get block
curl https://mempool.space/api/block/{hash}

Get Latest Block

curl https://mempool.space/api/blocks/tip/hash
curl https://mempool.space/api/blocks/tip/height

Get Block Transactions

curl https://mempool.space/api/block/{hash}/txs

Agent Considerations

Block Confirmation

ConfirmationsSecurity LevelUse Case
0UnconfirmedSmall, trusted
1TentativeLow value
3ReasonableMedium value
6StandardHigh value
100Coinbase maturityMining rewards

Monitoring New Blocks

import websocket
import json

def on_message(ws, message):
    data = json.loads(message)
    if 'block' in data:
        print(f"New block: {data['block']['height']}")

ws = websocket.WebSocketApp(
    "wss://mempool.space/api/v1/ws",
    on_message=on_message
)
ws.send(json.dumps({"action": "want", "data": ["blocks"]}))
ws.run_forever()

Reorg Handling

Blocks can be orphaned during chain reorganizations:

def handle_reorg(old_tip, new_tip):
    # Find common ancestor
    # Revert transactions from orphaned blocks
    # Apply transactions from new chain
    pass

Best practice: Wait for confirmations before considering transactions final.


Machine-Readable Summary

{
  "topic": "bitcoin-blocks",
  "header_size": 80,
  "max_weight": 4000000,
  "target_interval_seconds": 600,
  "adjustment_period_blocks": 2016,
  "current_reward_btc": 3.125,
  "apis": {
    "block": "https://mempool.space/api/block/{hash}",
    "height": "https://mempool.space/api/block-height/{height}",
    "tip": "https://mempool.space/api/blocks/tip/hash"
  }
}