Ethereum Fusaka 升級介紹

本文介绍了以太坊 Fusaka 硬分叉的主要内容,该分叉包含了13个EIP,涵盖了扩展、优化和改善用户体验等方面。重点介绍了PeerDAS、交易Gas上限、预先计算的出块者名单等关键EIP,以及它们对以太坊的性能、安全性和用户体验的影响。此外,还提到了客户端规则相关的EIP,以更好地掌握节点和验证者是否已升级到正确的版本。

Photo by Yusheng Deng on Unsplash

Fusaka 硬分叉已於 2025/12/03 於主網部署。Fusaka 包含 13 個 EIP,

接下來會將相關的 EIP 一起介紹,不會按照 EIP 號碼大小或以上順序介紹。

先備知識:

  • Ethereum 區分為共識層(Consensus Layer,CL)及執行層(Execution Layer,EL)

擴容相關 EIP

EIP-7594: PeerDAS — Peer Data Availability Sampling

PeerDAS 是 Fusaka 升級中最重要的改動:將 Blob 資料進行分片儲存,正式踏上資料擴容之路。如果要了解資料擴容以及 DAS(Data Availability Sampling)可以參考這系列文章:

Data Availability Sampling(一):為什麼會需要 DAS?

2024 年的 Dencun 升級中引入了 EIP-4844 Proto-Danksharding,開啟資料擴容的大門,也就是引入了 Blob 資料格式,讓 Rollup 們可以將各自的資料存放在便宜又大碗的 Blob 資料裡。如果要複習 EIP-4844 和 Blob 可以參考這一篇:

Rollup 的大補帖:Proto-Danksharding(一)

不過 EIP-4844 並還沒有真的開啟資料擴容,而是單純鋪好地基,引入 Blob 資料格式。怎麼樣才算真的開啟資料擴容?答案是網路要能隨著節點數量增加而處理更多的資料。如果每個新加入的節點都和舊節點一樣要「保存所有資料」,那網路就沒辦法真的擴容。而在 EIP-4844 中,其實所有節點都還是保存著所有資料,並沒有真的將資料進行分片。

EIP-7594 PeerDAS 正式將資料進行分片,節點不再需要下載並保管每一個完整的 Blob 資料,而是只需要保管其中的 1/8 份。只要由四個節點者拿著各自的 1/8 份資料拼湊成 1/2 份,就可以完整還原出原始資料。每個節點該保管第幾份則由它的 p2p 網路 ID 所決定,節點們會透過 p2p 網路以及節點網路 ID 去向彼此索取和提供資料。

Blob 資料(藍色)透過糾刪碼(Erasure Coding)擴展出冗餘部分(橘色),節點按照自己的 p2p 網路 ID 索取並保管相對應的片段。 src

只要有任意 50% 資料就可以還原出完整資料(藍色 + 橘色)。 src

註: 驗證者要保管比一般節點更多的分片(> 1/8),數量和驗證者質押金額成正比,達到質押金額上限(2048 ETH)的驗證者就會需要保管完整資料。

另外要注意的是資料分片發送後,接收方必須要有方式可以驗證「這真的是屬於原本 Blob 資料的第 X 份」,否則惡意人士就可以往 p2p 網路塞入一堆垃圾資料,騙其他節點們這些是有效的分片資料。在 EIP-4844 中我們引入了對 Blob 資料進行 KZG 承諾的運算,因此透過 KZG 承諾我們可以很方便快速地透過一個 KZG 證明來驗證「這真的是屬於原本 Blob 資料的第 X 份」,這個證明被稱作 Cell Proof。

每份片段要順便附上 KZG 承諾(藍點)以及相對應的 Cell Proof(卷軸)讓接收的人可以驗證,否則對方會直接拒收。 src

未來的 DAS 設計會再進一步降低每個節點保管的資料大小,代表擴容進一步提升。不過這也考驗網路的韌性以及還原機制的設計,因為每個節點保管的資料變少表示需要更多節點參與才能合力還原出原始資料。要考量的除了節點數量之外,還有時機點(什麼時候要觸發大家一起合力還原?要避免隨便就能被觸發,否則分片就等於白做工)、溝通管道(效率、頻寬)和誰來負責還原(因為這可能需要硬體資源足夠的節點來做)。

EIP-7825: Transaction Gas Limit Cap

在 EIP-7825 以前,每筆交易可以消耗的 Gas 值(Gas Limit)是無上限的,只要使用者付得出手續費。如果一筆交易的 Gas Limit 值設得特別大會有幾個缺點:

  • 排擠其他交易被收入的權利
  • 潛在 DoS 攻擊風險:交易的 Gas Limit 設得很高但實際執行時只消耗一點點,讓區塊瞬間空了一大塊用不到
  • 不利未來平行化交易驗證:平行化驗證將交易們分散成多個序列並同時進行驗證,但如果交易的 Gas Limit 都設成和區塊的 Gas Limit 一樣高,那其實平行化驗證就沒什麼意義了,因為每個序列都只能執行一筆交易

EIP-7825 將交易的 Gas Limit 設了一個上限:2²⁴ Gas(約為 16.78 M)。降低 DoS 攻擊風險外,也避免未來平行化驗證在使用者惡意或無意情況下做白工。

EIP-7935: Set default gas limit to 60M

目前節點預設的區塊 Gas Limit 值是 36M,之後驗證者們可以在每個區塊逐步調升區塊的 Gas Limit(每次增加不得超過 1/1024)。像是 投票 一樣,當驗證者們都有共識要將區塊 Gas Limit 調升至 45M 的話,那整個網路就會慢慢往目標前進。

從 30M 開始慢慢推進到目前的 45M。 src

驗證者們的投票趨勢。 src

但這個共識需要許多社交網路層面的大力宣傳,達成的速度也比較緩慢。某些驗證者背後的使用者未必有從社交網路上得知大家有這個目標,所以沒有一起參與。因此這個 EIP 便是藉由 Fusaka 升級來綁定調升區塊 Gas Limit 的目標,讓(預設的)區塊 Gas Limit 一次調升至 60M。

EIP-7892: Blob Parameter Only Hardforks

EIP-7892 將「每個區塊的 Blob 數量控制」從正式、大規模的升級(例如 Dencun、Pectra、Fusaka 等等)獨立出來。

Blob 資料格式在 Dencun 升級中引入,一開始定訂的目標 Blob 數量與上限數量分別是 3 與 6,接著在 Pectra 升級中調升至 6 與 9。雖然協調整個網路調整 Blob 數量並不會很困難,但其實它並不需要和正式、大規模的升級綁在一起,而是可以在社群經過壓力測試並達成共識的前提下一起進行調整,就像調整 Transaction Gas Limit 那樣。

EIP-7892 訂定「Blob 數量控制」自己的升級規則:所有客戶端只要一起更改「Blob 數量控制」的參數值即可,不需要配合一起升級客戶端,所以基本上不會有出錯的可能。不過因為是一個升級,所以還是要定訂一個生效時間點並要求所有客戶端在該時間點以前配合設置好參數及生效時間,否則網路一樣會出現硬分叉。

優化相關 EIP

EIP-7917: Deterministic proposer lookahead

EIP-7917 將共識層未來幾個 Epoch 的出塊者(Proposer)預先計算出來並儲存在共識層狀態裡,為出塊者名單提供可預測性,降低攻擊者影響出塊者名單的機會。

目前在共識層中下一個 Epoch 的出塊者名單都是在當前 Epoch 結束時才接著馬上計算,這是因為當初在設計時考量到驗證者在當前 Epoch 都有可能因為獎賞或懲罰而改變它們的押金數量,而押金數量會影響到一個驗證者被選為出塊者的機率,所以統一在一個 Epoch 結束後再按照所有驗證者最新的押金數量去選出下一個 Epoch 的出塊者。但這也給攻擊者一個潛在的攻擊向量:在最後一刻透過改變押金餘額的方式影響下一個 Epoch 的出塊者名單,藉此獲得優勢(如果沒優勢攻擊者就選擇不發動),這讓安全性分析變得更複雜。

因此 EIP-7917 規定要提前計算出未來 MIN_SEED_LOOKAHEAD 個 Epoch 的出塊者名單(MIN_SEED_LOOKAHEAD 是可調整的參數)並儲存在共識層狀態中,如此攻擊者就無法在最後一刻透過操控驗證者押金數量的方式去影響出塊者名單並獲得優勢。另外這對 Based Rollup 也有很大幫助。

Based Rollup Based Rollup 沒有一個中心化的排序器(Sequencer),而是由 Ethereum 出塊者們輪流擔任該 Rollup 的出塊者,藉此增加抗審查能力以及讓 Rollup 的部分獲利能回流到 Ethereum 上。而 Based Rollup 的合約中需要有機制能驗證 Ethereum 出塊者的身份,才能允許其擔任 Rollup 的出塊者,因此 EIP-7917 將未來數個 Epoch 的出塊者資訊寫入共識層狀態中後,Based Rollup 合約就能透過 EIP-4788 去讀取共識層狀態並解析出接下來的出塊者名單,如此就可以基於這個名單來驗證誰才有資格為其 Rollup 出塊。

EIP-7823: Set upper bounds for MODEXP

MODEXP 是一個預編譯合約,用來對模數做指數運算。相比於使用 EVM 位元組碼(Bytecode)來進行模數的指數運算,用 MODEXP 會更為便宜。不過當初在新增 MODEXP 預編譯合約時並沒有對輸入值的大小做限制,因此過去在許多測試案例中常常導致不同客戶端產出不一樣的結果,這在實際的鏈上發生的話會直接導致鏈的分叉。

EIP-7823 將 MODEXP 輸入值的大小限制在 8192 位元(Bits),8192 位元的大小涵蓋所有常見用例,也避免了可能的惡意輸入值導致非預期結果。

EIP-7883: ModExp Gas Cost Increase

EIP-7883 調高 MODEXP 預編譯合約的執行成本,因為原本的執行成本定價過低,被利用的話會導致對網路的 DoS 攻擊。

EIP-7934: RLP Execution Block Size Limit

EIP-7934 為執行層(Execution Layer)的區塊大小加了一個上限,避免攻擊者刻意產生很大的區塊導致效能較弱的節點跟不上驗證速度,或是因為區塊太大導致某些節點拒收(共識層的客戶端有對從 p2p 網路接收的區塊大小設一個 10 MiB 上限,避免被 DoS 攻擊)。

在 EIP-7934 之後,執行層的區塊大小最大為 8 MiB,超過就會直接被視為不合法的區塊。

註:這 EIP 保留一個 2 MiB(2 = 10 - 8)的空間給共識層區塊,因為共識層傳遞的內容是包含共識層區塊加上執行層區塊,而共識層 p2p 網路本身又有 10 MiB 大小上限,所以不能10 MiB 都給執行層區塊,否則共識層區塊加上去會超過 10 MiB。

EIP-7939: Count leading zeros (CLZ) opcode

EIP-7939 新增一個 CLZ 操作碼(Opcode),用來方便計算一個 256 位元的值的前面有多少個零。

計算「一個值前面有多少個零」是一個基本常見的運算功能,而 EVM 本身不支援這個原生運算,所以合約開發者或編譯器必須要用 SHR(Shift Right)這個操作碼來做這件事。有了 CLZ 這個操作碼之後,合約可以省下 Gas,本身的合約大小也可以減少。

EIP-7918: Blob base fee bounded by execution cost

EIP-7918 為 Blob 資料的成本設一個下限,避免 Blob 成本在總成本由「非 Blob 成本」所主導的情況下讓 Blob 的供需機制失靈。

Blob 資料的手續費和一般 Gas 的手續費一樣會在用量超過目標值時指數上升;在用量低於目標值時指數下降。但如果一般 Gas 的成本(即上述「非 Blob 成本」)遠大於 Blob 成本,例如市場熱絡導致 Gas Fee 大幅提升,此時 Rollup 們就會降低發佈資料的頻率,導致 Blob 需求降低及 Blob 手續費驟降,也就是 Blob 的供需機制反而被「非 Blob 成本」所影響而失靈。

EIP-7918 新增了一個 Blob 資料成本的下限:如果一般 Gas 消耗的成本大過於 Blob 資料成本的話,就不調降 Blob 手續費。判斷式如下:

if (
  BLOB_BASE_COST * parent.base_fee_per_gas # 1
  >
  GAS_PER_BLOB * get_base_fee_per_blob_gas(parent) # 2
)
  • #1: BLOB_BASE_COST 是這個 EIP 所新增的參數,是一個用來計算「Blob 對應到一般 Gas 」用的常數,所以它是乘上 base_fee_per_gas(也就是一般 Gas 手續費)
  • #2: 是原本 Blob 成本計算的方式,所以是乘上 base_fee_per_blob_gas

如果#1 > #2 就表示一般 Gas 成本高於 Blob 成本,那就不會扣掉「累積的 Blob 使用數」(稱為 excess_blob_gas),等同於 Blob 越用越多,所以即便實際上每個區塊的 Blob 使用數持續低於目標值,Blob 手續費也不會降低,甚至會緩慢上升。如果 #2 > #1,那就會按照原本 Blob 供需機制去調整「累積的 Blob 使用數」和 Blob 手續費。以下是計算「累積的 Blob 使用數」的函式,Blob 手續費會參考這個值來計算:

def calc_excess_blob_gas(parent: Header) -> int:
    target_blob_gas = GAS_PER_BLOB * blobSchedule.target # 每個區塊的 Blob 使用數目標值
    if parent.excess_blob_gas + parent.blob_gas_used < target_blob_gas:
        # 累積的 Blob 使用數本來就沒超過目標值,所以維持為零
        return 0

    if BLOB_BASE_COST * parent.base_fee_per_gas > GAS_PER_BLOB * get_base_fee_per_blob_gas(parent):
        #1 > #2,持續維持並累積 Blob 使用數
        return parent.excess_blob_gas + parent.blob_gas_used * (blobSchedule.max - blobSchedule.target) // blobSchedule.max
    else:
        #2 > #1,按照原本 Blob 供需機制新增或減少累積 Blob 使用數
        return parent.excess_blob_gas + parent.blob_gas_used - target_blob_gas

使用體驗相關 EIP

EIP-7951: Precompile for secp256r1 Curve Support

EIP-7951 將許多 L2 已經支援的預編譯合約 — secp256r1(或稱 P256)橢圓曲線的 ECDSA 簽章驗證 — 新增到 Ethereum 上。

secp256r1 橢圓曲線的 ECDSA 簽章驗證是目前越來越常見的 Passkey 的簽章演算法,使用者透過 Passkey 可以直接以硬體裝置(例如手機或電腦)本身的安全晶片裡的私鑰進行數位簽章。透過 Passkey,錢包可以提供非常流暢的上手體驗 — 使用者只需要掃臉或指紋即可創建錢包,不必再記下並保管好助記詞或私鑰。

註:Ethereum 和 Bitcoin 一樣最初都只有支援 secp256k1 橢圓曲線的 ECDSA 簽章驗證。

現在有 L2 都已遵循 RIP-7212 的標準將這個預編譯合約新增到本身的鏈上,增進使用者體驗。而 Ethereum 則因為需要更久的社群共識才有辦法新增,所以直到此次升級才完成。在這之前開發者只能直接寫一個智能合約來實作相關的驗證邏輯,但缺點是 Gas 消耗非常高。在這次升級之後,Ethereum 上的錢包也都能以相當便宜的方式驗證 Passkey 簽章,讓更多使用者體驗到流暢的錢包創建過程。

EIP-7951 在地址 0x100 上新增一個預編譯合約用來驗證 secp256r1 橢圓曲線的 ECDSA 簽章,每次呼叫會消耗 6900 Gas(不管驗證成功或失敗)。

註 1:0x100 地址是遵循既有的 RIP-7212 內容,讓所有鏈都能統一將這個預編譯合約部署在同一個地址。

註 2:常見的 ECRECOVER 預編譯合約(sepc256 k 1 的 ECDSA 簽章驗證)消耗 3000 Gas。

客戶端規則相關 EIP

EIP-7642: eth/69 — Drop pre-merge fields

EIP-7642 減少節點同步時所需的資料量以及支援「歷史資料刪減(History Pruning)」在 p2p 層所需要的功能。

1. 不再同步交易收據(Transaction Receipt)的 Bloom Filter 資訊

新的節點在加入後會從 p2p 網路同步所有歷史交易的收據的 Bloom Filter 資訊。Bloom Filter 資訊用來快速篩選出特定交易,但實際上節點同步完後並不會儲存 Bloom Filter 資訊,所以 EIP-7642 將 Bloom Filter 資訊的同步需求移除,當有使用者想要查訊特定交易時,節點再實時計算出 Bloom Filter 資訊即可。如此可為新節點所需的同步資料量節省約 530 GB。

2. p2p 節點支援告知、通知自己「儲存哪個範圍的歷史區塊資料」

在 Pectra 升級後,規定節點可以不再儲存 The Merge 前的歷史資料,因此 p2p 網路層也會需要相對應的改動來支援向 p2p 節點索取歷史資料。EIP-7642 規定 p2p 節點在告知其他節點自己的資訊時,要額外附上自己所儲存的歷史資料範圍(earliestBlock(Number)latestBlock(Number)),避免其他節點來向自己查詢自己沒有的資料而浪費時間。另外自己的儲存資料範圍有更新時也可以透過新增的通知格式去通知和自己有連結的 p2p 節點。

EIP-7910: eth_config JSON-RPC Method

EIP-7910 新增一個 JSON-RPC 接口供查詢一個節點的升級相關設定值,讓社群可以更好地在升級前掌握節點們及驗證者們是否都已經升級到正確的版本。

二月在 Holesky 測試網上的 Pectra 升級遭遇多數客戶端錯誤的升級參數設置,導致升級時多數錯誤的客戶端的驗證者們竟然分叉錯誤的鏈出去而且還成功完成區塊最終敲定(Finalize)。整個測試網最終花了兩週左右完成復原,將大多數驗證者們切換回正確的鏈,但也因此導致 Pectra 測試被延宕,最終社群決定下線 Holesky 並新起一個 Hoodi 測試網。

EIP-7910 為每個節點新增一個 eth_config 的 JSON_RPC 接口,讓別人可以查詢一個節點的「當前升級版本」、「下一次升級」及「最新已知升級」的相關設定值。每個升級的設定值包含:該鏈/升級的 ID、啟用時間或排定啟用時間、Blob 資料設定值、預編譯合約們及系統合約們。將預編譯合約與系統合約包含在內方便大家一起比對節點是否有為這些合約設定正確的地址,這也是 Holesky 的 Pectra 升級出錯主因。

參考資料與推薦延伸閱讀

TEM Medium 2025 有獎徵稿

TEM Medium 目前正在進行有獎徵稿!詳情請參考:

TEM Medium 有獎徵稿

Special thanks to

Kimi Wu

and Kevin Chia for reviewing and improving this post

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
EthTaipei
EthTaipei
Taipei Ethereum Meetup