跳至主要內容
挖礦 進階

難度

Difficulty

又稱:挖礦難度、Mining Difficulty

難度(Difficulty)是比特幣網路中衡量找到有效區塊所需計算量的指標。透過自動調整難度,比特幣網路確保無論全網算力如何變化,平均出塊時間始終維持在約 10 分鐘。這是比特幣協議中最精妙的自我調節機制之一。

難度的本質

什麼是難度?

簡單理解:

難度就是「找到有效區塊有多困難」

類比:
- 擲骰子得到 1:難度 6(六面)
- 擲骰子得到 1:難度 1000(千面骰)
- 擲骰子得到小於目標值的數字

比特幣:
- 骰子有 2^256 面
- 找到小於目標值的雜湊
- 難度決定目標值的大小

難度與目標值

數學關係:

目標值(Target)= 難度1目標值 / 難度

難度1目標值(最大目標):
0x00000000FFFF0000000000000000000000000000000000000000000000000000

等於十進位:
26,959,535,291,011,309,493,156,476,344,723,991,336,010,898,738,574,164,086,137,773,096,960

難度 D 時的目標值:
Target = 難度1目標值 / D

難度越高 → 目標值越小 → 越難找到有效雜湊

挖礦成功的條件

有效區塊的條件:

SHA256(SHA256(區塊頭)) < 目標值

視覺化:

目標值:00000000000000000025...
有效雜湊必須小於此值

有效:000000000000000000024...(比目標值小)
有效:000000000000000000001...(更小)
無效:000000000000000000026...(比目標值大)

雜湊結果是隨機的:
- 有些以很多零開頭
- 大多數沒有
- 需要大量嘗試才能找到

難度調整機制

為什麼需要調整?

問題情境:

算力增加時(無調整):
- 更多礦機 → 更快找到區塊
- 出塊時間 < 10 分鐘
- 比特幣發行加速
- 減半週期縮短
- 供應計劃被打亂

算力減少時(無調整):
- 礦工離開 → 更難找到區塊
- 出塊時間 > 10 分鐘
- 交易確認變慢
- 用戶體驗下降
- 網路可能停滯

難度調整解決這些問題

調整週期

每 2016 個區塊調整一次:

為什麼是 2016?
2016 區塊 × 10 分鐘 = 20,160 分鐘 = 2 週

調整時機:
區塊 2016, 4032, 6048, 8064, ...
每 2016 的倍數

當前(2024):
區塊高度約 850,000
已經過約 423 次調整

調整公式

計算公式:

新難度 = 舊難度 × (目標時間 / 實際時間)
新難度 = 舊難度 × (20,160 分鐘 / 實際耗時)

等價於:
新目標 = 舊目標 × (實際時間 / 目標時間)

範例1:出塊太快
實際耗時:10,080 分鐘(1週,比目標快一倍)
新難度 = 舊難度 × (20,160 / 10,080) = 舊難度 × 2
難度翻倍

範例2:出塊太慢
實際耗時:40,320 分鐘(4週,比目標慢一倍)
新難度 = 舊難度 × (20,160 / 40,320) = 舊難度 × 0.5
難度減半

調整限制

防止極端波動:

最大調整幅度:4 倍
- 上限:新難度 ≤ 舊難度 × 4
- 下限:新難度 ≥ 舊難度 / 4

為什麼有限制?
1. 防止時間戳操縱攻擊
2. 平滑過渡
3. 給礦工適應時間

極端情況:
如果 99% 算力突然消失
- 無限制:難度立即降到 1%
- 有限制:需要多個週期逐步下降

nBits 編碼格式

目標值的壓縮表示

區塊頭中的 nBits 欄位(4 bytes):

格式:
nBits = 指數(1 byte) + 尾數(3 bytes)

解碼公式:
target = 尾數 × 256^(指數-3)

範例(難度1):
nBits = 0x1d00ffff
指數 = 0x1d = 29
尾數 = 0x00ffff = 65535

target = 65535 × 256^(29-3)
       = 65535 × 256^26
       = 0x00000000ffff0000...

編碼與解碼

def bits_to_target(bits):
    """將 nBits 解碼為目標值"""
    exponent = bits >> 24
    mantissa = bits & 0x007fffff

    if exponent <= 3:
        target = mantissa >> (8 * (3 - exponent))
    else:
        target = mantissa << (8 * (exponent - 3))

    # 處理負數情況(最高位為符號位)
    if mantissa & 0x00800000:
        target = -target

    return target

def target_to_bits(target):
    """將目標值編碼為 nBits"""
    # 計算需要的字節數
    target_bytes = target.to_bytes((target.bit_length() + 7) // 8, 'big')

    if len(target_bytes) <= 3:
        mantissa = int.from_bytes(target_bytes.ljust(3, b'\x00'), 'big')
        exponent = len(target_bytes)
    else:
        mantissa = int.from_bytes(target_bytes[:3], 'big')
        exponent = len(target_bytes)

    # 確保尾數不會被解釋為負數
    if mantissa & 0x00800000:
        mantissa >>= 8
        exponent += 1

    return (exponent << 24) | mantissa

難度歷史

歷史里程碑

時間難度事件
2009-011創世區塊
2010-07181首次顯著上升
2011-0114,484GPU 挖礦興起
2013-013,129,573ASIC 時代開始
2017-121.87T牛市高峰
2018-125.11T熊市低谷
2021-0525.05T中國禁礦前
2021-0713.67T中國禁礦後最低
2024-0483.13T第四次減半時

難度與算力關係

難度與全網算力的關係:

算力估算公式:
算力(H/s) = 難度 × 2^32 / 600

其中 600 是目標出塊時間(秒)

範例(難度 80T):
算力 = 80 × 10^12 × 2^32 / 600
     ≈ 573 EH/s

反向計算:
難度 = 算力 × 600 / 2^32

中國禁礦事件(2021)

時間線:

2021年5月:
- 難度:25.05T
- 全網算力:~180 EH/s
- 中國佔比:~65%

2021年6月-7月:
- 中國全面禁止挖礦
- 大量算力離線
- 難度連續下降

2021年7月:
- 難度:13.67T(下降 45%)
- 最大單次下降:-28%

恢復:
- 礦工遷移到北美、哈薩克等地
- 2021年底恢復到禁礦前水平
- 證明了網路的彈性

難度與安全性

攻擊成本計算

51% 攻擊成本估算:

假設:
- 難度:80T
- 全網算力:~570 EH/s
- 需要控制:>285 EH/s

硬體成本:
- 最新 ASIC:200 TH/s
- 需要數量:285 EH/s / 200 TH/s = 142 萬台
- 單價:~$5,000
- 總成本:~$71 億

電力成本(每天):
- 每台功耗:3.5 kW
- 總功耗:5 GW
- 日耗電:120 GWh
- 電費($0.05/kWh):$600 萬/天

結論:難度越高,攻擊成本越高

難度與網路健康

評估指標:

健康信號:
✓ 難度穩定增長
✓ 算力分佈均勻
✓ 出塊時間接近 10 分鐘

警告信號:
⚠️ 難度大幅下降
⚠️ 算力集中於少數礦池
⚠️ 出塊時間異常波動

監控工具:
- mempool.space/mining
- btc.com/stats
- coinwarz.com/mining/bitcoin

難度調整的邊緣情況

時間戳操縱

潛在攻擊:

時間戳規則:
- 必須大於前 11 區塊的中位數時間
- 必須小於網路時間 + 2 小時

操縱方式:
- 礦工故意設置未來時間戳
- 縮短週期計算的「實際時間」
- 導致難度增加較少

防禦:
- 4 倍調整上限
- 中位數時間規則
- 2 小時未來時間限制

難度炸彈?

比特幣沒有難度炸彈:

與以太坊不同:
- 以太坊有「難度炸彈」設計
- 強制定期升級
- 比特幣沒有這個機制

比特幣的設計哲學:
- 最小化強制變更
- 難度純粹基於算力
- 無人為干預

開發者資源

計算難度

import struct

def calculate_difficulty(bits):
    """從 nBits 計算難度值"""
    # 難度 1 的目標值
    max_target = 0x00000000FFFF0000000000000000000000000000000000000000000000000000

    # 解碼當前目標
    current_target = bits_to_target(bits)

    # 計算難度
    difficulty = max_target / current_target

    return difficulty

def estimate_hashrate(difficulty):
    """從難度估算全網算力"""
    # 算力 = 難度 × 2^32 / 600
    hashrate = difficulty * (2**32) / 600
    return hashrate  # H/s

def expected_time(difficulty, hashrate):
    """計算期望出塊時間"""
    # 找到有效區塊的期望嘗試次數
    expected_hashes = difficulty * (2**32)
    # 期望時間 = 期望嘗試 / 算力
    return expected_hashes / hashrate  # 秒

Bitcoin Core RPC

# 獲取當前難度
bitcoin-cli getdifficulty

# 獲取區塊的難度目標
bitcoin-cli getblockheader <blockhash>
# 查看 "bits" 和 "difficulty" 欄位

# 獲取挖礦資訊(包含難度)
bitcoin-cli getmininginfo

# 獲取區塊鏈資訊
bitcoin-cli getblockchaininfo
# 查看 "difficulty" 欄位

# 獲取網路算力估算
bitcoin-cli getnetworkhashps
bitcoin-cli getnetworkhashps 120  # 最近 120 區塊的平均值

追蹤難度調整

const bitcoin = require('bitcoinjs-lib');

function getNextRetargetBlock(currentHeight) {
  const interval = 2016;
  const currentPeriod = Math.floor(currentHeight / interval);
  return (currentPeriod + 1) * interval;
}

function blocksUntilRetarget(currentHeight) {
  return getNextRetargetBlock(currentHeight) - currentHeight;
}

function estimateNextDifficulty(periodStartTime, periodEndTime, currentDifficulty) {
  const targetTime = 2016 * 10 * 60; // 20160 分鐘(秒)
  const actualTime = periodEndTime - periodStartTime;

  let adjustment = targetTime / actualTime;

  // 應用 4 倍限制
  if (adjustment > 4) adjustment = 4;
  if (adjustment < 0.25) adjustment = 0.25;

  return currentDifficulty * adjustment;
}

常見問題

如果所有礦工同時停止會怎樣?

理論情境:

所有算力消失:
1. 無法產生新區塊
2. 交易無法確認
3. 網路「凍結」

但是:
- 只要有一個礦工,就會繼續
- 難度會在下個週期調整
- 最多等待 4 倍時間(8週)
- 然後難度降到 1/4

實際上:
- 永遠會有礦工(只要有利可圖)
- 價格下跌會讓更多人有利可圖
- 網路有強大的自我修復能力

難度能降到 1 以下嗎?

理論上可以,但不太可能:

難度 < 1 的含義:
- 比創世區塊更容易挖
- 目標值非常大
- 幾乎任何雜湊都有效

為什麼不可能發生:
1. 當前難度是 80T+
2. 每次最多降 75%
3. 需要數十次連續下降
4. 意味著算力持續暴跌

即使發生:
- 難度 < 1 仍然有效
- 協議沒有禁止
- 只是非常不可能

難度調整會影響價格嗎?

間接關係:

難度上升通常意味著:
- 更多礦工加入
- 對未來價格樂觀
- 投資增加

難度下降可能意味著:
- 礦工退出(不盈利)
- 可能伴隨價格下跌
- 或只是效率提升

但不是因果關係:
- 難度不決定價格
- 價格影響礦工決策
- 礦工決策影響算力
- 算力決定難度

為什麼不更頻繁調整?

2016 區塊(2 週)的理由:

優點:
1. 給礦工適應時間
2. 減少波動
3. 降低操縱風險
4. 足夠的數據點

更頻繁調整的問題:
- 更容易被操縱
- 過度反應短期波動
- 增加計算複雜度

不同幣種的選擇:
- Bitcoin Cash:每區塊調整
- Litecoin:2016 區塊
- Dogecoin:每區塊調整

比特幣的選擇經過多年驗證
已複製到剪貼簿