跳至主要內容
進階

Block Header

深入了解比特幣區塊頭的 80 位元組結構,包括各欄位的用途和驗證規則。

10 分鐘

區塊頭是比特幣區塊中最重要的 80 位元組數據。它包含了區塊的所有元數據, 是工作量證明(PoW)計算的目標,也是區塊雜湊值的來源。

區塊頭結構

欄位 大小 位移 說明
version 4 bytes 0 區塊版本號
prev_block 32 bytes 4 前一區塊雜湊
merkle_root 32 bytes 36 Merkle 樹根
timestamp 4 bytes 68 Unix 時間戳
bits 4 bytes 72 難度目標
nonce 4 bytes 76 隨機數

總計: 80 bytes(固定大小)

各欄位詳解

Version(版本)

// 4 bytes, little-endian
版本歷史:
- 1: 原始版本
- 2: BIP-34(區塊高度在 coinbase)
- 3: BIP-66(嚴格 DER 簽名)
- 4: BIP-65(CHECKLOCKTIMEVERIFY)

// BIP-9 版本位信號(version bits)
// 高位用於軟分叉信號
0x20000000 | signal_bits

示例: 0x20000002 表示版本 2 + 某個信號位

Previous Block Hash(前區塊雜湊)

// 32 bytes, 內部存儲為 little-endian
// 顯示時通常反轉為 big-endian

創世區塊的 prev_block:
0x0000000000000000000000000000000000000000000000000000000000000000

這個欄位將區塊連接成鏈
每個區塊都引用其父區塊的雜湊值

Merkle Root(Merkle 根)

// 32 bytes
// 區塊中所有交易 TXID 的 Merkle 樹根

計算過程:
1. 收集所有交易的 TXID
2. 兩兩配對並雜湊
3. 重複直到只剩一個雜湊值

用途:
- 驗證交易是否在區塊中(SPV 證明)
- 確保交易集合的完整性

Timestamp(時間戳)

// 4 bytes, Unix 時間戳(秒)

驗證規則:
1. 必須 > 前 11 個區塊的中位數時間(MTP)
2. 必須 < 節點時間 + 2 小時

用途:
- 難度調整計算
- 時間鎖(nLockTime, CSV)
- 大約表示區塊產生時間

注意: 時間戳不保證精確,礦工可在一定範圍內調整

Bits(難度目標)

// 4 bytes, 緊湊格式的難度目標

格式: [exponent (1 byte)][coefficient (3 bytes)]

target = coefficient × 256^(exponent - 3)

示例: 0x1d00ffff(創世區塊)
exponent = 0x1d = 29
coefficient = 0x00ffff
target = 0x00ffff × 256^26
      = 0x00000000ffff0000...0000 (很大的數)

區塊雜湊必須 < target 才有效

Nonce(隨機數)

// 4 bytes, 礦工可自由調整

挖礦過程:
1. 組裝區塊頭
2. 嘗試不同的 nonce 值
3. 計算 SHA256(SHA256(header))
4. 檢查結果是否 < target
5. 如果不是,改變 nonce 重試

範圍: 0 到 4,294,967,295 (2^32 - 1)

當 nonce 空間耗盡,礦工會改變:
- coinbase 的 extraNonce
- 時間戳(在允許範圍內)

區塊雜湊計算

import hashlib

def calculate_block_hash(header_bytes):
    """計算區塊雜湊(雙 SHA-256)"""
    first_hash = hashlib.sha256(header_bytes).digest()
    second_hash = hashlib.sha256(first_hash).digest()
    # 反轉為 big-endian 顯示
    return second_hash[::-1].hex()

# 區塊頭序列化
def serialize_header(version, prev_block, merkle_root,
                     timestamp, bits, nonce):
    header = b''
    header += version.to_bytes(4, 'little')
    header += bytes.fromhex(prev_block)[::-1]  # 反轉
    header += bytes.fromhex(merkle_root)[::-1]  # 反轉
    header += timestamp.to_bytes(4, 'little')
    header += bits.to_bytes(4, 'little')
    header += nonce.to_bytes(4, 'little')
    return header  # 80 bytes

RPC 查詢

# 獲取區塊頭
bitcoin-cli getblockheader <blockhash>
{
  "hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
  "confirmations": 850000,
  "height": 0,
  "version": 1,
  "versionHex": "00000001",
  "merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  "time": 1231006505,
  "mediantime": 1231006505,
  "nonce": 2083236893,
  "bits": "1d00ffff",
  "difficulty": 1,
  "chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
  "nTx": 1,
  "previousblockhash": null,
  "nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
}

# 獲取原始區塊頭(hex)
bitcoin-cli getblockheader <blockhash> false

創世區塊頭

創世區塊頭(hex):
01000000  // version = 1
00000000000000000000000000000000
00000000000000000000000000000000  // prev_block (全零)
3ba3edfd7a7b12b27ac72c3e67768f61
7fc81bc3888a51323a9fb8aa4b1e5e4a  // merkle_root
29ab5f49  // timestamp = 1231006505 (2009-01-03 18:15:05)
ffff001d  // bits = 0x1d00ffff
1dac2b7c  // nonce = 2083236893

區塊雜湊:
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f

驗證規則

  • PoW 驗證:block_hash < target(從 bits 計算)
  • 時間戳:必須在 MTP 和當前時間+2h 之間
  • 版本:必須符合當前啟用的 BIP 要求
  • Merkle Root:必須與區塊交易匹配
  • Previous Block:必須引用有效的已知區塊

區塊頭在 SPV 中的應用

輕客戶端只需下載區塊頭(80 bytes/block)即可驗證最長鏈。 完整區塊鏈的所有區塊頭約需 60 MB(截至 2024 年)。

// SPV 驗證流程
1. 下載所有區塊頭
2. 驗證每個區塊頭的 PoW
3. 驗證區塊頭形成連續的鏈
4. 選擇累積工作量最大的鏈
5. 驗證交易時,使用 Merkle 證明

存儲需求:
850,000 區塊 × 80 bytes ≈ 68 MB
已複製連結
已複製到剪貼簿