原文標題:Announcing Zeth: the first Type Zero zkEVM
作者:Tim Cartens, Victor Graf, Rami Khalil, Steven Li, Parker Thompson, Wolfgang Welz, Zeth Collaboration
編譯:bayemon.eth, ChainCatcher
8月25日,基於RISC Zero zkVM 的以太坊開源ZK 區塊驗證器Zeth 公開發布。 Zeth 通過在zkVM 中完成構建新區塊所需的全部工作,而無需依賴驗證器或同步委員會。 Zeth 已在以太坊主網的多個真實區塊上得到驗證,並通過了以太坊官方測試套件的所有相關測試。 Zeth 能夠在4週之內實現基於zkVM 的Rust 支持和包括revm、etherthers 和alloy 在內的強大板塊。通過zkVM 對連續性和Bonsai 證明服務的支持,Zeth 可以在幾分鐘內生成這些證明。有了Zeth對鏈上驗證的支持,任何人都能以低成本在鏈上驗證這些證明。在這篇文章中,我們將介紹更多細節,如果你想深入了解代碼,請查看源代碼並訪問RISC Zero 開發者門戶網站。
摘要
大約一年前, Vitalik 在zkEVM的不同類型中闡述:
以太坊最初並不是圍繞ZK 友好性設計的,因此以太坊協議中有許多部分需要大量計算來進行ZK 驗證。 1類EVM的目標是完全複製以太坊,因此它無法緩解這些低效問題。目前,以太坊區塊的證明需要數小時才能完成。
雖然在以太坊發展史上已經有相關案例可以實現,但今天我們很高興地宣布,使用RISC Zero 的zkVM 和Bonsai 服務的以太坊區塊證明只需幾分鐘,而不是幾小時。
Zeth:可驗證的以太坊區塊生成
今天,我們在RISC Zero zkVM 上為以太坊發布了開源ZK 區塊驗證器Zeth。
Zeth 可以證明給定的以太坊區塊是有效的,而無需依賴驗證器或同步委員會。這是因為Zeth 在zkVM 中完成了生成新區塊所需的所有工作,包括:
- 驗證交易簽名
- 根據父區塊的狀態根驗證賬戶和存儲狀態。
- 應用交易
- 向區塊作者支付費用。
- 更新狀態根
- 其他生成區塊需要的工作
生成新區塊後,Zeth 會計算並輸出它的哈希值。通過在zkVM 中運行這一過程,我們就能獲得新區塊有效的ZK 證明。
通過利用RISC Zero 的zkVM 和流行的Rust crates(如revm、ether 和alloy),我們在不到4 週的時間內就編寫出了Zeth 的第一個版本。通過zkVM 對連續性和Bonsai 證明服務的支持,證明生成可以在僅僅幾分鐘之內完成。有了對鏈上驗證的支持,我們就能以低成本在鏈上驗證這些證明。
Zeth 已在以太坊主網的多個真實區塊上得到驗證,並通過了以太坊官方測試套件的所有相關測試。
由於Zeth 構建了標準的以太坊區塊,因此可以將其視為1 類zkEVM。但它的意義遠不止於此:因為Zeth 是使用標準的Rust 代碼板(與Reth 等流行的全節點使用的代碼板相同)構建的,所以我們更願意將其視為0 類zkEVM:完全的協議兼容性,以及大量的代碼復用。
這一里程碑代表著ZK 技術和以太坊生態系統向前邁進了一大步。在這篇文章中,我們將討論如何在幾週內編寫出Zeth 的第一個版本、它的性能、工作原理以及這對ZK 項目的意義。
RISC Zero 使構建zk rollup、zkEVM、輕型客戶端和橋接器變得更加容易
我們編寫Zeth 出於以下兩個原因:
- 讓其他團隊更容易構建他們自己的ZK 驅動的基礎設施:ZK rollup、zkEVM、ZK 輕型客戶端、ZK 橋接器等。 Zeth 提供了為基於EVM 的區塊生成ZK 證明所需的一切。這是任何zkEVM 或橋接器的關鍵組件。 Zeth 基於revm 開源,因此項目開發者可以輕鬆修改或使用。證明可以在鏈上驗證(非常適合橋接器和L2),也可以在本地應用程序中驗證(非常適合全節點和輕客戶端)。
- 在Zeth的zkVM 中進行EVM 性能的相關研究,特別是與以太坊相關的任務。 (調查結果分析見下文)。
zk rollup 與zkEVM
作為0 類zkEVM,Zeth 使開發人員能夠構建具有完全本地EVM 和以太坊兼容的zk rollup。加之Zeth對鏈上證明驗證的支持,構建由ZK 驅動的L2 擴容方案將變得無比簡單。
現有的ZK rollups 和zkEVM 電路在設計上都是單片式的,如果開發人員不具備對ZK 密碼學的高水平理解,就無法進行升級。相比之下,基於zkVM 的Zeth 方法使任何開發人員都能根據自己的需要進行定制和修改。
Zeth 是基於revm 的開放源代碼,調整以支持其他zkEVM 和EVM 兼容鍊是一件相對容易的事。因此,Zeth 對於未來EIP的更新也會有相對更快的反應速度。此外,Zeth同時提供了模塊化功能,使開發人員能夠在其中構建自己的區塊構建邏輯。
我們希望Zeth做出的努力能使zk rollup和zkEVMs 民主化,要知道zk驅動的L2解決方案以前需要多年的研究開發與超過1 億多美元的資金,這是絕大多數項目都無法負擔的消耗。
輕型客戶端與橋
毫無疑問,信標鏈的引入是輕客戶端和橋接器的福音。這些技術建立在以太坊現已成熟的PoS模型之上,在每個人都遵守規則的前提下,使輕客戶端和橋接器可以輕鬆驗證最近的區塊,而無需重建這些區塊。
當然,質押的全部意義在於為遵守規則的節點提供經濟激勵。但是,Slashing加諸於節點的威脅並不能完全避免作惡——外部激勵因素會使利益的”天平”永遠向作惡方傾斜——而設計一個能正確處理這些惡性行為的輕型客戶端或橋樑是很難的。
有了Zeth 這樣的工具,節點作惡的風險就大大降低了。輕客戶端只需向zkVM添加幾個調用藉口,就能與Zeth集成;橋接器等鏈上應用程序可使用我們的鏈上證明驗證合約與Zeth集成。
在不久的將來,我們可以想像輕客戶端和橋接器使用ZK 證明來確定給定區塊是否有效。這種方法將大大降低風險,同時又不會顯著增加驗證區塊的成本。
這對於應用程序鏈、模塊化生態系統和新鏈來說尤為重要,因為它們還不具備以太坊大型完整節點社區所提供的同等級別的安全。
良好的基礎簡化項目開發流程
Zeth 基於RISC Zero zkVM ,以RISC-V 指令集架構為動力,能為開發者提供熟悉的編程體驗。但我們的zkVM 不僅僅是一個RISC-V 內核。我們還為哈希算法和簽名驗證等常見加密任務配備了加速電路。
這種混合方法(通用CPU 內核與加速電路的結合)為我們提供了兩全其美的解決方案:
- 支持主流編程語言。
- 關鍵加密操作的性能不打折扣。
因此,我們能夠使用來自revm、ether 和alloy 的現有Rust 代碼包快速構建Zeth。通過復用現有的板塊,我們在不到4 週的時間內就完成了Zeth 的第一個版本。這種速度在不太成熟的生態系統中是不可能實現的。
在性能方面,Zeth 利用了我們用於ECDSA 簽名驗證的加速器電路以及連續性–這是我們ZK 框架的一項新功能,可輕鬆使用並行工作的GPU 集群(使用nVidia CUDA 或Apple Metal)快速證明大型計算。 Continuations 易於使用:該功能透明地提供給在zkVM 中運行的所有訪客程序,即無需對代碼進行任何修改,它就能正常運行。
有了我們的zkVM,我們就能在幾分鐘內,而不是幾小時內,快速生成以太坊區塊有效性的ZK 證明。
性能
我們將介紹Zeth 區塊生成器的性能。 Zeth 仍是一個新產品,因此這些數據可能會發生變化;不過,我們希望提供一些具體數據,作為未來工作的基準線。
說到性能,有幾個因素需要考慮:
- 生成證明所需的計算資源。
- 生成證明所需的”牆上時間”(即用戶需要等待多長時間才能獲得證明)。
- 生成證明的總成本(美元)。
連續性
Zeth的zkVM 可以通過使用連續運行來調整性能。因此,我們需要暫停一下,討論一下“連續運行”是何種工作原理。
我們的zkVM 實現了標準的RISC-V 處理器。因此,執行以周期為單位。 (在我們的電路中,大多數RISC-V 指令的執行只需1 個週期,當然也有例外)。簡單的程序通常只需要幾十萬個週期來執行,但更複雜的程序可能需要幾十億個週期。
在典型的ZK 系統中,這些執行週期匯集成一個證明;隨著周期數的增加,生成證明所需的時間和內存也會增加。但我們的zkVM 並不遵循這些陳規,今年早些時候,我們率先推出了一項連續性新功能,改進了傳統證明模式生成的弊端。
在連續性方面,證明過程分為三個階段:
我們在非證明仿真器中執行所需的計算。在此過程中,我們會計算迄今為止已運行的循環次數。在可配置的時間間隔內,我們對程序的狀態進行快照。這就有效地將執行過程分割成多個片段。每個片段都很小,通常代表100 萬個或更少的周期。
這些片段被分配給一組證明生成工人。他們為其給定的程序段生成ZK 證明。重要的是,他們可以並行地完成這項工作。只要有足夠多的工人,就能在證明一個程序段所需的時間內證明所有程序段。由於網段較小,因此所需的時間通常很短(幾十秒)。
在生成分段證明時,它們會最終進行rollup。每次”rollup “操作都會獲取一對連續的分段證明,並為這些分段的組合生成一個新的證明。例如,如果片段1 證明程序從狀態A 過渡到了狀態B,而片段2 證明程序從狀態B 過渡到了狀態C,那麼rollup就證明程序從狀態A 過渡到了狀態C。如果有足夠多的工作人員,這可以在log(N) 時間內完成,其中N 是片段的數量。
當我們深入研究這些數字時,將會看到這些階段的實際效果。
構建一個以太坊區塊有多難?
首先,讓我們來看看構建以太坊區塊的複雜程度。在下表中,我們選取了一些現實世界中的以太坊區塊,並在zkVM 中使用Zeth 對它們進行了重構。
例如,區塊17606771 產生2131 個區段。每個區段最多代表2^20 個執行週期,因此整個計算最多需要2,234,515,456 個執行週期。
一般來說,我們看到一個典型的以太坊區塊需要20-4 億個週期來構建,但有時多達95 億個週期。 (起初,我們驚訝地發現這些差異並沒有反映在交易的Gas中。但進一步思考後,這就說得通了:Gas系統在設計時考慮的是常規執行,而不是ZK 證明)。
有了連續性,這種規模就很容易管理了。根據這些數據,一個有10,000 個節點運行zkVM 校驗器的點對點網絡足以實現最大區塊的最高並行驗證性能,而這只是以太坊目前擁有的700,000 個驗證器的一小部分。
生成證明需要多長時間?
為了收集一些基本的性能數據,我們啟動了一個帶有64 個GPU Worker 的Bonsai 測試實例。然後,我們要求它使用Zeth 證明區塊17735424(182 個事務,3242 個區段,或大約3.4B 個週期)。
要生成證明,zkVM 必須首先將執行分割成多個區段。在下面的截圖中,Executor 任務捕捉到了這一過程,該任務運行了10 分鐘。 (其中大部分時間是在做AWS 的事情,比如寫入網絡存儲)。在本地機器上,同樣的任務只需不到6 分鐘即可完成。我們希望在未來一年內大大縮短這個時間)。
執行器最終將執行分成了3242 個片段。對於僅有的64 個GPU 來說,這是一個很大的分段。因此,每個工作節點必須生成50 個分段證明。如下圖所示,這需要35 分鐘。如果我們有50 倍的工作節點,則只需要42 秒。
分段證明完成後,開始rollup。由於有3242 個分段,我們需要執行log_2(3242) = 12 輪的rollup過程。在rollup的早期階段,工作量比工人多;因此第一階段耗時1 分鐘,第二階段耗時35 秒,第三階段耗時25 秒,等等。到了第七階段,時間穩定在5 秒多一點。同樣,如果我們有更多的工人,每個階段都只需要5 秒鐘。
rollup完成後,結果將被最終確定,這又需要一分鐘時間。
因此,在集群規模不足的情況下,我們能夠在大約50 分鐘內生成證明(有效速度為1.1 MHz)。如果集群規模適當,我們估計生成證明的速度會更快:
在完全並行的情況下,證明步驟可在42 + 12 * 5 + 60 秒或2 分42 秒內完成。
如果我們保守地四捨五入並將執行器時間計算在內,則時間大約在9 到12 分鐘之間(有效速度為4.7 MHz – 6.3 MHz)。
隨著我們對執行器和證明框架的不斷改進,我們樂觀地認為,在未來一年內,這個時間將大大縮短。
生成證明的資源消耗
上述測試集群已部署到AWS。它由64 個g5.xlarge 證明節點和1 個m5zn.xlarge 執行節點組成。根據亞馬遜的說法,每個g5.xlarge 節點都有
- 1 個GPU,擁有24 GiB GPU 內存
- 4 個vCPU,內存容量為16 GiB
在撰寫本文時,這些實例的按需價格為1.006 美元/小時,保留實例的優惠價格為0.402 美元/小時。與此同時,亞馬遜規格表顯示我們的m5zn.xlarge 節點擁有
- 4 vCPU,16 GB 內存
在撰寫本文時,該實例的按需價格為0.3303 美元/小時。
我們可以使用這些數字來粗略估算上文描述的區塊17735424 的證明成本。
回想一下,我們部署了64 個證明節點,在這種部署下,生成證明需要50 分鐘(端到端)。忽略空閒的工人時間,64 個證明節點加上一個執行節點,50 分鐘的成本為50/60 * (64 * 0.402 + 0.3303) = 21.72 美元。這是一個高估的數字,因為它假定我們要為閒置工人付費。如果我們不考慮閒置工人的成本(例如,關閉他們或讓他們從事其他工作),成本大約為19.61 美元。
- 這個區塊有182 筆交易,即每筆交易0.11 美元。
- 交易總價值為1.125045057 Eth,約合2137.59 美元。因此,每1 美元的證明可獲得109.01 美元的用戶資金。
- 同一區塊支付的獎勵為0.117623263003047027 Eth(不包括交易費)。在撰寫本文時,這大約是223.48 美元。因此,我們的證明大約花費了區塊獎勵的8.7%。
- 交易費加起來為0.03277635 Eth,即62.28 美元,是我們證明成本的3 倍多。
值得注意的是,這些美元估算與集群的規模無關!重要的是分段的數量。這是因為,1 台機器依次完成2 項工作的成本與2 台機器並行完成1 項工作的成本相同。因此,如果集群規模更大,生成證明的速度會更快,但成本不會更高。
有幾種方法可以進一步降低成本。除了繼續提高zkVM 的性能,或許還可以添加Keccak 加速器,我們還可以四處尋找更便宜的實例。重要的是,鑑於我們使用的機器規格較低(而且我們的zkVM 支持nVidia Cuda 和Apple Metal),這項工作可以通過由普通消費PC 和Mac 組成的p2p 網絡輕鬆完成。
鏈上驗證
如上所述,我們使用RISC Zero Groth16 校驗器驗證了Sepolia 上的Zeth 證明。這是RISC Zero 協議棧中相對較新的一部分,於本月初發布。它的工作原理是使用Bonsai 將zkVM 的原生STARK 證明轉換為等價的SNARK 證明,並將該證明提交給鏈上SNARK 校驗器。
如果我們將交易輸入視為UTF-8 數據,我們就會看到該證明對應於區塊17735424。
使用Bonsai,從STARK 到SNARK 的轉換耗時約40 秒。驗證SNARK 上鍊消耗了245,129 瓦斯(撰寫本文時約為5.90 美元)。
當然,zkVM 的一個優點是它可以將多個證明合併成一個。有了這項功能,就可以在鏈上驗證一整套證明,而無需使用任何額外的氣體。這樣,鏈上驗證的成本就可以分攤到整套證明中,從而降低了每個人的費用。
這對以太坊來說意味著什麼
如前所述,以太坊在設計時並沒有考慮到ZK 的友好性。正如zkEVMs 的情況所顯示的那樣,有很多事情可以用不同的方式來完成,特別是在操作碼、數字簽名和哈希函數方面。
雖然這些改動確實提高了性能,但我們仍然能夠在不使用這些改動的情況下實現穩定的性能。維塔利克去年撰文介紹不同類型的zkEVM 時,證明一個以太坊區塊的有效性需要幾個小時;而現在,我們可以在幾分鐘內完成。 ZK 性能正在飛速提升,我們有理由相信,這一趨勢將在未來幾年內持續下去。
附錄:Zeth的工作原理
這一部分是為開發商準備的。
粗略地說,Zeth 構建區塊的方式與完整節點相同:我們從父區塊、事務列表和區塊作者開始,然後進行大量計算(驗證簽名、運行事務、更新全局狀態等),最後返回新區塊的哈希值。
但與完整節點不同的是,我們是在zkVM 中完成這些工作的。這意味著我們會獲得一個ZK 證明,證明具有給定哈希值的區塊是有效的。
當然,這並非沒有挑戰。在本節中,我們將介紹這些挑戰以及我們是如何應對的。
密碼學
第一個挑戰是密碼學。構建一個以太坊區塊需要做大量的工作,其中最主要的是散列(Keccak-256)和簽名驗證(ECDSA 與secp256k1)。
我們的zkVM 對橢圓曲線有加速支持,因此ECDSA 簽名校驗並不難。
但說到散列,我們就沒那麼幸運了。我們的zkVM 對Sha2-256 提供了加速支持,但(在撰寫本文時)不支持Keccak-256。因此,目前我們只使用了sha3 Rust crate 中的Keccak 實現。通過剖析,我們知道這需要花費大量的周期。這並不是最佳方案,但我們的zkVM 可以處理它,而且我們還可以循環使用,並在以後添加Keccak 加速器。
賬戶和存儲:性能和安全
在以太坊中,賬戶和存儲由全球Merkle Patricia Trie(MPT)跟踪。
根據Etherscan 的數據,在撰寫本文時,這棵樹包含了近250,000,000 個唯一以太坊地址的狀態。從整體上看,這並不是一個很大的數據量,但它足以讓我們對其存儲和使用方式慎之又慎。尤其是,MPT 的性能至關重要。
但性能並不是唯一的因素,我們還必須考慮安全性。
Zeth 的區塊生成器是以客戶身份在zkVM 中運行的。這意味著它無法直接訪問以太坊p2p 網絡或其他RPC 提供商。相反,它必須依賴運行在zkVM 外部的獨立程序提供的數據。
在分析ZK 應用程序的安全性時,我們必須假設外部程序是惡意的,因此可能會提供惡意數據。為了防止這種情況,ZK 應用程序必須驗證提供給它們的數據是否有效。
對於Zeth 區塊生成器來說,這意味著要驗證所有相關賬戶和存儲的狀態(即運行給定交易列表所需的賬戶和存儲)。
幸運的是,EIP-1186 提供了這樣一種機制,它定義了一種通過Merkle 包含來證明給定賬戶(及其存儲)狀態的標準方法。
原則上,Zeth 的區塊生成器可以通過驗證一組EIP-1186 包含證明來驗證賬戶和存儲狀態。但這種方法並不理想。
相反,最好是使用EIP-1186 包含證明中的數據來構建部分MPT。這是一種MPT,只包含與給定交易列表相關的節點;不相關的分支只用相應的哈希值表示。你可以把部分MPT 視為梅克爾包含證明的一種”聯合”;或者,如果你願意,也可以把它視為梅克爾子集證明。
驗證部分MPT 的過程與驗證普通EIP-1186 證明基本相同:計算根哈希值,然後與父塊的狀態根進行比較。如果兩者相等,則可以信任其中賬戶和存儲的完整性。
部分MPT 經過驗證後,就可以應用交易並更新部分MPT。新的狀態根可以通過計算部分MPT 的新根哈希值獲得。
- 在運行Zeth 區塊生成器之前,我們先在沙箱中運行事務列表,以確定哪些賬戶和存儲是相關的。 (這個過程還能讓我們確定最老的相關前代區塊,這是支持blockhash() 查詢所必需的)。
- 我們為每個相關賬戶和存儲獲取EIP-1186 包含證明。 (我們還會獲取相關的前代區塊)。
- 我們使用這些包含證明來構建包含所有相關數據的部分MPT。
- 我們啟動zkVM,讓它運行Zeth 區塊生成器,並提供部分MPT 和其他輸入(父區塊、交易列表等)。
在zkVM 中,Zeth 塊生成器:
- 驗證部分MPT 根是否與父塊的狀態根相匹配。
- 驗證前代區塊的哈希鏈,直到父區塊。
- 應用事務。
- 更新部分MPT。
- 使用部分MPT 的新根哈希值作為新區塊的狀態根。
Zeth區塊生成器完成後,會輸出新區塊的哈希值。
這個哈希值包括對父區塊的承諾,因此也包括父區塊的狀態根(用於驗證原始的部分MPT)。這意味著惡意驗證者如果不提供無效的父塊,就無法為賬戶和存儲提供無效數據。
換句話說:如果父塊是有效的,那麼Zeth生成的新塊也是有效的。
因此,如果有人給你一個新區塊和一個由Zeth 生成的ZK 證明,你可以通過檢查以下三點來檢查該區塊的有效性:
- 確保ZK 證明有效且來自Zeth。對於鏈外應用,可使用zkVM Rust crate 提供的函數進行檢查。對於鏈上應用,可使用我們的鏈上證明驗證器進行檢查。
- 確保ZK 證明提交了新區塊的哈希值。
- 確保父區塊擁有你所期望的哈希值。
如果這些都檢查出來了,那麼新區塊就是有效的。
局限性和未來改進
我們這個項目的目標是研究區塊構造的性能。為此,我們決定將範圍限制在合併后區塊上。
此外,雖然Zeth 能夠證明給定區塊是有效的,但目前還不能證明共識(即該區塊確實包含在正則鏈中)。這一點在未來可能會有所改變,或許可以通過在zkVM 中添加驗證者或同步委員會簽名的檢查來實現。
最後,Zeth 是一款新軟件。雖然我們已經進行了一些測試(包括以太坊測試套件和各種現實世界的區塊),但Zeth 可能仍然包含一些錯誤。在撰寫本文時,它應被視為實驗性軟件。