
Dencun 是由 Deneb 及 Cancun 兩個名稱所組成,分別代表 Ethereum 共識層與執行層的硬分叉。Dencun 硬分叉已經在 Goerli、Sepolia 及 Holesky 測試網完成,主網將在 Epoch 269568(約為 2024 年 3 月 13 日)進行。
閱讀提示
在閱讀本文前,需要了解的先備知識包括:
-
硬分叉
-
Ethereum 分為共識層(Consensus Layer)及執行層(Execution Layer)
Dencun 升級包含 9 個 EIP,分別是:
-
EIP-1153: Transient storage opcodes(執行層改動)
-
EIP-4788: Beacon block root in the EVM(執行層與共識層改動)
-
EIP-4844: Shard Blob Transactions(執行層與共識層改動)
-
EIP-5656: MCOPY – Memory copying instruction(執行層改動)
-
EIP-6780: SELFDESTRUCT only in same transaction(執行層改動)
-
EIP-7044: Perpetually Valid Signed Voluntary Exits(共識層改動)
-
EIP-7045: Increase Max Attestation Inclusion Slot(共識層改動)
-
EIP-7514: Add Max Epoch Churn Limit(共識層改動)
-
EIP-7516: BLOBBASEFEE opcode(執行層改動)
這篇文章將介紹這幾個 EIP(不包含 EIP-4844)的改動與影響,EIP-4844 的介紹可以參考:
Rollup 的大補帖:Proto-Danksharding(一)
-
https://medium.com/taipei-ethereum-meetup/rollup-and-the-boost-from-proto-danksharding-85d2fe0566b6
Rollup 的大補帖:Proto-Danksharding(二)
-
https://medium.com/taipei-ethereum-meetup/rollup-proto-danksharding-implementation-detail-913a3c61fde8
接下來介紹與順序會大致區分為「執行層改動相關的 EIP」「共識層改動相關的 EIP」及「與 EIP-4844 相關的 EIP」。
EIP-1153
-
執行層改動
-
EIP-1153: Transient storage opcodes
-
https://eips.ethereum.org/EIPS/eip-1153
-
EIP-1153: fan page
-
https://www.eip1153.com/
-
EIP-1153: Transient storage opcodes
-
https://ethereum-magicians.org/t/eip-1153-transient-storage-opcodes/553
EIP-1153 新增兩個 Opcode:TSTORE 與 TLOAD,用來寫入與讀取「暫時的」Storage 數據。它們將可為許多合約開發者省下不少 Gas 成本。
背景
Storage 指的就是智能合約透過 SSTORE 這個 Opcode 將數據寫入到該合約的儲存空間中,數據寫入後是永久存在的,直到合約主動移除該筆數據為止。而「暫時的」這個特質則是相對於「永久存在」,TSTORE 寫入的數據有效期限只有到該筆交易結束為止,該筆交易執行完後 TSTORE 寫入的值就會被丟棄。
運作細節
TSTORE 相比於 SSTORE 便宜非常多,而其有效期限又能橫跨不同合約之間的呼叫(直到交易結束),不像 Memory 雖然便宜但 Memory 裡的值只專屬於每個合約自己,A 合約無法去讀取 B 合約的 Memory。這對許多用途非常有幫助:
-
Reentrancy Lock。目前 Reentrancy Lock 只能用 SSTORE 來仿真,雖然 SSTORE 的規則經過 EIP-2200 後有對 Reentrancy Lock 這樣的用途減輕不少 Gas 成本,但 TSTORE 可以將成本再大幅降低:從 5000 降為 100。
-
使用於單筆交易內的 ERC-20 approve。如果 A 合約和 B 合約進行交互,而 A 合約需要從 B 合約身上轉走 ERC-20,此時 B 合約會先對 A 合約做 approve ERC-20 的動作然後才呼叫 A 合約。因為 ERC-20 的 approve 都是透過 SSTORE 所以成本不低,改成使用 TSTORE 後將能大幅降低成本。
-
透過 CREATE2 部署合約時的部署參數。因為 Constructor 參數會影響 CREATE2 部署的合約地址,所以如果不想被 Constructor 參數影響的話,合約 Constructor 就會設計為去部署者合約的 Storage 讀取參數,例如 Uniswap V3 的 Pool。透過 TSTORE,這樣的模式就能省下許多成本。
注意事項
-
合約開發者在用 TSTORE 改寫自己的 Reentrancy Lock 時,記得還是要在該清空 Lock 時清空,不要想說交易結束後它會自己清空所以可省下清空的 Gas 消耗,否則交易過程中如果有需要再次進入合約的話就有可能因為 Lock 沒解鎖(沒清空)而無法進入。
-
EIP-1153 已經在 Solidity 0.8.24 版中推出,開發者可以提前試用。這裡有開發者實作的 Mutex 範例。仰賴 TSTORE 的 Uniswap V4 也將在 Dencun 升級完成後上線。
-
這個 EIP 新增新的 Opcode,所以開發者如果要部署合約到多鏈,要注意是否所有的鏈都有支持最新的 Opcode,否則將導致無法使用。
EIP-4788
-
執行層改動
-
EIP-4788: Beacon block root in the EVM
-
https://eips.ethereum.org/EIPS/eip-4788
-
EIP-4788: Beacon root in EVM
-
https://ethereum-magicians.org/t/eip-4788-beacon-root-in-evm/8281
EIP-4788 新增一個 BEACON_ROOTS_ADDRESS 合約來讓人讀取共識層區塊的數據,也就是執行層將能讀取到共識層的數據。透過這個合約,Staking 及 Restaking 協議可以在不信任任何第三方的前提下讀取並使用共識層的數據,例如讀取某個驗證者的狀態。
運作細節
使用者或合約可以透過呼叫合約的方式去查詢某個時間點的共識層區塊根(Beacon Block Root)。區塊根如同區塊內容的哈希值(Beacon Block Hash),是區塊內容透過 SSZ 編碼的方式所得到的 Merkle Tree 的樹根(Merkle Tree Root)。呼叫者將時間戳(timestamp)編碼成 uint256 的值並當作呼叫內容,合約會以時間戳去 Storage 尋找相對應的共識層區塊根並回傳。
開發者如果要使用共識層的信息,則他的合約會透過 BEACON_ROOTS_ADDRESS 合約查詢他要讀取的共識層區塊的區塊根,然後再搭配該共識層區塊的信息(例如某個驗證者的餘額)及 Merkle Proof 來驗證該信息是否屬於該區塊根。(SSZ 因為將內容都做成 Merkle Tree,所以內容裡任何信息都可以產生相對應的 Merkle Proof 來驗證該信息存在於該內容裡。)
△ 使用者提供 Merkle Proof 與共識層區塊的時間戳
△ Merkle Proof 搭配詢問區塊根來驗證某個時間點的驗證者餘額
不過 BEACON_ROOTS_ADDRESS 合約裡存的共識層區塊根其實是「母」區塊(也就是前一個區塊)的區塊根,而不是和執行層同一個區塊的區塊根。
△ Block 11001 的時間戳(1234567)對應的是 Block 11000 的區塊根。同樣地,Block 11000 的時間戳(1234555)對應的是 Block 10999 的區塊根。
注意事項
BEACON_ROOTS_ADDRESS 合約裡儲存最多 8191 個共識層區塊根,8191 個以前的區塊根會被覆寫。例如假設現在是 Block 18191,則當下能存取到區塊根範圍會是 Block 10000 到 Block 18190 的區塊根。
EIP-5656
-
執行層改動
-
EIP-5656: MCOPY – Memory copying instruction
-
https://eips.ethereum.org/EIPS/eip-5656
EIP-5656 新增一個 MCOPY Opcode,專門用來複製合約執行過程中 Memory 裡儲存的值。合約將可受益於這個 Opcode 節省的 Gas 成本。
合約開發者若要使用 MCOPY Opcode,需要將編譯程序版本指定為 0.8.24(或以上)以及 EVM 版本指定為 Cancun:
△ 要使用 MCOPY 需要設定編譯程序版本及 EVM 版本
註:0.8.24 版的編譯程序只開放透過 Assembly 的方式來使用 MCOPY(mcopy(),link),未來的版本才會自動由編譯程序來在需要複製 Memory 的地方套用 MCOPY。
注意事項
這個 EIP 新增新的 Opcode,所以開發者如果要部署合約到多鏈,要注意是否所有的鏈都有支持最新的 Opcode,否則將導致無法使用。
EIP-6780
-
執行層改動
-
EIP-6780: SELFDESTRUCT only in same transaction
-
https://eips.ethereum.org/EIPS/eip-6780
-
EIP-6780: Deactivate SELFDESTRUCT, except where it occurs in the same transaction in which a contract was created
-
https://ethereum-magicians.org/t/eip-6780-deactivate-selfdestruct-except-where-it-occurs-in-the-same-transaction-in-which-a-contract-was-created/13539
EIP-6780 修改了 SELFDESTRUCT Opcode 的行為,為 Verkle Tree 及淘汰 SELFDESTRUCT Opcode 做準備。合約有使用到 SELFDESTRUCT Opcode 的開發者需要特別注意。
背景
SELFDESTRUCT Opcode 目前的行為是:(1) 刪除該合約的代碼及 Storage,並 (2) 將身上的 ETH 全都轉給指定的地址。
一開始設計 SELFDESTRUCT Opcode 搭配 Refund 機制來激勵開發者移除用不到的合約及儲存空間,協助維持 Ethereum 狀態在一個適合的大小。但真的這麼做的人不多,反倒是出現像 Parity Multisig 這樣因為 SELFDESTRUCT 導致數十萬 ETH 凍結的意外,因此 Ethereum 社群希望能逐漸淘汰掉 SELFDESTRUCT Opcode。過去有不少修改或移除 SELFDESTRUCT Opcode 的提案,EIP-6780 是其中一個並且最終被收入進 Dencun 硬分叉中。
註:在 2023 年初的 Shanghai 硬分叉中,EIP-6049 已經正式宣告 SELFDESTRUCT 將會被淘汰。
Verkle Tree 是 Ethereum 社群目前正在積極研究與開發的狀態儲存結構,將用來取代目前的 Merkle Patricia Tree。Verkle Tree 將會讓 Ethereum 狀態的證明大小變得更小,因此也是 Stateless Client 設計中的關鍵。有了 Stateless Client,節點的硬體將會降低,讓更多人可以以更輕量、便宜的硬體來運行節點,提升網絡的去中心化程度。
運作細節
在 EIP-6780 後,SELFDESTRUCT Opcode 將會移除 (1) 的行為,只保留 (2)「將身上的 ETH 全都轉給指定的地址」的功能。合約的代碼及 Storage 都將維持不動,除非該合約是在同一筆交易創建然後又進行 SELFDESTRUCT。
所以當 SELFDESTRUCT 被觸發時:
-
如果合約不是在同一筆交易被創建,則合約的代碼及 Storage 都維持不動,但把身上的 ETH 全都轉給指定的地址。
-
如果合約是在同一筆交易被創建,則行為和原本(EIP-6780 以前)一樣:合約的代碼及 Storage 都會被移除,ETH 也會被轉給指定地址。
為了 Verkle Tree,必須移除 (1) 的行為
在 Verkle Tree 的設計中,其儲存狀態的方式和 Merkle Patricia Tree 不一樣。Merkle Patricia Tree 儲存狀態可以想像成是兩層(樹中樹)的結構:第一層是所有地址集合成的一棵樹,第二層是每個地址所有 Storage 及合成的一棵樹;而 Verkle Tree 則可以想像是一層、完全打平的結構。因此在 Merkle Patricia Tree 中我們可以很輕鬆定位一個地址的 Storage 並將其移除,但在 Verkle Tree 中則幾乎無法定位一個地址的 Storage,因為所有地址及地址的每個 Storage 值都被打平分散在同一棵樹中,無法輕易知道哪個值是屬於哪個地址的 Storage,所以我們沒辦法在 Verkle Tree 中移除合約代碼及它的所有 Storage。
△ 目前的狀態樹設計(Merkle Patricia Tree)是兩層結構:State Root 對應所有地址集合成的一棵樹,Storage Root 對應一個地址底下所有 Storage 及合成的一棵樹。
圖源: https://fisco-bcos-documentation.readthedocs.io/en/latest/docs/design/storage/mpt.html
△ Verkle Tree 狀態樹則是一層、完全打平的樹,
圖中紅色節點是地址,綠色節點是該地址的 Storage 值。
圖源: https://youtu.be/s7fm6Zz_G0I?t=572
△ 如果我們只移除紅色節點但沒移除 Storage(綠色節點們),則要是合約重新部署至同一個地址,它就會直接繼承舊的、沒有被刪除的 Storage,這會成為潛在的高風險漏洞。
圖源: https://youtu.be/s7fm6Zz_G0I?t=572
所以為了迎接 Verkle Tree,我們勢必得禁止 SELFDESTRUCT Opcode 可以移除合約代碼及 Storage 的行為。
注意事項
-
如果開發者使用 CREATE2 + SELFDESTRUCT 來重複部署到同一個地址,在 Dencun 後這將只會在同一筆交易內同時發生才能完成。
-
如果開發者使用 CREATE2 + SELFDESTRUCT 來達成合約升級的效用(因此 CREATE2 + SELFDESTRUCT 不會是在同一筆交易完成),在 Dencun 後將無法繼續,請改用一般不會 SELFDESTRUCT 的升級模式。
EIP-7044
-
共識層改動
-
EIP-7044: Perpetually Valid Signed Voluntary Exits
-
https://eips.ethereum.org/EIPS/eip-7044
-
EIP-7044: Perpetually Valid Signed Voluntary Exits
-
https://ethereum-magicians.org/t/eip-7044-perpetually-valid-signed-voluntary-exits/14348
EIP-7044 讓驗證者用來退出 PoS 的籤章變為永久有效,避免籤章因為網絡硬分叉而導致無效。委託給非託管質押服務(例如 Lido)的驗證者們的使用體驗與保障將可以提升:不必每次硬分叉就要請第三方重新籤名。
背景
Ethereum PoS 的驗證者需要有兩把私鑰:一把用於日常參與驗證(例如產區塊並籤名),稱作 Validator Key;另一把則是在退出 PoS 時領回質押資產及手續費的地址的私鑰,稱作 Withdrawal Key。當驗證者要退出 PoS 時,他會用 Validator Key 籤名,籤名的內容包含當前的網絡(硬分叉)版本。
在目前的非託管質押服務中,服務提供商手上會握有 Validator Key,使用者則是握有 Withdrawal Key,因此服務提供商只能執行日常的驗證相關的工作內容,不能領走使用者的質押資產及手續費,達到非託管的目的。而為了避免服務提供商以「不退出 PoS」來威脅敲詐使用者,服務提供商在一開始就會先籤好退出 PoS 證明並將此證明交給使用者,如此使用者就隨時都可以選擇退出 PoS,不受服務提供商影響。
運作細節
但因為退出 PoS 的籤名內容包含當前網絡(硬分叉)版本,例如當前的 Shanghai 或前一版的 Capella。而網絡會比對「退出證明裡的硬分叉版本」和「網絡當前的版本」,如果版本差異在兩個版本以上就會視為無效。也就是說隨著網絡不斷更新,進行硬分叉、升級到新版本後,太舊的退出證明就會無效。
例如目前共識層的硬分叉版本從舊到新分別是 Altair、Bellatrix 及(目前的)Capella。那在 Altair 那時籤的退出證明在現在就會變成無效;如果接下來更新至下一個版本 Deneb,那在 Altair、Bellatrix 那時籤的退出證明就會變成無效。為了應付這種狀況,使用者每次硬分叉時就要向服務提供商重新索取一次退出證明,如果使用者沒有提前拿到退出證明,那硬分叉後服務提供商就可能可以以「不退出 PoS」威脅敲詐使用者。
註:不過因為「退出 PoS」是在 Capella 之後才開放,所以可能沒有什麼人提前在 Altair 或 Bellatrix 就籤退出證明。
所以 EIP-7044 將退出證明裡的硬分叉版本固定在 Capella,如此在當前這個版本所籤的所有退出證明都將永久有效。而未來不管更新幾次,退出證明裡也都是籤 Capella,不會再受硬分叉版本所影響。
注意事項
因為退出證明的硬分叉版本已經固定在 Capella,所以如果有驗證者或服務提供商提前就籤了 Deneb 版的退出證明,在 Deneb 後反而會變成無效。
EIP-7045
-
共識層改動
-
EIP-7045: Increase max attestation inclusion slot
-
https://eips.ethereum.org/EIPS/eip-7045
-
EIP-7045: Increase max attestation inclusion slot
-
https://ethereum-magicians.org/t/eip-7045-increase-max-attestation-inclusion-slot/14342
EIP-7045 延長驗證者們的投票(Attestation)有效期,讓投票有更充足的時間能被收入,增加網絡的穩定性。對一般使用者或驗證者無影響。
背景
原本驗證者的投票(Attestation)有一個 Epoch(32 個 Slot)的時間可以被收入,例如假設驗證者 Alice 被分派在 Slot 10000 進行投票,而她因為網絡等待時間問題可能到了 Slot 10010 才完成投票或到了 Slot 10020 投票才成功廣播到 p2p 網絡中,但她的投票都還是會被收入。不過如果她的投票到 10033 Slot 才出現,那就沒辦法收錄她的投票,視同沒有投票。
運作細節
EIP-7045 將投票收錄的有效期限延長至最晚「投票的下一個 Epoch 結束前」都有效。例如假設驗證者 Alice 被分派在 Epoch 100 的 Slot 3205 進行投票,在 EIP-7045 之前,她的投票有效期限最晚是到 Slot 3237 (3237 = 3205 + 32);在 EIP-7045 之後,她的投票最晚到 Epoch 101 結束前(也就是 Slot 3263)都可以被收錄。
註:Epoch 0 包含的 Slot 是 0 到 31;Epoch 100 包含的 Slot 是 3200 到 3231;Epoch 101 包含的 Slot 是 3232 到 3263。
EIP-7514
-
共識層改動
-
EIP-7514: Add Max Epoch Churn Limit
-
https://eips.ethereum.org/EIPS/eip-7514
-
EIP-7514: Add max epoch churn limit
-
https://ethereum-magicians.org/t/eip-7514-add-max-epoch-churn-limit/15709
背景
從 2023 年上海升級開放驗證者退出 PoS 後,反倒吸引更多使用者加入成為驗證者,導致驗證者等待序列(Entry Queue)總是處於爆滿狀態,總驗證者數量也不斷高速上升。
△ Entry Queue 從開放退出 PoS 後反而激增。圖源: https://www.validatorqueue.com/
如果驗證者等待序列持續維持滿載的狀態,則從 2023 年 9 月(EIP 提出時)到 2024 年 5 月,約八個月的時間,就會有 50% 的 ETH 都將質押進 PoS;到了 2024 年 9 月就會有 75% ETH 質押。這麼多 ETH 質押有幾個缺點,例如驗證者數量太多,造成驗證者投票及聚合籤章數量太多,增加驗證者 p2p 網絡的負擔及共識鏈的狀態膨脹。另外也有人覺得 Ethereum 所需要的安全性並不需要這麼多 ETH 質押,多質押的 ETH 從安全性的角度是浪費。
而為什麼會持續有這麼多 ETH 湧入呢?因為即便到了 100% ETH 都質押,年化率仍然有約 1.6%,而且 Liquid Staking Token(LST)的出現近一步的提高資本利用效率,再加上 MEV 的收益,種種因素都讓質押變成一個非常吸引人的選項。
所幸質押熱潮在 2023 年下半年逐漸退去,減緩了驗證者數量成長的速度。
△ 2023 年下半年驗證者數量成長放緩,在 2024 年 2 月時約有 25% 左右 ETH 質押。圖源: https://www.validatorqueue.com/
運作細節
原本 Entry Queue 的數量上限是隨著當前驗證者人數而變動,每增加或減少 65536 個驗證者,Entry Queue 的數量上限就會增加或減少 1。2024 年 2 月的 Entry Queue 數量上限是 14 個(當前驗證者數量約為 95 萬)。
EIP-7514 會將 Entry Queue 數量上限固定在 8,不再隨著當前驗證者人數增加而提高,藉此減緩驗證者數量成長的速度,讓社群有更多時間能想出長期的解法,例如下一個硬分叉可能會收入的 EIP-7251。
EIP-4844 與 EIP-7516
-
EIP-4844: Shard Blob Transactions
-
https://www.eip4844.com/
-
Rollup 的大補帖:Proto-Danksharding(一)
-
https://medium.com/taipei-ethereum-meetup/rollup-and-the-boost-from-proto-danksharding-85d2fe0566b6
-
Rollup 的大補帖:Proto-Danksharding(二)
-
https://medium.com/taipei-ethereum-meetup/rollup-proto-danksharding-implementation-detail-913a3c61fde8
EIP-4844 新增新的交易種類,一個專門用來放 Blob 數據的交易。透過將數據放在 Blob 裡,Rollup 將可以進一步降低交易手續費。
EIP-4844 並非作為進行擴容升級的改動,而更像是「提升區塊 Gas Limit」並「降低成本」,讓區塊可以放入更多(Rollup)交易的一種提升交易量的改動。但 EIP-4844 同時也是為真正的擴容方案 – Danksharding 在進行鋪路。
另外 Blob 交易會和一般交易會是分開獨立的手續費市場,各自有各自的 Base Fee 及 Priority Fee,所以 EIP-7516 為 Blob 交易的手續費市場新增一個 BLOBBASEFEE Opcode(作用等同於一般交易的 BASEFEE Opcode),讓 Rollup 合約可以透過這個 Opcode 得知該 Blob 的 Base Fee 是多少。
總結與重點
-
Dencun 硬分叉由共識層的 Deneb 硬分叉及執行層的 Cancun 硬分叉所組成。
-
本次升級的主角是 EIP-4844,引入 Blob 交易格式讓 Rollup 能進一步降低交易成本,並同時為 Danksharding 鋪路。
-
共識層的改動包含 EIP-7044、EIP-7045 與 EIP-7514。
-
EIP-7044 讓使用非託管質押服務的驗證者在選擇退出 PoS 時能不受未來硬分叉所影響。
-
EIP-7045 及 EIP-7514 可視為增加 PoS 網絡穩定性的更新。
-
執行層的改動包含 EIP-1153、EIP-4788、EIP-5656、EIP-6780 與 EIP-7516。
-
EIP-1153 讓許多合約設計模式上能節省不少 Gas;EIP-5656 也是讓 Gas 成本能稍微降低。
-
EIP-4788 讓執行層能以不需信任第三方的方式讀取到共識層的信息,開啟更多質押相關服務的可能性。
-
EIP-6780 則是進一步淘汰 SELFDESTRUCT,拿掉它「移除合約代碼及狀態」的能力。
-
開發者需要注意使用 EIP-1153 時不要仰賴「暫時 Storage 在交易後會被清空」的假設,以及如果有使用到 SELFDESTRUCT,務必留意自己的合約會不會受影響。
-
一般使用者不需特別留意,只要等到 Rollup 採用 Blob 交易後就能享受到更低的交易成本。
參考數據與推薦延伸閱讀
EIP-1153
-
https://eips.ethereum.org/EIPS/eip-1153
-
https://www.eip1153.com/
-
https://ethereum-magicians.org/t/eip-1153-transient-storage-opcodes/553
-
https://hackmd.io/@-_WYFKbvSmip5m7MNB4b8A/SJFH66Eca
EIP-4788
-
https://eips.ethereum.org/EIPS/eip-4788
-
https://ethereum-magicians.org/t/eip-4788-beacon-root-in-evm/8281
EIP-5656
-
https://eips.ethereum.org/EIPS/eip-5656
EIP-6780
-
https://eips.ethereum.org/EIPS/eip-6780
-
https://ethereum-magicians.org/t/eip-6780-deactivate-selfdestruct-except-where-it-occurs-in-the-same-transaction-in-which-a-contract-was-created/13539
-
https://www.youtube.com/watch?v=s7fm6Zz_G0I
EIP-7044
-
https://eips.ethereum.org/EIPS/eip-7044
-
https://ethereum-magicians.org/t/eip-7044-perpetually-valid-signed-voluntary-exits/14348
EIP-7514
-
https://eips.ethereum.org/EIPS/eip-7514
-
https://ethereum-magicians.org/t/eip-7514-add-max-epoch-churn-limit/15709
EIP-4844 & EIP-7516
-
https://www.eip4844.com/
-
https://medium.com/taipei-ethereum-meetup/rollup-and-the-boost-from-proto-danksharding-85d2fe0566b6
-
https://medium.com/taipei-ethereum-meetup/rollup-proto-danksharding-implementation-detail-913a3c61fde8
-
https://eips.ethereum.org/EIPS/eip-7516
-
https://ethereum-magicians.org/t/eip-7516-blobbasefee-opcode/15761