乙太坊的未來、數據可用性、Layer2 角色改變。
原文:What might an “enshrined ZK-EVM” look like?(ethereum.org)
編譯:Loopy Lu
出品:Odaily 星球日報
今日, Vitalik Buterin 在乙太坊社區發佈了一篇名為《內置 ZK-EVM 可能是什麼樣子的?》的新文章。 這篇文章探討了乙太坊在未來的網路升級中將如何內置自己的 ZK-EVM。
眾所周知,在乙太坊開發緩慢的背景下,目前幾乎主流 Layer 2 都已經擁有了 ZK-EVM,而當乙太坊主網封裝了自己的 ZK-EVM 之後,主網和 Layer 2 又是否會產生角色定位的衝突呢? Layer 1 和 Layer 2 又該如何有效的分工合作呢?
在本文中,Vitalik Buterin 強調了相容性、數據可用性和可審計性的重要性,並探索了實現高效和有狀態證明者的可能性。 此外,文章還探討了為提高效率實現有狀態證明者的可能性,並討論了 Layer 2 專案在提供快速預確認和 MEV 緩解策略方面的作用。 這篇文章反映了在保持乙太坊網路靈活性的同時,通過 ZK-EVMs 推進其發展的平衡。
Odaily 星球日報對原文進行了編譯,如下:
optimistic rollups 和 ZK rollup 作為乙太坊之上的 Layer-2 EVM 協定,都依賴於 EVM 驗證。 然而,這要求他們信任一個龐大的代碼庫,如果這個代碼庫中存在 bug,那麼這些虛擬機就有被駭客攻擊的風險。 這也意味著,ZK-EVM 即便是希望與 L1 EVM 保持完全等效,也需要某種形式的治理,以此來將 L1 EVM 的改變複製到它們自己的 EVM 實現中。
這種並不是一種理想的情況。 因為這些專案正在把乙太坊協定中已經存在的功能複製到自身中——乙太坊治理已經負責進行升級和修復 bug,ZK-EVM 基本上做的工作只是驗證 Layer 1 以太坊區塊。 在未來幾年中,我們預計輕用戶端將變得越來越強大,很快就能夠使用 ZK-SNARKs 來完全驗證 L1 EVM 執行。 到那時,乙太坊網路將實際上擁有一個封裝的 ZK-EVM。 因此,問題就出現了:為什麼不讓這個 ZK-EVM 對於 rollups 也是原生可用的呢?
這篇文章將描述「封裝 ZK-EVM」的幾個版本,分析其權衡、設計挑戰以及不走某些特定方向的原因。 實現一個協定功能的好處應該與讓生態系統處理事務並保持基礎協定簡單的好處相比較。
我們希望從封裝的 ZK-EVM 中獲得哪些關鍵特性?
基本功能:驗證乙太坊區塊。 該協定功能(目前還未確定是操作碼、預編譯還是其他機制)應該至少能接受預狀態根、一個區塊和后狀態根作為輸入,並驗證后狀態根實際上是在預狀態根之上執行該區塊的結果。 與乙太坊的多用戶端相容。 這意味著我們希望避免內置單一證明系統,而是允許不同的用戶端使用不同的證明系統。
這也意味著幾點:
數據可用性要求:對於任何使用封裝 ZK-EVM 證明的 EVM 執行,我們希望保證底層數據是可用的,這樣使用不同證明系統的證明者就可以重新證明執行,依賴該證明系統的用戶端就可以驗證這些新生成的證明。
證明位於 EVM 和區塊數據結構之外:ZK-EVM 功能不會真的將 SNARK 作為 EVM 內部的輸入,因為不同的用戶端會期望不同類型的 SNARK。 相反,它可能類似於 blob 驗證:交易可以包括需要證明的(預狀態、區塊體、後狀態)聲明,操作碼或預編譯可以訪問這些聲明的內容,客戶端共識規則會分別檢查數據可用性和區塊中所做聲明的證明。
可審計性:如果任何執行被證明,我們希望底層數據是可用的,這樣如果出現任何問題,用戶和開發者都可以檢查它。 實際上,這增加了一個更多原因,為什麼數據可用性要求很重要。
可升級性:如果發現某個特定 ZK-EVM 方案存在 bug,我們希望能夠迅速修復它。 這意味著不需要硬分叉就能修復問題。 這又增加了一個原因,說明在 EVM 和塊數據結構之外的證明很重要。
支援「近似 EVM」:L2s 的一個吸引力在於能夠在執行層進行創新,並對 EVM 進行擴展。 如果某個 L2 的 VM 只是稍微有點不同於 EVM,那麼如果 L2 可以對與 EVM 相同的部分使用原生的協定內 ZK-EVM,並且只依賴自己的代碼來處理不同的部分,這將是很好的。 這可以通過設計 ZK-EVM 功能來實現,使得調用者可以指定一個位域或操作碼或位址清單,這些將由外部提供的表格而不是 EVM 本身來處理。 我們還可以使 gas 成本在一定程度上可定製。
“開放式” 與 “封閉式” 多客戶端系統
“多用戶端思路” 可能是這個清單中最有爭議的要求。 一個選項是放棄多用戶端並專注於一個 ZK-SNARK 方案,這將簡化設計。 但代價是對乙太坊進行更大的「哲學轉變」(因為這實際上是放棄了乙太坊長期以來的多用戶端思路),並引入更大的風險。 在長期的未來,例如當形式驗證技術變得更好時,走這條路可能會更好,但目前看來風險似乎太大。
另一個選擇是封閉的多客戶端系統,其中有一個固定的證明系統集合,該集合在協定內已知。 例如,我們可能決定使用三個 ZK-EVM:PSE ZK-EVM、 Polygon ZK-EVM 和 Kakarot 。 一個區塊需要至少來自這三個中的兩個的證明才有效。 這比單一證明系統要好,但它使系統因為用戶必須為每個存在的證明系統維護驗證器,會有不可避免的治理過程來納入新的證明系統等原因而變得不那麼適應性強。
這促使我更傾向於一個開放的多客戶端系統,其中證明被放置在「區塊之外」,由客戶端分別驗證。 個別使用者會使用他們想要的任何客戶端來驗證區塊,只要有至少一個證明者為該證明系統創建證明,他們就能做到這一點。 證明系統將通過說服使用者運行它們來獲得影響力,而不是通過說服協定治理過程。 然而,這種方法確實有更多的複雜性成本,正如我們將看到的。
我們在 ZK-EVM 實現中想要什麼關鍵特性?
除了基本的功能正確性和安全性保證之外,最重要的屬性是速度。 雖然可以設計一個異步的協定內置 ZK-EVM 功能,每個聲明只在 N 個 slots 後返回結果,但如果我們能可靠地保證在幾秒鐘內就能生成一個證明,問題就會變得容易得多,這樣每個區塊中發生的事情就是自給自足的。
雖然今天為一個乙太坊區塊生成一個證明需要花費幾分鐘或幾小時的時間,但我們知道沒有理論上的原因阻止大規模並行化:我們總是可以集結足夠的 GPU 來分別證明區塊執行的不同部分,然後使用遞歸 SNARK 將這些證明組合在一起。 此外,通過 FPGA 和 ASIC 的硬體加速可以進一步優化證明過程。 然而,實際達到這一點是一個不容小覷的工程挑戰。
協定內 ZK-EVM 功能具體是什麼樣的?
類似於 EIP-4844 blob 交易,我們引入了一種包含 ZK-EVM 聲明的新交易類型:
class ZKEVMClaimTransaction(Container):
pre_state_root: bytes 32
post_state_root: bytes 32
transaction_and_witness_blob_pointers: List[ VersionedHash]
...
與 EIP-4844 一樣,在記憶體池中傳遞的物件是交易的修改版本:
class ZKEvmClaimNetworkTransaction(Container):
pre_state_root: bytes 32
post_state_root: bytes 32
proof: bytes
transaction_and_witness_blobs: List[Bytes[FIELD_ELEMENTS_PER_BLOB * 31 ]]
後者可以轉換為前者,但反之則不行。 我們還擴展了區塊 sidecar 物件(在 EIP-4844 中引入),以包含區塊中聲明的證明清單。
![](https://web3caff.com/wp-content/uploads/2023/12/image-460.png)
請注意,在實踐中,我們可能希望將 sidecar 拆分為兩個單獨的 sidecar,一個用於 blob,一個用於證明,並且為每種類型的證明設置一個單獨的子網(以及一個用於 blob 的附加子網)。
在共識層,我們添加了一個驗證規則,即只有當用戶端看到區塊中每個聲明的有效證明時,才會接受區塊。 證明必須是 ZK-SNARK 證明的串聯,是一對的 transaction_and_witness_blobs 序列化,並且 pre_state_root 使用(i)有效,並且 Witness(ii)輸出正確的 post_state_root.(Block , Witness)潛在地,客戶可以選擇等待多種類型證明的 M-of-N。
這裡的一個注意事項是,塊執行本身可以簡單地被視為需要與 ZKEVMClaimTransaction 物件中提供的三元組一起檢查的三元組(σpre,σpost, Proof)。
因此,使用者的 ZK-EVM 實現可以取代其執行用戶端; 執行用戶端仍將由(i)證明者和區塊構建者使用,以及(ii)關心索引和存儲數據以供本地使用的節點。
驗證和重新驗證
假設有兩個乙太坊用戶端,其中一個使用 PSE ZK-EVM,另一個使用 Polygon ZK-EVM。 假設此時,兩個實現都已經發展到可以在 5 秒內證明乙太坊區塊執行的程度,並且對於每個證明系統,都存在足夠多的獨立志願者運行硬體來生成證明。
不幸的是,由於獨立證明系統沒有被內置,因此它們不能在協定中得到激勵; 然而,我們預計與研發成本相比,運行證明者的成本較低,因此我們可以簡單地使用通用機構為證明者提供公共產品資金。
假設有人發佈了一個 ZKEvmClaimNetworkTransaction ,只不過他們只發佈了 PSE ZK-EVM proof 的一個版本。 Polygon ZK-EVM 的證明節點看到了這一點,並使用 Polygon ZK-EVM 的 proof 計算並重新發佈物件。
![](https://web3caff.com/wp-content/uploads/2023/12/image-459.png)
這增加了最早的誠實節點接受一個塊和最新的誠實節點接受相同的塊δ之間的總最大延遲: 2 δ+Tprove(假設 Tprove<5 s)。
然而,好消息是,如果我們採用單槽(slot)最終性(finality),我們幾乎可以肯定地可以將這種額外的延遲與 SSF 固有的多輪共識延遲一起「管道化」。。 例如,在 4 子插槽提案中,「頭部投票」步驟可能只需要檢查基本區塊的有效性,但隨後「凍結並確認」步驟將需要存在證明。
擴展:支援 “近似 EVM”
ZK-EVM 特性的一個理想目標是支援「近似 EVM」:即內置了一些額外功能的 EVM。 這可能包括新的預編譯、新的操作碼,甚至是合約可以在 EVM 或完全不同的虛擬機(例如,像 Arbitrum Stylus 中的)中編寫的選項,或者甚至是具有同步交叉通信的多個並行 EVM。
一些修改可以以簡單的方式支援:我們可以定義一種語言,允許 ZKEVMClaimTransaction 傳遞修改後的 EVM 規則的完整描述。 這可以做到:
- 自訂 gas 表(使用者不能減少 gas 成本,但可以增加)
- 禁用某些操作碼
- 設定區塊編號(這將根據硬分叉而隱含不同規則)
- 設置一個標誌,用於啟動一整套 EVM 更改,這些更改已針對 L2 使用而非 L1 使用進行標準化,或其他更簡單的更改
為了讓使用者以更開放的方式添加新功能,通過引入新的預編譯(或操作碼),我們可以在 ZKEVMClaimNetworkTransaction 的 blob 中加入一個預編譯輸入/輸出記錄:
class PrecompileInputOutputTranscript(Container):
used_precompile_addresses: List[Address]
inputs_commitments: List[VersionedHash]
outputs: List[Bytes]
EVM 執行將按以下方式修改。 初始化一個空的輸入陣列。 每當 used_precompile_addresses 中的位址被調用時,我們向 inputs 添加一個 InputsRecord(callee_address, gas, input_calldata)物件,並將調用的 RETURNDATA 設置為 outputs[i]。 最後,我們檢查 used_precompile_addresses 是否總共被調用了 len(outputs)次,並且 inputs_commitments 是否與對輸入的 SSZ 序列化生成 blob 承諾的結果匹配。 暴露 inputs_commitments 的目的是為了讓外部的 SNARK 更容易證明輸入和輸出之間的關係。
請注意輸入和輸出之間的不對稱性,輸入存儲在哈希中,而輸出存儲在必須提供的位元組中。 這是因為執行需要由只看到輸入並理解 EVM 的用戶端來完成。 EVM 執行已經為他們生成了輸入,所以他們只需要檢查生成的輸入是否與聲稱的輸入匹配,這只需要一個哈希檢查。 然而,輸出必須完整地提供給他們,因此必須是可用的數據。
另一個有用的功能可能是允許「特權交易」,這些交易可以從任意發送者賬戶發起調用。 這些交易可以在兩個其他交易之間運行,或者在調用預編譯時,作為另一個(可能也是特權的)交易的一部分運行。 這可以用來允許非 EVM 機制回調到 EVM 中。
這種設計可以修改以支援新的或修改後的操作碼,除了新的或修改後的預編譯。 即使只有預編譯,這種設計也相當強大。 例如:
- 通過將 used_precompile_addresses 設置為包括狀態中帶有某些標誌的普通帳戶位址清單,並製作一個 SNARK 來證明它是正確構建的,你可以支援 Arbitrum Stylus 風格的功能,其中合約可以用 EVM 或 WASM(或另一個 VM)編寫。 特權交易可以用來允許 WASM 帳戶回調到 EVM 中。
- 通過添加一個外部檢查,以確保多個 EVM 執行的輸入/輸出記錄和特權交易以正確的方式匹配,你可以證明一個通過同步通道相互交談的多個 EVM 的並行系統。
- 一種 4 型 ZK-EVM 可以通過擁有多個實現來操作:一個直接將 Solidity 或另一種高級語言轉換為對 SNARK 友好的 VM,另一個將其編譯為 EVM 代碼並在內置的 ZK-EVM 中執行。 第二種(不可避免地更慢的)實現只能在故障證明者發送一個斷言存在 bug 的交易的情況下運行,如果他們能提供兩者處理不同的交易,則收集賞金。
- 一種純異步 VM 可以通過使所有調用返回零並將調用映射到添加到區塊末尾的特權交易來實現。
擴展:支持有狀態的證明器
上述設計的一個挑戰是它完全無狀態,這使得它在數據上效率低下。 在理想的數據壓縮情況下,與僅有狀態壓縮相比,使用有狀態壓縮的 ERC 20 發送可以高達 3 倍的空間效率。
![](https://web3caff.com/wp-content/uploads/2023/12/image-458.png)
此外,有狀態的 EVM 不需要提供見證數據。 在這兩種情況下,原則是相同的:當我們已經知道數據是可用的,因為它是在以前的 EVM 執行中輸入或產生的,那麼要求數據是可用的就是一種浪費。
如果我們想讓 ZK-EVM 特性具有狀態,那麼我們有兩個選擇:
1)要求 σpre 要麼為空,要麼是已聲明鍵和值的可用數據清單,要麼是某次之前執行的 σpost 。
2)向(σpre, σpost, Proof)三元組中添加一個對區塊生成的收據 R 的 blob 承諾。 任何以前生成或使用的 blob 承諾,包括那些代表區塊、見證、收據甚至是普通的 EIP-4844 blob 交易的承諾,可能有一些時間限制,可以在 ZKEVMClaimTransaction 中引用,並在其執行期間訪問(可能通過一系列指令:“將承諾 i 的位元組 N... N+k-1 插入到區塊+見證數據的位置 j “)。
選項一意味著:與其內置無狀態 EVM 驗證,不如內置 EVM 子鏈。 選項二本質上是創建一個最小的內置有狀態壓縮演算法,它使用以前使用或生成的 blob 作為字典。 這兩種方法都會給證明者節點帶來負擔,只有證明者節點需要存儲更多資訊; 在情況二中,比起情況一更容易讓這種負擔有時間限制。
封閉式多證明器和鏈下數據的參數
一個封閉的多證明者系統,其中有一個固定數量的證明系統在一個 M-of-N 結構中,避免了上面的很多複雜性。 特別是,封閉的多證明者系統不需要擔心確保數據在鏈上。 此外,一個封閉的多證明者系統將允許 ZK-EVM 證明鏈下執行; 這使其與 EVM Plasma 解決方案相容。
然而,一個封閉的多證明者系統增加了治理複雜性並移除了可審計性,這些是高昂的成本,需要與這些好處相權衡。
如果我們將 ZK-EVM 內置並使其成為協定特性,那麼 “Layer 2 專案” 的角色是什麼?
目前由 Layer 2 團隊自己實現的 EVM 驗證功能將由協議處理,但 Layer 2 專案仍然負責許多重要功能:
- 快速預確認:單個 slot 的最終確定性可能會使 Layer 1 的 slot 變慢,而 Layer 2 專案已經在為其使用者提供 “預確認”,這些預確認由 Layer 2 自身的安全性支援,延遲遠低於一個 slot。 這項服務將繼續完全由 Layer 2 負責。
- MEV(礦工可提取價值)緩解策略:這可能包括加密的 mempool、基於聲譽的排序器選擇,以及 Layer 1 不願意實現的其他功能。
- 對 EVM 的擴展:Layer 2 專案可以為其使用者提供對 EVM 的重大擴展。 這包括「近似 EVM」和像 Arbitrum Stylus 的 WASM 支援以及對 SNARK 友好的 Cairo 語言這樣的根本不同的方法。
- 面向使用者和開發者的便利性:Layer 2 團隊在吸引使用者和專案到他們的生態系統並使他們感到受歡迎方面做了很多工作; 他們通過在其網路內捕獲 MEV 和擁堵費用來獲得補償。 這種關係將繼續存在。
免責聲明:作為區塊鏈資訊平臺,本站所發佈文章僅代表作者及嘉賓個人觀點,與 Web3Caff 立場無關。 文章內的資訊僅供參考,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。