昨天算出 EIP-4444 的真實窗口是 33024 epochs = 146.77 天,那個結論的前提是:歷史資料可以丟,因為它是「已經結束的敘事」——任何人只要拿得到一份,就能重放驗證。狀態(state)沒有這個性質。狀態是「當下的事實」,是每一次 SLOAD 都必須立刻答得出來的東西,不能延遲、不能向 Portal 網路請求、不能等 32 個 peer 回應。EIP-4444 幫全節點省掉了幾百 GB 的歷史,但那筆帳只結清了一次;狀態這一邊,每個區塊都在往上加,而且沒有任何協議機制在減少它。今天補的洞就是這個:狀態到底多大、長多快、Ethereum 在 2026 年打算用什麼手段擋住它,以及為什麼「state expiry」講了六年,到今天連一個 Draft 都沒有。
📖 學
一、先把數字量出來:390 GiB、326 MiB/day、650 GiB
談狀態膨脹最容易變成空泛的焦慮,所以先鎖住三個實測數字。EIP-8037(State Creation Gas Cost Increase)的 Motivation 章節給了目前最權威的公開數據:2026 年 1 月,一個 Geth 節點專門用於狀態的資料庫大小約為 390 GiB。這不是整個節點的磁碟佔用(那還要加上區塊、收據、索引),而是「狀態」這一項本身。
第二個數字更關鍵。主網 gas limit 從 30M 提到 60M 之後,每日新增的狀態大小從約 105 MiB 跳到約 326 MiB。注意這個倍率:gas limit 只漲了 2 倍,狀態增長率卻漲了 3.1 倍。EIP-8037 的作者群對這件事的解讀是,這不是穩態比例,而是使用者行為的一次性位移——便宜了之後,原本被抑制的建狀態行為一次釋放出來。
把 326 MiB/day 換算成年增量:
326 MiB/day × 365 day = 118,990 MiB
118,990 ÷ 1024 = 116.2 GiB/year
第三個數字是門檻:650 GiB。EIP-8037 把這個值標為「節點開始出現效能劣化」的臨界點。現在是 390 GiB,以 116 GiB/年的速度,還有 (650 − 390) / 116 ≈ 2.24 年。看起來還好。但如果 gas limit 真的照 Glamsterdam 的規劃走向 200M,按 EIP-8037 的線性外推:
326 MiB/day × (200 / 60) = 1,086.7 MiB/day
1,086.7 × 365 = 396,645 MiB = 387.3 GiB/year
(650 − 390) ÷ 387.3 = 0.672 年 ≈ 8.1 個月
八個月。這就是為什麼狀態定價會被排進 Glamsterdam,而且是和 gas limit 提升綁在同一組 EIP 裡送出去的——沒有前者,後者根本不能做。
更正 1:狀態膨脹的成本不是磁碟容量,是隨機讀的深度
最常見的誤解是把狀態膨脹理解成「硬碟不夠大」。2TB 的 NVMe SSD 現在很便宜,650 GiB 聽起來完全不是問題。但 650 GiB 這個門檻不是容量門檻,是存取模式的門檻。
Ethereum 的狀態存在 Merkle Patricia Trie 裡,每次讀寫一個 storage slot,客戶端必須沿著 trie 走 log₁₆(N) 層,每一層都是一次以 keccak hash 為 key 的隨機讀。當整棵樹能塞進作業系統的 page cache 或客戶端自己的記憶體快取時,這些讀取幾乎免費;當樹大到快取只能裝下一部分時,每一層都可能變成一次真實的磁碟 IOPS。狀態越大,快取命中率越低,而區塊執行時間直接被磁碟隨機讀的延遲綁住。這是一個非線性的懸崖,不是線性的擁擠。
所以「買更大的硬碟」解決不了這件事。它甚至讓事情更糟:更大的硬碟讓你有能力繼續容納一個你已經無法快速查詢的狀態。這也是為什麼 Ethereum 對歷史資料(EIP-4444)和對狀態的處理方式完全不同——歷史資料是順序讀、可以離線、可以慢;狀態是隨機讀、必須在 12 秒的 slot 裡完成、不能慢。
二、CPSB = 1530:一個常數怎麼被推導出來
EIP-8037 的核心是引入一個新常數 CPSB(cost per state byte),值為 1530 gas/byte。這個數字不是拍腦袋來的,推導過程完整寫在 EIP 的 Rationale 裡,值得逐步跟一遍,因為它示範了「協議層定價」實際上是怎麼做的。
輸入參數:
- 目標狀態增長:120 GiB/年,即
120 × 2³⁰ = 128,849,018,880bytes - 參考 block gas limit:150M(選在現行 60M 和預期未來 300M 的中間)
- Slot 時間 12 秒,故每天
86400 / 12 = 7,200個區塊,每年7,200 × 365 = 2,628,000個區塊 - 平均 state gas 利用率:50%。理由是在多維計價下,base fee 會收斂到 target,而 target 就是 gas limit 的一半
推導:
一年可用於建狀態的 state gas 總量
= (150,000,000 / 2) × 2,628,000
= 75,000,000 × 2,628,000
= 1.971 × 10¹⁴ gas
CPSB = 1.971 × 10¹⁴ ÷ 128,849,018,880
≈ 1,529.7
≈ 1530 gas/byte
接著要把「一次操作創造幾個 byte」定義清楚。EIP-8037 給了三張小表:
| 新帳戶(120 bytes) | 大小 |
|---|---|
| 帳戶 hash(作為 key) | 32 |
| nonce | 8 |
| balance | 16 |
| code hash | 32 |
| storage root | 32 |
| 合計 | 120 |
| 新 storage slot(64 bytes) | 大小 |
|---|---|
| slot hash(作為 key) | 32 |
| value | 32 |
| 合計 | 64 |
| EIP-7702 委派標記(23 bytes) | 大小 |
|---|---|
magic prefix 0xef0100 | 3 |
| 委派目標地址 | 20 |
| 合計 | 23 |
於是所有新價格都是乘法的結果:
新帳戶 : 120 × 1530 = 183,600 gas (原 25,000,約 7.34×)
新 slot : 64 × 1530 = 97,920 gas (原 20,000,約 4.90×)
7702 授權 : 23 × 1530 = 35,190 gas
24 KiB 合約: (120 + 24,576) × 1530 = 24,696 × 1530 = 37,784,880 gas
(原 32,000 + 200 × 24,576 = 4,947,200,約 7.64×)
EIP-8037 用 2025 年 12 月到 2026 年 1 月的平均 base fee 0.08 Gwei 換算成 ETH:新帳戶約 0.0000147 ETH,新 slot 約 0.00000783 ETH,24 KiB 合約部署約 0.00302 ETH。以絕對金額看仍然不貴,這是有意的——目的不是勸退,是讓價格反映真實的長期成本。
現行定價的不一致也值得看一眼。EIP-8037 列出五種創造狀態的方法,每 byte 的實際成本分別是:部署 24 kB 合約約 200 gas/byte、給新 EOA 打 1 wei 約 208、給已有餘額的 EOA 加委派標記約 219、對空地址做 7702 授權約 274、填新 storage slot 約 313。同樣是往資料庫寫一個 byte,價差 1.57 倍,純粹是十年來各自獨立定價的歷史殘留。CPSB 做的事情就是把這五條線壓成一條。
更正 2:EIP-8037 不是漲價 EIP,它偷渡了 Ethereum 第一個真正的多維 gas 市場
把 EIP-8037 讀成「狀態變貴了 5 到 8 倍」會漏掉整件事的重點。真正的結構改變是 gas 從一維變成二維:execution-gas 和 state-gas。
為什麼非拆不可?因為 EIP-7825 已經給單一交易設了 TX_MAX_GAS_LIMIT = 16,777,216(2²⁴)的上限。如果 state gas 也算在這個上限裡,EIP-8037 自己算給你看會發生什麼:
假設建構子執行預算 5M gas,加上 21,000 基本交易成本、
以及 120 × 1530 = 183,600 的建帳戶成本,
剩下能用於 code deposit 的預算為:
(16,777,216 − 21,000 − 5,000,000 − 183,600) ÷ 1530
= 11,572,616 ÷ 1530
≈ 7,564 bytes
也就是說,單維度下 CPSB=1530 會讓合約大小上限實質掉到 7.5 KB——比現行 EIP-170 的 24,576 bytes 還小三倍。這顯然不可接受,所以 state gas 必須逃出 EIP-7825 的籠子。
做法是 reservoir model(儲備池模型)。交易開始時:
evm_gas = tx.gas − intrinsic_gas
execution_gas_budget = TX_MAX_GAS_LIMIT − intrinsic_gas
gas_left = min(execution_gas_budget, evm_gas)
state_gas_reservoir = evm_gas − gas_left
gas_left 被硬性壓在 EIP-7825 的上限之下,溢出的部分全部進 state_gas_reservoir。執行類收費只扣 gas_left;建狀態類收費先扣 reservoir,扣光了才回頭扣 gas_left。退費(例如把同一筆交易內剛開的 slot 又清成 0)按 LIFO 順序倒著回填。
區塊層級同樣是二維的:
gas_used = max(block_execution_gas_used, block_state_gas_used)
assert gas_used <= block.gas_limit
「區塊滿了」從此指的是瓶頸維度滿了,而 base fee 也是跟著瓶頸維度更新。這是 Ethereum 主網第一次有真正的多維資源計價(blob 的 EIP-4844 是分開的獨立市場,不是同一個 gas 池的兩個維度)。
這個改動有兩個對開發者非常實際的副作用,EIP-8037 的 Security Considerations 自己寫出來了。第一,GAS opcode 只回傳 gas_left,看不到 reservoir。第二,因為退費會優先回填 gas_left,一個 frame 的 gas_left 有可能在某個操作之後變大。合約裡若用兩次 gasleft() 的差值來計量工作量,結果可能是負數:在 checked 算術下 revert,在 unchecked 下溢位。EIP 明說「已經部署的這類合約無法修復」。ERC-4337 的 EntryPoint 正是靠 gasleft() 差值來分攤 bundle 內各個 userOp 的成本,而 bundle 裡所有 userOp 共用同一個 reservoir——一個 userOp 的 state gas 退費可以在帳面上完全隱形地補貼另一個。EIP 直接要求 bundler 和 EntryPoint 實作 MUST 改成顯式追蹤 state gas,不能再靠差值。
還有一組配套值得一起看:EIP-7954 把合約大小上限從 24 KiB 提到 64 KiB。這件事之所以現在才做得到,正是因為 state gas 脫離了交易上限。用 CPSB 算一下一個滿版 64 KiB 合約的部署成本:
(120 + 65,536) × 1530 = 65,656 × 1530 = 100,453,680 gas(state 維度)
超過 1 億 gas。在現行 60M 的 block limit 下,這種合約根本塞不進任何一個區塊;在 150M 參考限額下佔掉 67%;要到 200M 以上才算舒服。換句話說,「合約可以變大」和「gas limit 要往上」是同一件事的兩面,不是兩個獨立的好消息。(此處為依 EIP 常數自行推算,非 EIP 原文列出的數字。)
Glamsterdam 裡跟這組配套的還有 EIP-8038(狀態存取定價,把 EXTCODESIZE、EXTCODECOPY 這類需要兩次資料庫讀取卻只收一次錢的操作補回來),以及 EIP-2780(把基本交易的 intrinsic gas 降低,單純 ETH 轉帳最多便宜 71%,但對「送到不存在的地址」加收建帳戶費——否則使用者會先花 21,000 建帳戶來規避 183,600 的建帳戶費,這個套利路徑 EIP-8037 自己在 Security Considerations 裡點名了)。
三、樹本身:從 Verkle 轉向 EIP-7864 二元樹
定價只是踩煞車。要真正改變狀態的成本結構,得動資料結構本身。
Ethereum 的長期路線曾經是 Verkle Tree(EIP-6800),用向量承諾(vector commitment)取代 hash 為基礎的 Merkle 分支,把 witness 壓到極小。2025 年 1 月 20 日,EIP-7864「Ethereum state using a unified binary tree」提出,作者群包含 Vitalik Buterin、Guillaume Ballet、Dankrad Feist、Ignacio Hagopian 等——注意這批人正是 Verkle 的主要推動者。到 2026 年 9 月的今天,EIP-7864 的狀態仍然是 Draft。
轉向的兩個理由,EIP 的 Rationale 寫得很直白:
第一是量子。Verkle 引入了一整套新的密碼學堆疊,基於橢圓曲線,而橢圓曲線不是後量子安全的。EIP 引用專家估計認為量子電腦可能在 2030 年代成真,NIST 建議 2030 年停用 ECC。stateless.fyi 這本書的說法更尖銳:如果部署 Verkle,「至少保證還會再發生一次狀態樹轉換」——先從 MPT 轉到 Verkle,再從 Verkle 轉到後量子的東西。而基於 hash 的二元樹「很可能就是協議最終使用的狀態樹」。
第二是證明系統進步太快。Verkle 的主要優勢是 proof 又小又快;但 SNARK/STARK 的 hashing throughput 進步速度,讓「用 SNARK 證明一棵 hash 樹」變得可行。優勢消失了,新增的密碼學風險就不划算。
EIP-7864 的具體設計,幾個關鍵點:
單一樹。 帳戶、code、storage 全部進同一棵邏輯樹。不再有「trie of tries」(帳戶 trie 底下掛 storage trie)的兩層結構,不再用 RLP 編碼節點,合約的 code 也被切成 chunk 放進樹裡(現在 code 不在狀態樹裡,只有 codeHash 在)。
stem 與 subindex。 樹的 key 是任意長度的 bytes,值固定 32 bytes。第一個 byte 是 storage type,中間是 stem,最後一個 byte 是 subindex。同一個 stem 底下有 256 個值,構成一棵完整的 8 層 Merkle 子樹。這個「256 個值共用一條路徑」的設計直接繼承自 Verkle,目的是資料局部性:常常一起被存取的東西住在同一條分支上,一次開branch 就都拿到。
storage type 前綴。 常數是 HEADER_SUBTREE = 0、CODE_SUBTREE = 1、STORAGE_SUBTREE = 255。這個前綴讓三種狀態各自佔據樹的不同區域,好處是可以分別同步。EIP 的 Rationale 明說這「在近期對於同步 VOPS 特別有價值」——後面會講 VOPS 是什麼。
arity = 2 的理由。 這是 EIP 裡少數給了完整數學論證的部分。在一個有 N 個元素、每個節點 k 個子節點的樹裡,一條分支的平均大小約為:
32 × (k − 1) × log(N) / log(k)
k − 1 是每層要提供的 sibling 數量,log(N)/log(k) 是層數。這個式子在 k = 2 時取得最小值。EIP 給了 N = 2²⁴ 的對照表:
| k(每節點子節點數) | 分支長度(chunks) | 分支長度(bytes) |
|---|---|---|
| 2 | 1 × 24 = 24 | 768 |
| 4 | 3 × 12 = 36 | 1,152 |
| 8 | 7 × 8 = 56 | 1,792 |
| 16 | 15 × 6 = 90 | 2,880 |
從 k=16 到 k=2,分支從 2,880 bytes 降到 768 bytes,3.75 倍。
現行 MPT 的實測參考值,EIP 也給了:在 2³² 大小的樹裡證明單一分支的期望大小是 15 × 32 × log₁₆(2³²) = 15 × 32 × 8 = 3,840 bytes。而最壞情況的區塊 witness,EIP 給了一個具體算式——如果用 30M gas 全部拿去讀不同合約 code 的單一 byte(因為 code 目前不 chunk 化,讀一個 byte 要提供整份 code):
每次冷帳戶存取 2,400 gas → 30,000,000 / 2,400 = 12,500 次
每次成本 = 5 層 × 480 bytes + 24 KiB code
= 2,400 + 24,576 = 26,976 bytes
總計 = 12,500 × 26,976 = 337,200,000 bytes ≈ 337 MB
EIP 寫 330MB。三百多 MB 的 witness 要在 12 秒的 slot 裡透過 p2p 傳播完——這就是為什麼在現行 MPT 上做 stateless 是不可能的,而不是「很難」。
更正 3:二元樹的目的不是省磁碟
中文圈流傳的說法常常是「新的狀態樹讓節點儲存需求降低 90%」。這句話有兩層錯。
第一層,那個 90% 是 Verkle 時代的行銷數字,而且指的是 stateless client——不存狀態、只驗 witness 的節點——的儲存需求,不是樹本身變小。第二層,EIP-7864 的樹在磁碟上不會比 MPT 小,甚至可能更大,因為合約 code 被 chunk 化後正式進入了狀態樹(現在 code 存在一個獨立的 code database 裡,只有 32 bytes 的 codeHash 在 trie 裡)。
EIP-7864 的 Motivation 從頭到尾講的是證明,不是儲存:「Ethereum 的長期目標是讓區塊能用有效性證明來證明」,而「證明狀態樹是達成這個目標最有挑戰的部分之一」。MPT 對有效性證明不友善的理由是 RLP 編碼、Keccak、樹中樹、code 不在樹裡。二元樹解決的是這四件事。
省磁碟是 stateless 和 state expiry 的工作,是另一條路線,依賴這棵樹但不等於這棵樹。把兩件事混為一談,會導致對時程的嚴重誤判——因為樹換了之後,磁碟佔用不會有任何立即改善。
更正 4:EIP-7864 目前的 Draft 有一段自相矛盾的常數表,別把它當定稿抄
這一點值得單獨拉出來,因為它是「不要憑二手摘要引用規格」的最好例子。
EIP-7864 的 Abstract 說「account stem 包含帳戶基本資料、前 64 個 storage slot 和前 128 個 code chunk」。但同一份文件的常數表寫的是 CODE_CHUNKS_IN_HEADER = 16、STORAGE_CHUNKS_IN_HEADER = 4。64 vs 4,128 vs 16,兩處差了 8 到 16 倍。
更明顯的是,EIP 自己聲明的不變量寫著「必須滿足 STEM_SUBTREE_WIDTH > CODE_OFFSET > HEADER_STORAGE_OFFSET」,而常數表給的是 STEM_SUBTREE_WIDTH = 256、CODE_OFFSET = 4、HEADER_STORAGE_OFFSET = 20。代進去是 256 > 4 > 20——後半段直接不成立。此外 get_tree_key_for_storage_slot 的程式碼裡用了 STORAGE_OFFSET 和 chunk_id 兩個在該函式作用域內未定義的名字(參數叫 storage_key,常數表裡叫 HEADER_STORAGE_OFFSET)。
結論:EIP-7864 的 tree embedding 這一節尚未定稿,任何引用這些常數的中文文章都應該回到原文確認。這也提醒了一件事——一個 EIP 停在 Draft 狀態一年八個月,不代表它被冷凍,而是代表它還在被改。(此處為對 2026-09-05 當日 eips.ethereum.org 版本的觀察,後續可能已修正——已標存疑。)
四、hash function:2026 年最戲劇性的轉向
EIP-7864 在 Abstract 用粗體警告過:「Do not assume BLAKE3 is a final decision.」草案用 BLAKE3 只是為了讓執行層客戶端方便做實驗,最終候選有三個:BLAKE3、Keccak、Poseidon2。
這個選擇為什麼難?stateless.fyi 的說明最清楚:「在目前目標硬體規格上,Keccak 或 BLAKE3 這類一般密碼學 hash 的 proving 效能,仍比 L1 所需慢一個數量級。」而 Poseidon2 這類算術友善的 hash,「目前在目標硬體上的 proving 效能對 L1 區塊需求綽綽有餘」,但「Poseidon2 尚未被認為可安全用於 L1」。
於是 Ethereum Foundation 在 2024 年 11 月啟動了 Poseidon Cryptanalysis Initiative,由 George Kadianakis、Dmitry Khovratovich、Antonio Sanso 主持,顧問團包含 Jean-Philippe Aumasson、Eli Ben-Sasson、Daira-Emma Hopwood 等人。公告的預算天花板加總約 136 萬美元,其中包含一筆 992,000 美元的 Poseidon1 碰撞獎金,原訂執行到 2029 年 1 月。本質上這是在試圖用兩年時間,買到 SHA-2 從 2001 年累積至今的檢視強度。
2026 年發生了三件事,把整個賭注掀掉:
2026 年 2 月,Vitalik Buterin 在回應「為什麼 Solana、Starknet、Stellar 都有 Poseidon precompile 而 Ethereum 沒有」時解釋,基金會針對 Poseidon2 跑了近兩年的密碼分析,已經發現需要「加 round 或退回 Poseidon1」的問題;把某個版本 enshrine 成 precompile,意味著問題發生時要遷移,並留下一個沒人用、但每個新客戶端都得實作的 precompile。
2026 年 8 月 1 日,基金會暫停了那筆 992,000 美元的碰撞獎金。
2026 年 8 月 13 日,Justin Drake 公開宣布基金會放棄在 Ethereum L1 使用 Poseidon,轉向 SHA 或 BLAKE,並稱之為「一個八年、八位數的兔子洞」的終結。
關鍵在於:沒有人破解 Poseidon。壓垮它的是等式的另一邊——為 hash 設計的 SNARK 追上來了。Drake 的總結是「關鍵不是 SNARK-friendly hashes,而是 hash-friendly SNARKs,秘密在於在最小的質數 2 上做算術」,也就是特徵為 2 的二元擴張體。當 prover 的原生體本來就是位元時,XOR、AND、rotate 這些讓 SHA-256 在大質數體上爆炸的操作,就不再昂貴。
Benjamin Diamond 與 Jim Posen 的 Binius 在 EUROCRYPT 2025 示範了這條路;2026 年 6 月 Benedikt Bünz、Ron Rothblum、William Wang 發表的 Flock 把它推到可用的量級。Flock 原型在單顆 Apple M4 Max 核心上的實測:
| Hash | compressions/秒(單核) |
|---|---|
| BLAKE3 | 82,100 |
| SHA-256 | 42,100 |
| Keccak(permutations) | 30,700 |
十核跑 BLAKE3 超過 660,000 compressions/秒,原生執行的 overhead 低於 250 倍。論文自稱在 SHA-256 上比 Binius64 快 9 倍以上,在 BLAKE3 上比 Binius64 和 Plonky3 快約 14 倍。
對 EIP-7864 的意義非常直接:草案裡那個「暫定用 BLAKE3、最終待定」的註記,在 2026 年 8 月之後BLAKE3 從權宜之計變成了主要候選。困擾這個 EIP 一年半的最大未定項,不是靠 Poseidon 被證明安全解決的,是靠 SNARK 追上標準 hash 解決的。
必須標注的存疑處:Drake 引用的「筆記型電腦上每秒約一百萬次傳統 hash 呼叫、約 100 倍原生 overhead」比已發表的 Flock 數據更樂觀,超出的部分來自一個叫 SNARK.fast 的自動化最佳化專案,目前沒有論文也沒有公開方法論——已標存疑。Flock 本身作者聲明是原型、不建議用於生產,且只支援固定布林電路的批次證明,不是通用計算。而「SHA 或 BLAKE」到現在仍是一份候選名單,沒有指定具體函數與參數集——SHA-2 有四分之一世紀的公開分析,BLAKE3 是 2020 年的設計,兩者的成熟度並不對等。
更正 5:「換 hash function 很容易」只在特定意義下成立
EIP-7864 說 hash 可以在 EIP 推進過程中更換,「對實作的影響最小」。這句話在「樹的形狀定義」這一層是對的——merkelization 規則寫成 internal_node_hash = hash(left_hash || right_hash),把 hash 換掉不影響結構。
但 EIP 自己在 Abstract 就列出了例外:如果選 Poseidon2,「需要額外規格來定義 field 選擇(BN254 scalar field、31-bit field elements 等)以及如何把 32-byte 值編碼成 field element」。也就是說,選算術 hash 不只是換函數,是把整棵樹的值域綁定到某個有限體上,連帶把未來能用的 proving system 也綁定了。Rothblum 對此的說法是:算術友善 hash 只在為它設計的那個體上便宜,選它就等於 enshrine 那個體,換 prover 或跨體組合時優勢就消失。
Poseidon 之所以能被輕鬆丟掉,正是因為 Vitalik 在 2026 年 2 月頂著壓力拒絕了 precompile。沒有 enshrine,就沒有遷移成本。這是 crypto-agility 最乾淨的實例:能換,是因為當初沒有焊死。而 Solana、Starknet、Stellar 選了另一邊。
五、遷移:樹換了,四億筆舊狀態怎麼辦
假設 EIP-7864 定案了。主網上已經存在的狀態不會自己變形。這件事需要兩個獨立的 EIP。
EIP-7612(Overlay Tree) 處理分叉當下:新樹從空的開始,MPT 被凍結。所有新的寫入進新樹;讀取先查新樹,查不到再回頭查凍結的 MPT。EIP-7864 的 Rationale 明說了這個設計:「這個 EIP 定義的新二元樹從空開始。只有新的狀態變更被存進樹裡。MPT 繼續存在但被凍結。」
EIP-7748(State conversion) 處理剩下的:等使用者自然把狀態搬過去太慢,所以每個區塊強制轉換固定數量的「conversion unit」。一個 conversion unit 是一個 storage slot,或一個帳戶的基本資料加上 code。轉換量由常數 CONVERSION_STRIDE 控制,而這個常數到今天仍然是 TBD。
幾個實作細節很有意思:
- 轉換步驟跑在交易執行之前。理由是如果放在之後,同一個區塊內交易的寫入可能和轉換寫入撞在一起,產生 stale 值問題;放在前面,只有前面區塊的寫入會造成 stale。
- 每個帳戶先轉 storage slot,轉完才轉帳戶資料與 code。這個順序「和許多執行層客戶端的 flat-db 架構協同,最小化隨機磁碟 IO」。
- 帳戶的 code chunk 化在一步內做完,不分攤到多個 stride。理由是簡化演算法,代價是最壞情況下單一區塊可能超額
24k / 31 ≈ 793個 unit。 - EIP-7610 提到的 28 個異常帳戶(nonce 為 0、無 code、卻有非空 storage tree)的 storage 直接跳過不轉——因為那些 slot 已經不可能被存取了。
- EIP 的「Expected time for the conversion to finish」這一節,內容是
TODO。
另外,EIP-7748 的標題到今天仍然寫著 “State conversion to Verkle Tree”,Requires 也仍指向 EIP-7612。作者群和 EIP-7864 高度重疊,轉換演算法本身與樹的具體形狀關聯不大(它做的是「遍歷 MPT、逐項寫進新樹」),但目前沒有看到專為二元樹寫的獨立轉換 EIP 編號——已標存疑。
最後一個後果非常實際,EIP-7864 的 Backwards Compatibility 只用一行帶過,但影響面極大:
Tree structure change makes in-EVM proofs of historical state no longer work.
所有在鏈上智慧合約裡驗證 MPT storage proof 的東西,在轉換後都會壞。跨鏈橋、需要證明「某個地址在某個區塊有某個餘額」的協議、部分 L2 的提款證明、各種 storage proof 為基礎的 oracle。這和昨天談的 EIP-4444 是兩種不同的壞:EIP-4444 是資料不在了(節點不再提供 146.77 天以前的區塊),樹轉換是資料還在但證明格式變了。前者可以靠 Portal 網路或 era 檔案救,後者需要合約改程式碼。
六、state expiry:講了六年,今天連 Draft 都不是
前面所有東西——定價、換樹、遷移——都沒有讓狀態變小,只是讓它長慢一點、驗快一點。真正能讓狀態縮小的是 state expiry:讓長期沒被碰的狀態從協議層消失。
目前最具體的方案是 EIP-7736: Leaf-level state expiry in verkle trees,2024 年 7 月 5 日由 Guillaume Ballet 與 Wei Han Ng 提出。它今天的狀態是 Stagnant(停滯)。
它的設計是刻意退讓過的。EIP 的 Motivation 直說:「先前的 state expiry 實作嘗試,都因為快速增長的複雜度而停滯,需要對 Ethereum 結構做大幅改動(address space extension、oil、多棵樹⋯⋯)。這個提案提供一個更簡單、雖然不徹底的方法:只刪 leaf 節點,樹的其餘部分保持完整。」
核心常數:
| 參數 | 值 |
|---|---|
EPOCH_LENGTH | 15,778,800 秒(6 個月) |
INITIAL_EPOCH_COUNTER | 0 |
NUM_ACTIVE_EPOCHS | 2 |
RESURRECT_TX_TYPE | TBD |
FORK_TIME | TBD |
驗算一下:15,778,800 ÷ 86,400 = 182.625 天,確實是半年。NUM_ACTIVE_EPOCHS = 2 表示同時有兩個 epoch 存活,所以實際的過期窗口是 182.625 × 2 = 365.25 天——正好一年。
規則:
- extension node 增加一個
last_epoch欄位 - 任何讀或寫,檢查
current_epoch < last_epoch + NUM_ACTIVE_EPOCHS,不成立就 revert - 只有寫入會把
last_epoch更新成current_epoch,讀取不會
最後這條的理由 EIP 講得很清楚,而且是整個設計裡最精妙的權衡。如果讀取也更新 epoch,那更新本身就是一次寫入,結果只能二選一:要嘛把讀取的價格提到寫入的等級(在 EIP-4762 已經漲過一輪之後再漲一次),要嘛讓使用者用讀取的價格做寫入的事——後者「既閹割了 state expiry,又可能製造 DoS 向量」。所以協議選擇了一個違反直覺的語意:你可以讀一個東西讀一整年,它還是會過期。
過期怎麼做: 每個區塊開始執行前跑 check_epoch_end,時間到了就 current_epoch += 1 並排程刪除 current_epoch − 2 的資料。但刪除時要保留兩樣東西作為「keepsake」(遺物):stem 值(這樣還能插入 sibling)和該節點的承諾 C。EIP 還提醒:實際刪除不應該發生在該 epoch 第一個區塊 finalize 之前,否則 reorg 就救不回來。
復活怎麼做: 新的交易類型 RESURRECT_TX_TYPE | ssz(Vector[stem, last_epoch, values])。先按 EIP-4762 的常數收費:
resurrect_gas_cost = WITNESS_BRANCH_COST
+ SUBTREE_EDIT_COST
+ Σ (WITNESS_CHUNK_COST + CHUNK_EDIT_COST + CHUNK_FILL_COST)
然後用提交的 values 和 last_epoch 重算承諾,跟保留的 keepsake 比對,對得上就把節點放回去、epoch 更新成當前。
為什麼不用 ASE: EIP-7736 的 Rationale 第一條就是「不需要 Address Space Extension」。ASE 是把 Ethereum 地址從 160 bits 擴到 256 bits,多出來的位元用來編碼「這個帳戶屬於哪個 epoch」,讓過期與復活可以只看地址判斷。這條路卡了很多年,主要障礙是:EVM 裡所有接受地址的 opcode 都會把運算元截成最低的 20 bytes,要改就得處理極複雜的向後相容,而且既有合約還是得更新。EIP-7676(EOF - Prepare for Address Space Extension)想利用 EOF 這個新格式,從一開始就不做 masking,繞開相容性問題。但 EOF 本身也還沒上主網——這條路線是兩個尚未上線的東西互相依賴。
在二元樹上怎麼掛: EIP-7864 的 Rationale 有一節 State-expiry,給了兩個掛載點。一是在 StemNode 加一個 epoch 欄位(就是 EIP-7736 的做法搬過來);二是把 stem 縮到 247 bits,騰出空間讓每個 stem 有兩棵 256 值的子樹——StemValuesNode 放實際值,StemMetaNode 放任意 metadata。第二個方案更通用,但顯然還沒定案。
更正 6:state expiry 不會讓現在的節點磁碟變小,至少一開始不會
這是關於 state expiry 最需要打破的期待。
先看窗口:NUM_ACTIVE_EPOCHS = 2 意味著任何在過去一年內被寫過的東西都活著。過期的只有真正的冷資料。有一個廣為流傳的數字說「約 80% 的 Ethereum 狀態超過一年沒被碰」——這個數字我只在二手來源看到,沒有找到一手測量,已標存疑。就算它是對的,第一次過期發生時,協議的狀態才剛從 MPT 轉成二元樹沒多久,而過期需要至少兩個 epoch(一年)的計時。
更根本的是:過期的資料還是得有人存著。復活交易需要提交完整的 values,如果全世界沒有人保存那份資料,那個 stem 就永久死亡了。EIP-7736 只做了一件事——把「必須保存」的義務從「每個全節點」改成「願意保存的 archive 提供者」。
這個結構和昨天談 EIP-4444 時的結論一模一樣:協議層解除義務,社會層產生義務。EIP-4444 之後,146.77 天以前的歷史需要 Portal 網路、EIP-7801 的分片、或 era 檔案來承接;state expiry 之後,過期的狀態需要一個等價的、目前完全不存在的基礎設施來承接。差別在於,歷史資料只需要「有一份」就能重放;過期狀態需要「使用者本人或某個服務」在需要復活的那一刻拿得出來,而且必須是那個 stem 下的全部 256 個值。使用者體驗上,這意味著一個放了兩年的錢包,可能需要先送一筆復活交易才能動——而復活所需的資料,得從某個第三方那裡拿。
這也是為什麼 EIP-7736 停滯了兩年多。它在技術上是可行的;它在「誰來承接」這件事上沒有答案。
七、statelessness 與 VOPS:2026 年實際在推的那條線
state expiry 是讓狀態變小;statelessness 是讓節點不必存狀態。後者理論上更徹底。
完全的 stateless 設計是:每筆交易自帶 witness,驗證者不需要任何狀態就能驗區塊。問題在 mempool。witness 會過期(前面的交易改了狀態,後面交易的 witness 就失效了),而且交易大小會暴增,p2p 傳播成本承受不住。這不是工程細節,是設計上的死結。
2026 年實際在推進的是 VOPS(Validity-Only Partial Statelessness,驗證性部分無狀態)。EF 的 2026 Protocol Priorities 把它列在 Thomas Thiery 負責的「Harden the L1」track 底下,和 FOCIL 的抗審查工作放在一起。它的做法不是要求所有交易帶 witness,而是分工:明確規定維護 mempool 的節點、includer、attester 各自最少需要存哪些狀態,才能在不附帶交易層 witness 的前提下保住共識規則。也就是說,不追求「沒有人存狀態」,而是追求「沒有人需要存全部狀態」。
EIP-7864 已經為此鋪路了。前面提到 storage type 前綴讓三種狀態分開存放,EIP 給的理由第一條就是 separate syncability:「可以只同步一棵子樹而不同步其他的。這在近期對於同步 VOPS 特別有價值。」節點可以選擇「我只存 header subtree,不存 storage subtree」,而因為每種類型在自己的子樹裡,更新狀態時需要維護的 sister node 不會跨類型糾纏。
八、2026 年 9 月 5 日的真實座標
把上面所有東西放進一張表,這是今天的實況:
| 主題 | EIP | 狀態(2026-09-05) |
|---|---|---|
| 統一二元狀態樹 | EIP-7864 | Draft,hash function 未定,常數表有矛盾 |
| Verkle 樹 | EIP-6800 | 實質讓位給 EIP-7864 |
| Overlay Tree(分叉時的雙樹讀取) | EIP-7612 | Draft |
| 狀態轉換程序 | EIP-7748 | Draft,標題仍寫 Verkle,CONVERSION_STRIDE = TBD |
| Leaf-level state expiry | EIP-7736 | Stagnant |
| ASE 準備(EOF) | EIP-7676 | 依賴尚未上線的 EOF |
| 狀態創建定價 CPSB | EIP-8037 | Review,Glamsterdam 排定納入 |
| 狀態存取定價 | EIP-8038 | Glamsterdam 排定納入 |
| 合約大小 24 → 64 KiB | EIP-7954 | Glamsterdam,被生態強力要求優先 |
| Block-Level Access Lists | EIP-7928 | Glamsterdam 執行層 headliner |
| 降低 intrinsic gas | EIP-2780 | Glamsterdam,ETH 轉帳最多便宜 71% |
Glamsterdam 本身:根據 ethereum.org 於 2026 年 8 月 6 日的更新,狀態是「Testing on devnets」,主網預期 Q4 2026(日期未確認),下一個里程碑是 2026 年 9 月 28 日的 Sepolia 分叉——也就是三週之後。EF 4 月的 Checkpoint #9 描述得更誠實:ePBS 比預期難搞,「協議現在必須處理兩方之間的分歧或失敗」,「每一層都得推理『部分區塊』」。
後續的 Hegotá 已經選定 FOCIL(EIP-7805)為共識層 headliner,66 個非 headliner 提案正在篩選中,目標是 2027 年有實際出貨機會的那一批。
而 EF 在 2026 年 2 月的 Protocol Priorities 對整個狀態議題的定位,一句話講完:
State scaling involving repricing and history expiry in the short term, and a move to binary trees and statelessness in the long term.
短期是重新定價與歷史過期,長期才是二元樹與無狀態。
所以 2026 年 Ethereum 對狀態膨脹的實際答案不是「刪掉狀態」,也不是「換一棵更好的樹」,而是「先把價格調對」。EIP-8037 是今年唯一真的會上主網的狀態相關 EIP;二元樹是 2027 年之後的事;state expiry 甚至不在 Hegotá 的討論範圍內。這個排序是有邏輯的——定價不需要協調任何資料結構遷移,不會弄壞任何鏈上證明,而且它爭取到的是時間:把 387 GiB/年壓回 120–160 GiB/年,就等於把那個八個月的懸崖推到兩三年之後,剛好夠二元樹從 Draft 走到主網。
🧠 記
- 狀態和歷史是兩種東西:歷史是完成的敘事,可以丟、可以事後重放;狀態是當下的事實,每個
SLOAD都得立刻答得出來。EIP-4444 只結清了一次帳,狀態的帳每個區塊都在加。 - 三個必記數字:2026 年 1 月 Geth 狀態庫約 390 GiB;gas limit 30M→60M 後每日新增狀態從 105 MiB 跳到 326 MiB(3.1 倍,不是 2 倍);650 GiB 是節點效能開始劣化的門檻。200M gas limit 下外推,八個月就撞牆。
- CPSB = 1530 gas/byte 的來源:
(150M / 2) × 2,628,000 ÷ (120 × 2³⁰) ≈ 1530。新帳戶 120 bytes、新 slot 64 bytes、7702 委派 23 bytes,乘出來就是 183,600 / 97,920 / 35,190。 - EIP-8037 真正的改動是二維 gas:execution-gas 和 state-gas 分開計,
gas_used = max(兩者),GASopcode 看不到 reservoir,gasleft()差值可能為負。用gasleft()差值計量的合約(包括 ERC-4337 EntryPoint)會壞。 - arity 2 的數學:分支大小 ≈
32 × (k−1) × log(N)/log(k),在 k=2 取最小。N=2²⁴ 時,k=2 是 768 bytes,k=16 是 2,880 bytes。 - 二元樹的目的是「能被證明」,不是「省磁碟」。code 進樹之後磁碟佔用甚至可能變大。省磁碟是 stateless 和 state expiry 的工作。
- Verkle 出局的兩個理由:橢圓曲線不是後量子安全的(NIST 建議 2030 停用 ECC),且部署 Verkle 保證未來還要再換一次樹;同時 SNARK 進步到不需要 Verkle 的小 proof。
- 2026-08-13 Ethereum L1 放棄 Poseidon,不是因為被破解,是因為 hash-friendly SNARK(Binius → Flock)讓標準 hash 在電路裡夠快了。Flock 在 M4 Max 單核跑出 82,100 BLAKE3 compressions/秒。這讓 EIP-7864 的 BLAKE3 從權宜之計變成主要候選。
- 能換 hash,是因為當初沒把它做成 precompile。Vitalik 在 2026 年 2 月頂著壓力拒絕 Poseidon precompile,六個月後省下了一次遷移。
- EIP-7736 的過期窗口是
182.625 天 × 2 = 365.25 天,而且只有寫入會續命,讀取不會——讀一整年也照樣過期。理由是讓讀取續命等於用讀取的價格做寫入,不是漲價就是 DoS。 - state expiry 停滯的原因不是技術,是「誰來保存過期資料以供復活」沒有答案。協議解除義務,社會層必須產生義務。這是 EIP-4444 同一個結構的重演。
- 樹換掉會弄壞鏈上的 MPT storage proof:跨鏈橋、storage proof oracle、部分 L2 提款證明。這和「歷史資料不見了」是不同的壞——資料還在,證明格式變了。
✍️ 實踐
1. 用 CPSB 重算自己合約的部署與運行成本。 拿現有合約的 runtime bytecode 長度 L,算 (120 + L) × 1530,和現在的 32,000 + 200 × L 對比。再數一下典型使用者路徑會產生幾個「0 → 非 0」的新 slot,每個乘 97,920。如果你的協議是每個新使用者開三到五個 slot(很常見的模式:餘額、授權、時間戳),那單一使用者的首次互動成本會從約 60,000–100,000 gas 跳到 294,000–490,000 gas。這個數量級的變化值得現在就重新設計 storage layout,例如把多個小欄位 pack 進同一個 slot。
2. 全文搜尋 gasleft()。 任何形如 uint g = gasleft(); doSomething(); uint used = g - gasleft(); 的程式碼,在 EIP-8037 之後可能得到負值。checked 算術會 revert,unchecked 會溢位成天文數字。已部署且不可升級的合約無法修復,只能在文件上標記風險並規劃遷移路徑。如果你在做 ERC-4337 相關的東西,直接去看 EIP-8037 的 Interaction with ERC-4337 bundles 一節。
3. 盤點鏈上的 MPT proof 驗證。 搜尋合約裡有沒有在做 RLP 解碼加 keccak 路徑驗證的邏輯(典型特徵:abi.decode 一串 bytes 陣列、迴圈做 keccak256、和一個 stateRoot 比對)。這些在狀態樹轉換後全部失效。現在就把清單列出來,並確認每個依賴點有沒有升級路徑——這件事的前置時間以年計,但真的發生時是硬分叉當天。
4. 實測自己的 state footprint。 對主要合約用 debug_storageRangeAt 或 Erigon 的 state 相關 RPC 掃一遍 storage,數出實際佔用的 slot 數,乘 64 bytes 就是你的協議對全世界每一個 Ethereum 全節點施加的永久負擔。把這個數字寫進協議的技術文件裡。這不是道德姿態——EIP-8037 之後它會直接變成使用者付的錢。
5. 讀 EIP-7864 的 get_tree_key_for_storage_slot,把熱資料放進低位 slot。 在新樹裡,一個帳戶的基本資料和最前面幾個 storage slot 住在同一個 stem,共用一次 branch opening;超出的部分要另外開 branch。這意味著storage slot 的編號會直接影響 gas 成本,這在 MPT 下是不存在的考量。設計 layout 時,把每次呼叫都會讀的東西擠進最前面的 slot。EIP 的常數表目前有矛盾(見更正 4),但「低位 slot 更便宜」這個方向是確定的。
6. 建立一個「規格原文優先」的習慣。 這一篇裡最有價值的數字全部來自 eips.ethereum.org 的原文和 EF 官方部落格,而搜尋結果的前幾條摘要至少有三處明確錯誤(把 Verkle 樹說成 Hegotá 的內容、把「節點儲存降低 90%」歸給二元樹、把 Glamsterdam 的時程說成 Q3)。EIP 是有版本、有狀態標記(Draft / Review / Stagnant / Final)的一手文件,查證成本比想像中低。
🔗 延伸學習
- EIP-8037: State Creation Gas Cost Increase — 今年唯一會上主網的狀態 EIP。Motivation 有 2026 年最新的狀態大小實測,Rationale 有 CPSB 的完整推導,Security Considerations 對
gasleft()和 ERC-4337 的警告尤其實用。 - EIP-7864: Ethereum state using a unified binary tree — 二元樹規格本體。arity=2 的數學論證、MPT 最壞情況 witness 的 330MB 計算、以及 Rationale 裡對 Verkle 與後量子的取捨說明,都值得完整讀一遍。
- Ethereum stateless book — Binary Tree — 由 stateless-consensus 維護的技術書,把 EIP-7864 的設計動機、與 Verkle 的對照、以及 hash function 選擇的 proving 效能問題,講得比 EIP 本身更好懂。
- Protocol Priorities Update for 2026(EF Blog, 2026-02-18) — 官方對 2026 三條 track(Scale / Improve UX / Harden the L1)的定義,以及「短期重新定價與歷史過期,長期二元樹與無狀態」這句路線判斷的出處。
- Glamsterdam | ethereum.org — 每次更新都標日期的官方進度頁,包含 EIP-8037、EIP-8038、EIP-7954、EIP-7928 的白話說明與最新時程。
💬 問 AI
我在研究 Ethereum 的狀態膨脹問題,請用一手規格為依據回答,每個數字都標出處(EIP 編號或章節),查不到就明說「查不到」,不要用記憶補。
1. 請完整重算 EIP-8037 的 CPSB。列出四個輸入參數(目標年增量、參考 gas limit、每年區塊數、平均利用率),逐步算到 1530,並說明「平均利用率取 50%」這個假設如果改成 70% 會得到什麼值,以及那代表什麼政策取向。
2. 用 EIP-8037 的常數,幫我算三個場景的 state gas:
(a) 一個部署後 runtime bytecode 為 12,000 bytes 的合約
(b) 一個使用者首次互動會寫入 4 個全新 storage slot 的協議
(c) EIP-7954 的 64 KiB 上限合約
每個都和現行定價對比,並說明在 60M / 150M / 200M 三種 block gas limit 下是否塞得進單一區塊。
3. 解釋 EIP-8037 的 reservoir model,包含:gas_left 與 state_gas_reservoir 的初始化公式、63/64 規則對哪一個適用、LIFO 回填的順序、以及為什麼 `GAS` opcode 只回傳 gas_left。然後具體說明這會如何影響 ERC-4337 的 EntryPoint。
4. 對比 EIP-7864(二元樹)與 EIP-6800(Verkle):列出至少五個維度(密碼學假設、proof 大小、proving 效能、後量子安全性、實作複雜度),並說明 2026 年 8 月 Ethereum L1 放棄 Poseidon 這件事,如何改變了 EIP-7864 的 hash function 選擇。
5. 解釋 EIP-7736 為什麼「只有寫入會更新 last_epoch,讀取不會」。把 EIP Rationale 給的兩個替代方案(讀取漲價 / 讀取價格做寫入)各自的後果講清楚。然後回答:一個使用者的錢包放置兩年後要復活,實際上需要從哪裡取得復活交易所需的 values?這個基礎設施今天存在嗎?
6. EIP-7864 的 Backwards Compatibility 說樹結構改變會讓 in-EVM 的歷史狀態證明失效。請列出至少四類會受影響的鏈上系統,並對每一類說明可能的遷移路徑。
7. 最後,請指出上面我的問題裡有沒有錯誤的前提、或我因為問法而漏掉的重要面向。