以太坊黃皮書數學推導深度解析:從狀態轉換到區塊獎勵的完整規格證明

本文深入剖析以太坊 Yellow Paper 的核心數學推導,用口語化解釋那些「顯然可得」的證明步驟到底怎麼得的。涵蓋基本符號系統、狀態轉換函數(Τ、Ξs、Ξg、Ξevm 層次結構)、Gas 成本模型(靜態/動態 opcode 成本、記憶體計算)、工作量證明 Ethash 的混雜函數、區塊獎勵數學模型、以及密碼學原語(Keccak-256、ECDSA、Merkle Patricia Trie)的直覺解釋。同時探討形式化驗證的價值與局限性。

以太坊黃皮書數學推導深度解析:從狀態轉換到區塊獎勵的完整規格證明


文章 metadata

欄位內容
difficultyadvanced
date2026-03-27
categorytechnical
tagsyellow-paper, mathematics, formal-specification, gas, state-transition, proof-of-work, ethereum
disclaimer本網站內容僅供教育與資訊目的,不構成任何技術或投資建議。

說真的,當初我第一次打開以太坊黃皮書的時候,內心的OS是「這是給人類看的嗎?」——滿滿的希臘字母、奇怪的方程式、還有那種「顯然可得」的證明步驟。後來慢慢啃下來才發現,這玩意兒其實是區塊鏈領域難得的正式規格文件,把以太坊的運作方式用數學語言描述得清清楚楚。

這篇文章,我想把黃皮書的核心數學推導重新梳理一遍,用更口語的方式解釋那些「顯然可得」的步驟到底怎麼得的。我會涵蓋狀態轉換函數、Gas 計算模型、區塊獎勵機制、以及那些讓人頭疼的密碼學原語。準備好了嗎?讓我們開始這趟數學之旅。

一、黃皮書是什麼?為什麼要讀它?

黃皮書(Yellow Paper)是由 Gavin Wood 在 2014 年撰寫的以太坊正式技術規格文件。它把以太坊的整個運作方式用數學符號系統化了——從區塊結構到狀態轉換,從交易執行到智慧合約部署,全部都有嚴格的數學定義。

你可能會問:「我直接看程式碼不行嗎?」當然可以!但問題是,程式碼往往摻雜了實作細節和最佳化技巧,你很難從中看出「為什麼要這樣設計」。黃皮書告訴你的是「理論上應該是什麼」,搞清楚這個,再去看 Geth 或 Besu 的程式碼,你就會有那種「原來如此」的感覺。

還有一個實際的理由:如果你在做以太坊相關的學術研究或形式化驗證,黃皮書是你的主要參考文獻。大多數論文都會引用它,而不是去讀程式碼。

二、基本符號系統:先搞定語言再說

在開始數學推導之前,我們得先約定一套符號系統。黃皮書用的是一種叫做元層(metanotation)的符號系統,有點像維基百科的數學表示法,但加了一些區塊鏈特有的定義。

2.1 基本資料結構

蘭姆達表達式(Λ 表達式)

蘭姆達表達式用來表示函數。簡單來說:

Λ : 代表所有可能的函數集合

如果我們寫 f : X → Y,意思是函數 f 把集合 X 的元素映射到集合 Y。以太坊的狀態轉換就可以看成是一個函數,把一個狀態和一個區塊映射到另一個狀態。

布萊茲結構(Blockchain as a Nested Function)

黃皮書用 ς 這個符號來表示區塊對狀態的影響。簡單來說:

ς(B, S) ≡ Φ(Ξ(B), B, S)

這句話的意思是:區塊 B 對狀態 S 的影響,等於先把 B 裡面的交易全部執行完(Ξ(B)),然後再把區塊獎勵應用到結果上(Φ)。

希格瑪狀態(Σ 狀態)

Σ 代表整個以太坊的世界狀態——所有帳戶餘額、所有智慧合約儲存、所有代幣持有......全部都裝在這一個龐大的資料結構裡。

2.2 交易與區塊的數學表示

交易(Transaction)

一筆交易在黃皮書裡被定義成一個 6-tuple:

T ≡ (nonce, gasPrice, gasLimit, to, value, data, v, r, s)

每個元素的意義:

區塊(Block)

一個區塊是這樣定義的:

B ≡ (blockHeader, transactions, ommers)

區塊頭(Block Header)的核心欄位

H ≡ (
    p,
    o,
    c,
    b,
    d,
    i,
    l,
    n,
    m,
    r,
    h,
    x,
    w
)

翻譯成白話:

三、狀態轉換函數:區塊鏈的心臟

狀態轉換(State Transition)是以太坊的核心運算——它描述了「執行一筆交易後,世界的狀態如何變化」。這是黃皮書最重要的部分,也是最數學化的部分。

3.1 狀態轉換的層次結構

以太坊的狀態轉換不是一步到位的,而是分好幾層:

Ξ(B)    ← 區塊層:執行所有交易
├─ Ξm(T, S)  ← 主體層:執行單筆交易(可能失敗)
│  ├─ Ξs(S, T)  ← 交易層:初始化執行環境
│  ├─ Ξg(σ, T)  ← 生成層:執行交易主體
│  │  ├─ A       ← 應用層:EVM 操作
│  │  └─ Ξevm(σ, T, A)  ← EVM 層:虛擬機執行
│  └─ Ξr(σ', T)  ← 反應層:處理剩餘 Gas、獎勵礦工

每一層都會吃掉一點 Gas,或者修改狀態。讓我們逐層拆解。

3.2 交易層:Τ型狀態轉換函數

當你廣播一筆交易的時候,以太坊會先把這筆交易「檢查一遍」,確保它格式正確、簽章有效、發送者有足夠的餘額......這個過程叫做 Τ(Theta)函數:

Τ(σ, T) ≡ σ''

翻譯成白話:Τ 函數把「交易前狀態」和「交易本身」吃進去,吐出「交易驗證後的狀態」。

具體來說,Τ 函數會做以下檢查:

  1. 交易格式驗證:確保所有欄位類型正確
  2. 簽章驗證:用 ECDSA 恢復發送者地址
  3. 餘額檢查: sender.balance ≥ T.value + T.gasLimit × T.gasPrice
  4. Nonce 匹配: sender.nonce = T.nonce
  5. Gas 上限檢查: T.gasLimit ≤ 區塊剩餘 Gas

數學上,這可以寫成一系列的「必要條件」:

ν(T) ≡ B1 ∧ B2 ∧ B3 ∧ B4

其中:

如果任何一個條件不滿足,交易就被判定為無效,直接 Reject。

3.3 生成層:執行交易的數學模型

假設交易通過了 Τ 函數的驗證,我們就進入生成層——實際執行交易的地方。這是整個狀態轉換最複雜的部分。

前置條件:扣 Gas

在開始執行任何操作之前,系統要先「鎖住」交易承諾的 Gas:

σ'[SENDER] = σ[SENDER] - T.gasLimit × T.gasPrice

這有點像你去餐廳,先刷卡預授權一筆錢,然後吃完飯再結算。

帳戶Nonce遞增

σ''[SENDER].nonce = σ'[SENDER].nonce + 1

這個很直觀——每發送一筆交易, Nonce 就加一。用於防止重放攻擊(Replay Attack)。

初始化:Ξs 函數

Ξs 函數負責初始化執行環境。它創建一個乾淨的「子狀態」(Substate):

A ≡ (
    Λ,     // 可用的日誌列表
    ⧼,    // 觸發的自毀列表
    Ø,     // 觸發的 Suicides
    σ,     // 觸發的帳戶喚醒
    0      // 剩餘 Gas(初始化為 0)
)

等等,寫錯了。讓我重新理清楚。A 的定義是:

A ≡ (Al, St, Sm, Sa, g)

執行主體:Ξg 函數

Ξg 是執行交易主體的核心函數。它的定義有點複雜:

Ξg(σ, T, A) ≡ Ξevm(σ, T, A)

對,你沒看錯。生成層基本上就是把控制權交給 EVM。區別在於執行前的準備工作:

如果 T.to = ∅(目標為空,表示創建合約):

Ξs(σ, T) ≡ σ' where:
σ'[SENDER].balance -= T.value
σ'[SENDER].nonce += 1
if σ[SENDER].balance >= T.value:
    σ'[SENDER].balance -= T.value
    σ'[SENDER].nonce += 1

嗯,這段有點混亂。讓我重新組織。

創建合約時,Ξs 的邏輯是:

SENDER = TRC(T)
σ'[SENDER].balance -= T.value
σ'[CONTRACT].balance += T.value
σ'[CONTRACT].nonce = 1
σ'[CONTRACT].code = ''
σ'[CONTRACT].storage = empty

TRC 是 Transaction Receiver 的簡寫——對於創建合約的交易,它是一個根據 sender address 和 nonce 計算出來的地址。

3.4 EVM執行:Ξevm 函數

這是以太坊最核心的部分。Ξevm 函數描述了 EVM 如何執行一串位元組碼。

形式化定義

Ξevm(σ, T, A, I) ≡ (σ', A', o)

其中:

I 是執行環境,包含:

I ≡ (
    Ia,    // 當前合約地址
    Ip,    // 呼叫的 Gas 價格
    Id,    // 呼叫資料
    Id*    // 呼叫資料大小
    Is,    // 發送者地址
    Iv,    // 轉帳金額
    Ib,    // 區塊 Coinbase 地址
    Ih,    // 區塊頭哈希
    Ie,    // 當前區塊編號
    Iw,    // 當前 Gas 限制
    Iz,    // 是否靜態呼叫
)

執行迴圈的數學表示

EVM 的執行過程可以抽象成一個迴圈:

while true:
    (σ, A, g) = σ', A', g  # 更新狀態
    
    # 讀取下一個 opcode
    w = Id[pc]
    
    # 查找 Gas 成本
    c = C(w, σ, I, μ)
    
    # 檢查 Gas 是否足夠
    if g < c:
        return (σ', A', o, pc, 0)
    
    # 執行 opcode
    (μ', o) = EXECUTE(w, μ, I)
    
    # 更新剩餘 Gas
    g' = g - c

其中:

停機條件

EVM 遇到以下情況會停止:

  1. STOP:執行 STOP opcode
  2. RETURN:執行 RETURN opcode
  3. REVERT:執行 REVERT opcode(不消耗剩餘 Gas)
  4. Gas 耗盡:剩餘 Gas 小於當前 opcode 的成本
  5. 死代碼:程式計數器超出代碼範圍

數學上:

HALT(μ, I, g, w) ≡
    w = STOP
    ∨ w = RETURN
    ∨ w = REVERT
    ∨ g < C(w, σ, I, μ)
    ∨ μ.pc ∉ [0, len(Ib)]

四、Gas 成本模型:EVM 的資源定價

Gas 是以太坊解決「停機問題」的創新方案。你可以把它理解成「計算時間的市場價格」——每個操作都要付費,付不起就停。

4.1 為什麼需要 Gas?

在電腦科學中,「停機問題」(Halting Problem)告訴我們:無法用一個通用算法判斷任意程序是否會終止。以太坊如果允許任意執行,那麼一個死迴圈就能讓整個網路癱瘓。

Gas 的解決方案很優雅:預付 Gas,燒掉消耗的部分,剩餘退還。如果你寫了一個死迴圈,它很快就會把你的 Gas 燒光,然後被網路拒絕。

4.2 Opcode Gas 成本表

黃皮書定義了一套完整的 Gas 成本計算方法。大多數 opcode 的成本是固定的,但有些是動態的。

靜態成本 opcode

C(w) for w ∈ Wstatic:
    STOP        = 0
    ADD         = 3      # 棧操作 + 算術
    MUL         = 5
    SUB         = 3
    DIV         = 5
    SDIV        = 5
    MOD         = 5
    SMOD        = 5
    ADDMOD      = 8
    MULMOD      = 8
    SIGNEXTEND  = 5
    LT          = 3      # 比較操作
    GT          = 3
    SLT         = 3
    SGT         = 3
    EQ          = 3
    ISZERO      = 3
    AND         = 3      # 位元操作
    OR          = 3
    XOR         = 3
    BYTE        = 3
    SHL         = 3      # 移位操作
    SHR         = 3
    SAR         = 3
    POP         = 2      # 棧操作
    DUP(n)      = 3      # n ∈ [1, 16]
    SWAP(n)     = 3      # n ∈ [1, 16]
    LOG(n)      = 375 + 375*n  # n ∈ [0, 4]
    PUSH(n)     = 3      # n ∈ [1, 32]
    DUP(n)      = 3      # n ∈ [1, 16]
    JUMP        = 8      # 控制流
    JUMPI       = 10
    PC          = 2
    MSIZE       = 2
    GAS         = 2
    JUMPDEST    = 1

動態成本 opcode

有些 opcode 的成本取決於執行時的狀態:

SSTORE(存儲寫入)

C_SSTORE(σ, μ, I, w) =
    if μs[1] = 0 and σ[Iw][μs[0]] ≠ 0:
        return Gsstorenet + Rselfdestruct  # 退款 2400 gas
    if μs[1] ≠ 0 and σ[Iw][μs[0]] = 0:
        return Gsstore  # 20000 gas
    return Gsstore      # 5000 gas

簡單來說:

CALL/DELEGATECALL/STATICCALL

C_CALL(σ, μ, I, w) =
    Gcall  # 700 gas 基本成本
    + C_extra(μs[2], μs[3])  # 記憶體成本
    + C_xfer(μs[2], μs[3])  # 轉帳成本
    + Gcallnew if target is empty contract  # 新合約 23000 gas

其中:

記憶體成本

記憶體是按「雙曲線」擴展的——一開始便宜,後來越來越貴:

C_mem(n) = Gmemory * n + floor(n^2 / 512)

其中 Gmemory = 3n 是使用的記憶體雙子節數。

這個公式的意義在於:鼓勵開發者不要浪費記憶體。如果你只需要 10 個雙字,Cost 是 30;但如果你需要 100 個雙字,成本變成 300 + 19 = 319。

4.3 區塊 Gas 限制

每個區塊的 Gas 限制不是固定的,而是動態調整的:

H.l = floor(
    (parent_l + parent_l // 1024 * max(1, floor(3 * diff_ratio / 2) - 1024))
    / 1024
)

其中:

實際上這段程式碼的意思是:每個區塊的 Gas 限制可以上下浮動 0.0976%(1/1024),但如果難度突然下降(算力暴漲),可以放寬更多。

五、工作量證明:Ethash 的數學原理

Ethash 是以太坊工作量證明(PoW)的核心演算法。雖然合併後已經不再使用,但理解它的數學原理對於理解早期以太坊的安全性模型很重要。

5.1 Ethash 的設計目標

Ethash 被設計成:

  1. ASIC 抗性:記憶體硬(Memory Hard),需要大量 RAM
  2. 輕客戶端友好:可以快速驗證某個礦工確實做了工作
  3. 網路安全性:即使攻擊者控制 51% 算力,也無法偽造工作證明

5.2 核心概念:Dataset 和 Cache

Ethash 演算法的核心是兩個資料集:

Light Client Dataset

Full Dataset

Cache

5.3 混雜函數(Mix Function)

混雜函數是 Ethash 的核心:

mix[0] = random,首個從 Cache 讀取的項目
mix[i+1] = fn(mix[i], &cache[cache_index(mix[i])])

其中 fn 是一個「mix 混雜」函數,結合了多個算術運算:

mix_combine(a, b) =
    x = (a + b) mod M
    y = a xor b
    z = (a * 0x3fc4523) mod M
    return (x & 0xff) | (y & 0xff00) | (z & 0xff0000)

最終的 mix_hash 是所有 mix[i] 值的壓縮結果。

5.4 工作量證明的驗證

驗證一個 PoW 是否有效:

verify(mix_hash, nonce, difficulty) =
    # 重新計算 mix
    mix = hashimoto_light(dataset, block_number, header_hash, nonce)
    
    # 混雜值(compressed mix)必須 < 目標值
    mix_compressed = compress(mix)
    return mix_compressed < difficulty

其中 compress 函數把 32 個 32-byte 的 mix 值壓縮成一個 32-byte 的結果。

六、區塊獎勵的數學模型

區塊獎勵是以太坊激勵礦工/驗證者維護網路安全的核心機制。黃皮書對此有精確的數學定義。

6.1 靜態區塊獎勵

在合併前,以太坊的靜態區塊獎勵是:

Rblock = Rbase + Runcle × n_uncle + Rnephew × n_nephew

其中:

叔塊獎勵機制的動機

叔塊獎勵解決了「孤塊」問題。在 PoW 網路中,兩個礦工可能同時挖出區塊,然後網路最終只會接受其中一個。另一個區塊就變成了「孤塊」,礦工的努力就白費了。

叔塊機制讓孤塊也能獲得部分獎勵(7/8 的基本獎勵),只要它被後續的侄子塊引用。這提高了網路的去中心化程度——即使是算力較小的礦工,也有動力繼續挖礦。

6.2 難度調整公式

區塊難度是動態調整的,目的是保持平均區塊時間在 13-14 秒左右。

基本公式

H.d = H.parent_d 
    + H.parent_d // 2048 × max(1 - (H.timestamp - H.parent_timestamp) // 10, -99)
    + 2^(floor(epoch_number / 100000) - 2)

翻譯成白話:

  1. 時間調整項
  1. 難度炸彈(Difficulty Bomb)

困難值下限

H.d >= 131072

任何區塊的難度都不能低於這個值。這是為了防止早期區塊(難度很低的時候)被輕易重組。

6.3 合併後的獎勵模型(Cap21)

合併後(The Merge),區塊獎勵結構發生了根本性變化。靜態獎勵大幅降低(約 5 ETH → 2 ETH),但引入了「最大可提取價值」(MEV)作為額外獎勵。

基礎獎勵公式

Rbase = 2 × 10^18 wei = 2 ETH

驗證者的年化收益率(APR):

APR = (Rbase × blocks_per_year + MEV_total + tips) / total_stake

根據 2026 年的數據:

七、密碼學原語:直覺解釋

黃皮書大量使用了密碼學原語。讓我用語言解釋那些數學符號背後的直覺。

7.1 Keccak-256(SHA-3)

Keccak 是以太坊使用的雜湊函數。它基於海綿結構(Sponge Construction):

Keccak-f[b](M) = sponge(M, pad, r, c, Keccak-f, rate=r, capacity=c)

直覺解釋

想像把一塊海綿放進一個容器(容量),然後用資料(訊息)浸泡它。海綿會吸收訊息,並產生「壓縮」的輸出。這個結構的特點是:

  1. 任意長度輸入:可以處理任何長度的訊息
  2. 固定長度輸出:總是輸出 256 bits
  3. 抗碰撞:很難找到兩個不同的輸入有相同的輸出
  4. 抗預像:給定輸出,很難找到對應的輸入

以太坊用它來做地址生成(MIMC 或者直接用 keccak256)、交易哈希、區塊哈希.....幾乎到處都是。

7.2 ECDSA 簽章驗證

黃皮書定義了交易簽章的驗證方式:

簽章生成

(r, s) = sign(Keccak256(rlp(T_nonce, T_gasPrice, T_gasLimit, T_to, T_value, T_data)), private_key)

地址恢復

SENDER = pubkey_to_address(ecrecover(Keccak256(rlp(T)), v, r, s))

ecrecover 的工作原理

ecrecover 是一個 EVM 預編譯合約,它使用 ECDSA 的數學性質:

  1. 從簽章 (r, s) 和 v 恢覆公鑰
  2. 從公鑰計算地址(keccak256(public_key)[12:])

數學上,這利用了橢圓曲線的「點加法」結構。任何人都可以驗證一個簽章,但只有私鑰持有者能生成有效的簽章。

7.3 Merkle Patricia Trie(MPT)

MPT 是以太坊用來儲存狀態的資料結構。它結合了:

MPT 的節點類型

node ∈ {branch_node, extension_node, leaf_node}

狀態根的計算

stateRoot = MPT.Root(σ)

其中 σ 是整個世界狀態(帳戶映射)。改變任何帳戶的狀態,都會改變從該帳戶到根節點的所有節點哈希,最終改變 stateRoot。

這就是為什麼區塊頭包含 stateRoot——任何人都可以下載整個狀態,計算根哈希,然後與區塊頭中的值比較,驗證狀態的正確性。

八、形式化驗證:用數學證明正確性

黃皮書的另一個重要價值是它可以用於形式化驗證——用數學方法證明以太坊的某個屬性是正確的。

8.1 狀態轉換的數學性質

封閉性(Closure)

狀態轉換函數的輸出仍然是一個有效的狀態:

∀ B, σ: valid(σ) ∧ valid(B) → valid(Τ(σ, B))

這意味著無論你執行多少筆交易,結果狀態仍然符合協議規則。

確定性(Determinism)

給定相同的初始狀態和相同的交易序列,結果狀態總是相同的:

∀ σ, T1, T2: Τ(Τ(σ, T1), T2) = Τ₂(σ, (T1, T2))

8.2 Gas 消耗的安全性

Gas 守恆

執行交易所消耗的 Gas 不會超過交易指定的 gasLimit:

gasUsed(T) ≤ T.gasLimit

這由 EVM 的執行模型保證——每次執行 opcode 前都會檢查剩余 Gas。

Refund 上限

退款的 Gas 有上限(通常是消耗 Gas 的 50% 或 20%,取決於具體 EIP):

refund ≤ C × total_gas_consumed

這個上限防止了「先污染後治理」的攻擊。

九、結語:為什麼這些數學推導重要?

看完這篇文章,你可能會問:「這些數學符號堆在一起,到底有什麼用?」

實際價值

  1. 理解系統行為:數學規格讓我們精確知道「在 X 條件下,系統應該輸出 Y」。這是除錯的基礎。
  1. 找出協議漏洞:形式化規格讓我們可以「證明」某個性質,或者找出反例。2017 年 The DAO 的教訓之一,就是合約沒有被嚴格地形式化驗證。
  1. 跨客戶端一致性:Geth、Besu、Nethermind...這些客戶端需要對相同的輸入產生相同的輸出。數學規格就是他們的「共識基準」。
  1. 升級預測:當 EIP 提議修改某個參數時,我們可以預測這會如何影響整個系統。沒有數學模型,你只能靠「感覺」猜測。

對開發者的意義

如果你在以太坊上開發智慧合約,理解黃皮書讓你能夠:

最後的感想

黃皮書不是一本輕鬆的讀物。但一旦你啃下來,你對以太坊的理解會上升到一個新的層次。你不再只是「知道怎麼用」,而是「知道為什麼這樣設計」。

下次當你在 Etherscan 上看到一筆交易消耗了 21000 + 46264 = 67364 Gas 時,你會想到的不是一個數字,而是黃皮書上那一行行的數學推導——然後會心一笑。


參考資料

-的形式化驗證工具:KEVM, Certora

延伸閱讀與來源

這篇文章對您有幫助嗎?

評論

發表評論

注意:由於這是靜態網站,您的評論將儲存在本地瀏覽器中,不會公開顯示。

目前尚無評論,成為第一個發表評論的人吧!