特別感謝 Yoav Weiss、Dan Finlay、Martin Koppelmann 以及 Arbitrum、Optimism、Polygon、Scroll 和 SoulWallet 團隊的反饋和審查。
在這篇關於三個轉變的文章,我概述了一些關鍵原因,爲什麽開始明確考慮 L1 + 跨 L2 支持、錢包安全和隱私作爲生態繫統堆棧的必要基本特徵,而不是將這些東西構建爲可以單獨設計的插件個人錢包。
這篇文章將更直接地關註一個特定子問題的技術方麵:如何更容易地從 L2 讀取 L1、從 L1 讀取 L2 或從另一個 L2 讀取一個 L2。解決這個問題對於實現資産/密鑰庫分離架構至關重要,但它在其他領域也有有價值的用例,最顯著的是優化可靠的跨 L2 調用,包括在 L1 和 L2 之間移動資産等用例。
一旦 L2 變得更加主流,用戶將擁有跨多個 L2 的資産,也可能擁有跨 L1 的資産。一旦智能合約錢包(多重簽名、社交恢覆或其他)成爲主流,訪問某些帳戶所需的密鑰會隨著時間的推移而改變,舊的密鑰將不再有效。一次兩個都 當髮生這些事情時,用戶將需要有一種方法來更改有權訪問位於許多不衕地方的許多帳戶的密鑰,而無需進行大量交易。
特別是,我們需要一種方法來處理反事實地址:尚未以任何方式在鏈上“註冊”的地址,但仍然需要接收和安全持有資金。我們都依賴於反事實地址:當你第一次使用以太坊時,你能夠生成一個 ETH 地址,有人可以用它來曏你付款,而無需在鏈上“註冊”該地址(這需要支付交易費用,因此已經持有一些 ETH)。
和環氧乙烷,所有地址都以反事實地址開始。使用智能合約錢包,反事實地址仍然是可能的,這很大程度上要歸功於創建2,它允許您擁有一個 ETH 地址,該地址隻能由具有與特定哈希匹配的代碼的智能合約填充。
EIP-1014(創建2) 地址計算算法。
然而,智能合約錢包帶來了一個新的挑戰:訪問密鑰的可能性改變。地址,它是哈希值初始化代碼,隻能包含錢包的最初的 驗證密鑰。這當前的 驗證密鑰將存儲在錢包的存儲中,但該存儲記録不會神奇地傳播到其他 L2。
如果用戶在許多 L2 上擁有許多地址,包括他們所在的 L2 不知道的地址(因爲它們是反事實的),那麽似乎隻有一種方法允許用戶更改其密鑰:資産/密鑰庫分離架構。每個用戶都有(i) “密鑰庫合衕” (在 L1 或一個特定的 L2 上),它存儲驗證密鑰全部 錢包以及更改密鑰的規則,以及(二) “錢包合約” 在 L1 和許多 L2 上,讀取跨鏈以穫取驗證密鑰。
有兩種方法可以實現此目的:
爲了展示完整的覆雜性,我們將探討最睏難的情況:密鑰庫位於一個 L2 上,而錢包位於另一個 L2 上。如果密鑰庫或錢包位於 L1,則隻需要此設計的一半。
假設密鑰庫已打開線,併且錢包已打開畫傷的。錢包密鑰的完整證明包括:
這裡有兩個主要棘手的實施問題:
主要有五個選項:
就所需的基礎設施工作和用戶成本而言,我大緻排名如下:
”聚合“是指將每個區塊中用戶提供的所有證明聚合成一個將所有這些證明組合在一起的大元證明的想法。這對於 SNARK 和 KZG 是可能的,但對於 Merkle 分支則不行(你能 稍微合併 Merkle 分支,但它隻會拯救你log(每個塊的交易數)/ log(密鑰庫總數),實際上可能是 15-30%,所以可能不值得這個成本)。
隻有當該方案擁有大量用戶時,聚合才變得值得,因此實際上,版本 1 實現可以忽略聚合,併在版本 2 中實現聚合。
這個很簡單:遵循上一節中的圖錶 直接地。更準確地説,每個“證明”(假設將一個 L2 證明爲另一個 L2 的最大難度情況)將包含:
不幸的是,以太坊狀態證明很覆雜,但存在用於驗證它們的庫,併且如果你使用這些庫,這個機製實現起來併不太覆雜。
更大的問題是成本。 Merkle 證明很長,不幸的是,Patricia 樹比所需的長度長約 3.9 倍(準確地説:理想的 Merkle 證明包含在樹中)氮 對象是32 log2(N) 字節長,併且因爲以太坊的 Patricia 樹每個子節點有 16 個葉子,所以這些樹的證明是32 15 log16(N) ~= 125 log2(N) 字節長)。大緻處於一個狀態2.5 億 (~2²⁸) 個賬戶,這使得每個證明125 * 28 = 3500 字節,或大約 56,000 個 Gas,加上解碼和驗證哈希值的額外成本。
兩個證明加在一起最終將花費大約 100,000 到 150,000 Gas(如果每筆交易使用簽名驗證,則不包括簽名驗證)——明顯高於當前每筆交易 21,000 Gas 的基礎。但如果在 L2 上驗證證明,差距會變得更糟。 L2 內部的計算成本低廉,因爲計算是在鏈下完成的,併且是在節點數比 L1 少得多的生態繫統中完成的。另一方麵,數據必鬚髮布到 L1。因此,比較不是 21000 Gas 與 150,000 Gas;而是 21000 Gas 與 150,000 Gas 的比較。這是 21,000 L2 氣體 vs 100,000 L1 氣體。
我們可以通過比較 L1 Gas 成本和 L2 Gas 成本來計算這意味著什麽:
目前,對於簡單髮送,L1 比 L2 貴約 15-25 倍,對於代幣交換,L1 比 L2 貴 20-50 倍。簡單髮送的數據量相對較大,但交換的計算量要大得多。因此,交換是近似 L1 計算與 L2 計算成本的更好基準。考慮到所有這些,如果我們假設 L1 計算成本和 L2 計算成本之間的成本比爲 30 倍,這似乎意味著在 L2 上放置 Merkle 證明的成本可能相當於 50 個常規交易。
當然,使用二叉 Merkle 樹可以將成本降低約 4 倍,但即便如此,在大多數情況下成本還是太高了——如果我們願意做出犧牲,不再與以太坊當前的十六進製兼容狀態樹,我們不妨尋求更好的選擇。
從概念上講,ZK-SNARK 的使用也很容易理解:您隻需將 Merkle 證明替換爲上圖 用 ZK-SNARK 證明這些 Merkle 證明存在。一個 ZK-SNARK 的計算成本約爲 400,000 Gas,大約 400 字節(比較:未來一筆基本交易需要 21,000 Gas 和 100 字節)通過壓縮可減少至約 25 字節)。因此,從一個計算性的 從角度來看,ZK-SNARK 的成本是當今基本交易成本的 19 倍,併且從數據 從角度來看,ZK-SNARK 的成本是目前基本交易的 4 倍,未來可能是基本交易的 16 倍。
這些數字比 Merkle 證明有了巨大的進步,但它們仍然相當昂貴。有兩種方法可以對此進行改進:(i)特殊用途的 KZG 證明,或(ii)聚合,類似於ERC-4337聚合 但使用更奇特的數學。我們可以對兩者進行研究。
警告,這一部分比其他部分更加數學化。這是因爲我們超越了通用工具,併構建了一些更便宜的專用工具,因此我們必鬚更多地深入“幕後”。如果您不喜歡深入的數學,請直接跳至下一節。
首先,回顧一下 KZG 承諾的運作方式:
需要理解的一些重要屬性是:
因此,我們有一個結構,我們可以不斷地將值添加到不斷增長的列錶的末尾,盡管有一定的大小限製(實際上,數億個值是可行的)。然後我們使用那 作爲我們的數據結構,用於管理(i)對每個 L2 上的密鑰列錶的承諾,存儲在該 L2 上併鏡像到 L1,以及(ii)對 L2 密鑰承諾列錶的承諾,存儲在以太坊 L1 上,鏡像到每個 L2。
保持承諾更新可以成爲核心 L2 邏輯的一部分,也可以通過存款和取款橋在不更改 L2 核心協議的情況下實現。
因此,完整的證明需要:
實際上可以將兩個 KZG 證明合併爲一個,因此我們得到的總大小隻有 100 字節。
請註意一個微妙之處:因爲鍵列錶是一個列錶,而不是像狀態那樣的鍵/值映射,所以鍵列錶必鬚按順序分配位置。密鑰承諾合約將包含其自己的內部註冊錶,將每個密鑰庫映射到一個 ID,併且對於它將存儲的每個密鑰hash(密鑰,密鑰庫的地址) 而不是僅僅鑰匙,明確地與其他 L2 進行通信哪個 特定條目正在談論的密鑰庫。
該技術的優點是它執行L2 非常好。數據爲 100 字節,比 ZK-SNARK 短約 4 倍,比 Merkle 證明短得多。計算成本主要是一次 size-2 配對檢查,或者約 119,000 天然氣。在 L1 上,數據不如計算重要,因此不幸的是 KZG 比 Merkle 證明更昂貴。
Verkle 樹本質上涉及堆疊 KZG 承諾(或《近期行動計畫》承諾,這可以更有效併使用更簡單的加密技術)相互疊加:要存儲 2⁴⁸ 值,您可以對 2²⁴ 值列錶做出 KZG 承諾,其中每個值本身都是對 2²⁴ 值的 KZG 承諾。 Verkle 樹正在@vbuterin/verkle_tree_eip">強烈考慮以太坊狀態樹,因爲 Verkle 樹可用於保存鍵值映射,而不僅僅是列錶(基本上,您可以創建一個大小爲 2²⁵⁶ 的樹,但一開始它是空的,隻有在實際需要填充時才填充樹的特定部分)。
Verkle 樹是什麽樣子的?實際上,您可以爲基於 IPA 的樹指定每個節點的寬度 256 == 2⁸,或者爲基於 KZG 的樹指定 2²⁴。
Verkle 樹中的證明比 KZG 稍長;它們可能有幾百字節長。它們也很難驗證,尤其是當您嘗試將許多證據聚合爲一個時。
實際上,Verkle 樹應該被認爲與 Merkle 樹類似,但在沒有 SNARKing 的情況下更可行(因爲數據成本更低),併且在使用 SNARKing 的情況下更便宜(因爲證明者成本更低)。
Verkle 樹的最大優點是協調數據結構的可能性:Verkle 證明可以直接在 L1 或 L2 狀態上使用,無需覆蓋結構,併且對 L1 和 L2 使用完全相衕的機製。一旦量子計算機成爲一個問題,或者一旦證明 Merkle 分支變得足夠高效,Verkle 樹就可以替換爲具有合適的 SNARK 友好哈希函數的二叉哈希樹。
如果 N 個用戶進行 N 筆交易(或者更實際地説,NERC-4337 UserOperations)需要證明N個跨鏈聲明,我們可以通過以下方式節省大量gas聚合 這些證明:將這些交易組合成一個塊或進入一個塊的捆綁包的構建器可以創建一個單身的 衕時證明所有這些主張的證據。
這可能意味著:
在這三種情況下,每個證明隻需要花費幾十萬天然氣。建築商需要製作其中之一每個 L2 上 對於該 L2 中的用戶;因此,爲了使其有用,該方案作爲一個整體需要有足夠的用途,以至於衕一塊中經常至少有一些交易在多個主要 L2 上。
如果使用 ZK-SNARK,主要的邊際成本隻是在合約之間傳遞數字的“業務邏輯”,因此每個用戶可能需要幾千個 L2 Gas。如果使用 KZG 多重證明,證明者將需要爲該塊內使用的每個持有密鑰庫的 L2 添加 48 個 Gas,因此每個用戶的方案的邊際成本將爲每個 L2 添加約 800 個 L1 Gas(不是每個 L2)。用戶)在頂部。但這些成本遠低於不聚合的成本,後者不可避免地涉及超過 10,000 個 L1 Gas 和數十萬個 L2 Gas每個用戶。對於 Verkle 樹,您可以直接使用 Verkle 多重證明,爲每個用戶添加大約 100-200 字節,或者您可以製作 Verkle 多重證明的 ZK-SNARK,其成本與 Merkle 分支的 ZK-SNARK 類似,但證明起來要便宜得多。
從實施的角度來看,最好讓捆綁器通過以下方式聚合跨鏈證明:ERC-4337 帳戶抽象標準。 ERC-4337 已經爲構建者提供了一種以自定義方式聚合 UserOperations 部分的機製。甚至還有一個@voltrevo/BJ0QBy3zi">BLS 簽名聚合的實現,這可以將 L2 的 Gas 成本降低 1.5 倍到 3 倍,具體取決於還包括哪些其他形式的壓縮。
圖錶來自@voltrevo/BJ0QBy3zi">BLS 錢包實施帖子 顯示 ERC-4337 早期版本中 BLS 聚合簽名的工作流程。聚合跨鏈證明的工作流程可能看起來非常相似。
最後一種可能性,僅適用於 L2 讀取 L1(而不是 L1 讀取 L2),是修改 L2,讓它們直接對 L1 上的合約進行靜態調用。
這可以通過操作碼或預編譯來完成,它允許調用 L1,您可以在其中提供目標地址、gas 和 calldata,併且它返回輸出,但因爲這些調用是靜態調用,所以它們實際上不能改變 任何 L1 狀態。 L2 必鬚了解 L1 才能處理存款,因此沒有什麽根本性的因素可以阻止此類事情的實施;這主要是技術實施方麵的挑戰(參見:Optimism 的此 RFP 支持靜態呼叫 L1)。
請註意,如果密鑰庫位於 L1,和 L2 集成了 L1 靜態調用功能,因此根本不需要任何證明!然而,如果 L2 不集成 L1 靜態調用,或者密鑰庫位於 L2 上(一旦 L1 變得太昂貴而用戶無法使用,哪怕是一點點,它最終可能必鬚如此),那麽將需要證明。
上述所有方案都要求 L2 訪問最近的 L1 狀態根或整個最近的 L1 狀態。幸運的是,所有 L2 都已經具有一些訪問最近的 L1 狀態的功能。這是因爲他們需要這樣的功能來處理從 L1 到 L2 的消息,尤其是存款。
事實上,如果 L2 具有存款功能,那麽您可以按原樣使用該 L2 將 L1 狀態根移動到 L2 上的合約中:隻需在 L1 上有一個合約,調用區塊哈希 操作碼,併將其作爲存款消息傳遞給 L2。可以在 L2 側接收完整的塊頭,併提取其狀態根。然而,如果每個 L2 都有一種明確的方式來直接訪問完整的最近 L1 狀態或最近的 L1 狀態根,那就更好了。
優化 L2 如何接收最近的 L1 狀態根的主要挑戰是衕時實現安全性和低延遲:
此外,在相反方曏(L1s 讀取 L2):
對於許多 defi 用例來説,去信任的跨鏈操作的某些速度慢得令人無法接受;對於這些情況,您確實需要更快的網橋和更不完善的安全模型。然而,對於更新錢包密鑰的用例,較長的延遲是更可以接受的:你不是延遲交易 幾個小時,你就耽誤了關鍵變化。您隻需將舊鑰匙保留更長時間即可。如果您因爲密鑰被盜而更改密鑰,那麽您確實會在很長一段時間內容易受到攻擊,但這可以減輕,例如。通過錢包有凍結 功能。
最終,最好的延遲最小化解決方案是 L2 以最佳方式實現直接讀取 L1 狀態根,其中每個 L2 塊(或狀態根計算日誌)包含一個指曏最近的 L1 塊的指針,因此如果 L1 恢覆,L2也可以恢覆。密鑰庫合約應該放置在主網上,或者放置在 ZK-rollups 的 L2 上,這樣可以快速提交到 L1。
L2 鏈的區塊不僅可以依賴於之前的 L2 區塊,還可以依賴於 L1 區塊。如果 L1 恢覆經過這樣的鏈接,L2 也會恢覆。值得註意的是,這也是早期(Dank 之前)版本分片的設想工作方式;看這裡 對於代碼。
令人驚訝的是,沒有那麽多。它實際上甚至不需要是 Rollup:如果它是 L3 或 validium,那麽隻要您在 L1 或 ZK Rollup 上保存密鑰庫,就可以在那裡保存錢包。你那件事做 鏈需要直接訪問以太坊狀態根,併且如果以太坊重組願意重組,如果以太坊硬分叉則願意硬分叉的技術和社會承諾。
一個有趣的研究問題是確定一條鏈在多大程度上可以與多種的 其他鏈(例如以太坊和 Zcash)。天真地這樣做是可能的:如果以太坊,你的鏈可能會衕意重組或者 Zcash 重組(如果以太坊則硬分叉或者 Zcash 硬分叉),但是您的節點運營商和您的社區通常具有雙倍的技術和政治依賴性。因此,這種技術可用於連接到其他一些鏈,但成本會增加。方案基於ZK橋 具有有吸引力的技術特性,但它們有一個關鍵弱點,即對 51% 攻擊或硬分叉的魯棒性不強。或許還有更巧妙的解決方案。
理想情況下,我們還希望保護隱私。如果您有多個由衕一密鑰庫管理的錢包,那麽我們要確保:
這會産生一些問題:
使用 SNARK,解決方案在概念上很簡單:默認情況下,證明是信息隱藏的,併且聚合器需要生成遞歸 SNARK 來證明 SNARK。
如今這種方法的主要挑戰是聚合需要聚合器創建遞歸 SNARK,目前速度相當慢。
有了KZG,我們可以使用@vbuterin/non_index_revealing_proof">這項工作涉及非索引揭示 KZG 證明 (另請參閲:該工作的更正式版本填縫紙)作爲起點。然而,盲證明的聚合是一個需要更多關註的開放問題。
不幸的是,從 L2 內部直接讀取 L1 併不能保護隱私,盡管實現直讀功能仍然非常有用,既可以最大限度地減少延遲,也可以用於其他應用程序。
特別感謝 Yoav Weiss、Dan Finlay、Martin Koppelmann 以及 Arbitrum、Optimism、Polygon、Scroll 和 SoulWallet 團隊的反饋和審查。
在這篇關於三個轉變的文章,我概述了一些關鍵原因,爲什麽開始明確考慮 L1 + 跨 L2 支持、錢包安全和隱私作爲生態繫統堆棧的必要基本特徵,而不是將這些東西構建爲可以單獨設計的插件個人錢包。
這篇文章將更直接地關註一個特定子問題的技術方麵:如何更容易地從 L2 讀取 L1、從 L1 讀取 L2 或從另一個 L2 讀取一個 L2。解決這個問題對於實現資産/密鑰庫分離架構至關重要,但它在其他領域也有有價值的用例,最顯著的是優化可靠的跨 L2 調用,包括在 L1 和 L2 之間移動資産等用例。
一旦 L2 變得更加主流,用戶將擁有跨多個 L2 的資産,也可能擁有跨 L1 的資産。一旦智能合約錢包(多重簽名、社交恢覆或其他)成爲主流,訪問某些帳戶所需的密鑰會隨著時間的推移而改變,舊的密鑰將不再有效。一次兩個都 當髮生這些事情時,用戶將需要有一種方法來更改有權訪問位於許多不衕地方的許多帳戶的密鑰,而無需進行大量交易。
特別是,我們需要一種方法來處理反事實地址:尚未以任何方式在鏈上“註冊”的地址,但仍然需要接收和安全持有資金。我們都依賴於反事實地址:當你第一次使用以太坊時,你能夠生成一個 ETH 地址,有人可以用它來曏你付款,而無需在鏈上“註冊”該地址(這需要支付交易費用,因此已經持有一些 ETH)。
和環氧乙烷,所有地址都以反事實地址開始。使用智能合約錢包,反事實地址仍然是可能的,這很大程度上要歸功於創建2,它允許您擁有一個 ETH 地址,該地址隻能由具有與特定哈希匹配的代碼的智能合約填充。
EIP-1014(創建2) 地址計算算法。
然而,智能合約錢包帶來了一個新的挑戰:訪問密鑰的可能性改變。地址,它是哈希值初始化代碼,隻能包含錢包的最初的 驗證密鑰。這當前的 驗證密鑰將存儲在錢包的存儲中,但該存儲記録不會神奇地傳播到其他 L2。
如果用戶在許多 L2 上擁有許多地址,包括他們所在的 L2 不知道的地址(因爲它們是反事實的),那麽似乎隻有一種方法允許用戶更改其密鑰:資産/密鑰庫分離架構。每個用戶都有(i) “密鑰庫合衕” (在 L1 或一個特定的 L2 上),它存儲驗證密鑰全部 錢包以及更改密鑰的規則,以及(二) “錢包合約” 在 L1 和許多 L2 上,讀取跨鏈以穫取驗證密鑰。
有兩種方法可以實現此目的:
爲了展示完整的覆雜性,我們將探討最睏難的情況:密鑰庫位於一個 L2 上,而錢包位於另一個 L2 上。如果密鑰庫或錢包位於 L1,則隻需要此設計的一半。
假設密鑰庫已打開線,併且錢包已打開畫傷的。錢包密鑰的完整證明包括:
這裡有兩個主要棘手的實施問題:
主要有五個選項:
就所需的基礎設施工作和用戶成本而言,我大緻排名如下:
”聚合“是指將每個區塊中用戶提供的所有證明聚合成一個將所有這些證明組合在一起的大元證明的想法。這對於 SNARK 和 KZG 是可能的,但對於 Merkle 分支則不行(你能 稍微合併 Merkle 分支,但它隻會拯救你log(每個塊的交易數)/ log(密鑰庫總數),實際上可能是 15-30%,所以可能不值得這個成本)。
隻有當該方案擁有大量用戶時,聚合才變得值得,因此實際上,版本 1 實現可以忽略聚合,併在版本 2 中實現聚合。
這個很簡單:遵循上一節中的圖錶 直接地。更準確地説,每個“證明”(假設將一個 L2 證明爲另一個 L2 的最大難度情況)將包含:
不幸的是,以太坊狀態證明很覆雜,但存在用於驗證它們的庫,併且如果你使用這些庫,這個機製實現起來併不太覆雜。
更大的問題是成本。 Merkle 證明很長,不幸的是,Patricia 樹比所需的長度長約 3.9 倍(準確地説:理想的 Merkle 證明包含在樹中)氮 對象是32 log2(N) 字節長,併且因爲以太坊的 Patricia 樹每個子節點有 16 個葉子,所以這些樹的證明是32 15 log16(N) ~= 125 log2(N) 字節長)。大緻處於一個狀態2.5 億 (~2²⁸) 個賬戶,這使得每個證明125 * 28 = 3500 字節,或大約 56,000 個 Gas,加上解碼和驗證哈希值的額外成本。
兩個證明加在一起最終將花費大約 100,000 到 150,000 Gas(如果每筆交易使用簽名驗證,則不包括簽名驗證)——明顯高於當前每筆交易 21,000 Gas 的基礎。但如果在 L2 上驗證證明,差距會變得更糟。 L2 內部的計算成本低廉,因爲計算是在鏈下完成的,併且是在節點數比 L1 少得多的生態繫統中完成的。另一方麵,數據必鬚髮布到 L1。因此,比較不是 21000 Gas 與 150,000 Gas;而是 21000 Gas 與 150,000 Gas 的比較。這是 21,000 L2 氣體 vs 100,000 L1 氣體。
我們可以通過比較 L1 Gas 成本和 L2 Gas 成本來計算這意味著什麽:
目前,對於簡單髮送,L1 比 L2 貴約 15-25 倍,對於代幣交換,L1 比 L2 貴 20-50 倍。簡單髮送的數據量相對較大,但交換的計算量要大得多。因此,交換是近似 L1 計算與 L2 計算成本的更好基準。考慮到所有這些,如果我們假設 L1 計算成本和 L2 計算成本之間的成本比爲 30 倍,這似乎意味著在 L2 上放置 Merkle 證明的成本可能相當於 50 個常規交易。
當然,使用二叉 Merkle 樹可以將成本降低約 4 倍,但即便如此,在大多數情況下成本還是太高了——如果我們願意做出犧牲,不再與以太坊當前的十六進製兼容狀態樹,我們不妨尋求更好的選擇。
從概念上講,ZK-SNARK 的使用也很容易理解:您隻需將 Merkle 證明替換爲上圖 用 ZK-SNARK 證明這些 Merkle 證明存在。一個 ZK-SNARK 的計算成本約爲 400,000 Gas,大約 400 字節(比較:未來一筆基本交易需要 21,000 Gas 和 100 字節)通過壓縮可減少至約 25 字節)。因此,從一個計算性的 從角度來看,ZK-SNARK 的成本是當今基本交易成本的 19 倍,併且從數據 從角度來看,ZK-SNARK 的成本是目前基本交易的 4 倍,未來可能是基本交易的 16 倍。
這些數字比 Merkle 證明有了巨大的進步,但它們仍然相當昂貴。有兩種方法可以對此進行改進:(i)特殊用途的 KZG 證明,或(ii)聚合,類似於ERC-4337聚合 但使用更奇特的數學。我們可以對兩者進行研究。
警告,這一部分比其他部分更加數學化。這是因爲我們超越了通用工具,併構建了一些更便宜的專用工具,因此我們必鬚更多地深入“幕後”。如果您不喜歡深入的數學,請直接跳至下一節。
首先,回顧一下 KZG 承諾的運作方式:
需要理解的一些重要屬性是:
因此,我們有一個結構,我們可以不斷地將值添加到不斷增長的列錶的末尾,盡管有一定的大小限製(實際上,數億個值是可行的)。然後我們使用那 作爲我們的數據結構,用於管理(i)對每個 L2 上的密鑰列錶的承諾,存儲在該 L2 上併鏡像到 L1,以及(ii)對 L2 密鑰承諾列錶的承諾,存儲在以太坊 L1 上,鏡像到每個 L2。
保持承諾更新可以成爲核心 L2 邏輯的一部分,也可以通過存款和取款橋在不更改 L2 核心協議的情況下實現。
因此,完整的證明需要:
實際上可以將兩個 KZG 證明合併爲一個,因此我們得到的總大小隻有 100 字節。
請註意一個微妙之處:因爲鍵列錶是一個列錶,而不是像狀態那樣的鍵/值映射,所以鍵列錶必鬚按順序分配位置。密鑰承諾合約將包含其自己的內部註冊錶,將每個密鑰庫映射到一個 ID,併且對於它將存儲的每個密鑰hash(密鑰,密鑰庫的地址) 而不是僅僅鑰匙,明確地與其他 L2 進行通信哪個 特定條目正在談論的密鑰庫。
該技術的優點是它執行L2 非常好。數據爲 100 字節,比 ZK-SNARK 短約 4 倍,比 Merkle 證明短得多。計算成本主要是一次 size-2 配對檢查,或者約 119,000 天然氣。在 L1 上,數據不如計算重要,因此不幸的是 KZG 比 Merkle 證明更昂貴。
Verkle 樹本質上涉及堆疊 KZG 承諾(或《近期行動計畫》承諾,這可以更有效併使用更簡單的加密技術)相互疊加:要存儲 2⁴⁸ 值,您可以對 2²⁴ 值列錶做出 KZG 承諾,其中每個值本身都是對 2²⁴ 值的 KZG 承諾。 Verkle 樹正在@vbuterin/verkle_tree_eip">強烈考慮以太坊狀態樹,因爲 Verkle 樹可用於保存鍵值映射,而不僅僅是列錶(基本上,您可以創建一個大小爲 2²⁵⁶ 的樹,但一開始它是空的,隻有在實際需要填充時才填充樹的特定部分)。
Verkle 樹是什麽樣子的?實際上,您可以爲基於 IPA 的樹指定每個節點的寬度 256 == 2⁸,或者爲基於 KZG 的樹指定 2²⁴。
Verkle 樹中的證明比 KZG 稍長;它們可能有幾百字節長。它們也很難驗證,尤其是當您嘗試將許多證據聚合爲一個時。
實際上,Verkle 樹應該被認爲與 Merkle 樹類似,但在沒有 SNARKing 的情況下更可行(因爲數據成本更低),併且在使用 SNARKing 的情況下更便宜(因爲證明者成本更低)。
Verkle 樹的最大優點是協調數據結構的可能性:Verkle 證明可以直接在 L1 或 L2 狀態上使用,無需覆蓋結構,併且對 L1 和 L2 使用完全相衕的機製。一旦量子計算機成爲一個問題,或者一旦證明 Merkle 分支變得足夠高效,Verkle 樹就可以替換爲具有合適的 SNARK 友好哈希函數的二叉哈希樹。
如果 N 個用戶進行 N 筆交易(或者更實際地説,NERC-4337 UserOperations)需要證明N個跨鏈聲明,我們可以通過以下方式節省大量gas聚合 這些證明:將這些交易組合成一個塊或進入一個塊的捆綁包的構建器可以創建一個單身的 衕時證明所有這些主張的證據。
這可能意味著:
在這三種情況下,每個證明隻需要花費幾十萬天然氣。建築商需要製作其中之一每個 L2 上 對於該 L2 中的用戶;因此,爲了使其有用,該方案作爲一個整體需要有足夠的用途,以至於衕一塊中經常至少有一些交易在多個主要 L2 上。
如果使用 ZK-SNARK,主要的邊際成本隻是在合約之間傳遞數字的“業務邏輯”,因此每個用戶可能需要幾千個 L2 Gas。如果使用 KZG 多重證明,證明者將需要爲該塊內使用的每個持有密鑰庫的 L2 添加 48 個 Gas,因此每個用戶的方案的邊際成本將爲每個 L2 添加約 800 個 L1 Gas(不是每個 L2)。用戶)在頂部。但這些成本遠低於不聚合的成本,後者不可避免地涉及超過 10,000 個 L1 Gas 和數十萬個 L2 Gas每個用戶。對於 Verkle 樹,您可以直接使用 Verkle 多重證明,爲每個用戶添加大約 100-200 字節,或者您可以製作 Verkle 多重證明的 ZK-SNARK,其成本與 Merkle 分支的 ZK-SNARK 類似,但證明起來要便宜得多。
從實施的角度來看,最好讓捆綁器通過以下方式聚合跨鏈證明:ERC-4337 帳戶抽象標準。 ERC-4337 已經爲構建者提供了一種以自定義方式聚合 UserOperations 部分的機製。甚至還有一個@voltrevo/BJ0QBy3zi">BLS 簽名聚合的實現,這可以將 L2 的 Gas 成本降低 1.5 倍到 3 倍,具體取決於還包括哪些其他形式的壓縮。
圖錶來自@voltrevo/BJ0QBy3zi">BLS 錢包實施帖子 顯示 ERC-4337 早期版本中 BLS 聚合簽名的工作流程。聚合跨鏈證明的工作流程可能看起來非常相似。
最後一種可能性,僅適用於 L2 讀取 L1(而不是 L1 讀取 L2),是修改 L2,讓它們直接對 L1 上的合約進行靜態調用。
這可以通過操作碼或預編譯來完成,它允許調用 L1,您可以在其中提供目標地址、gas 和 calldata,併且它返回輸出,但因爲這些調用是靜態調用,所以它們實際上不能改變 任何 L1 狀態。 L2 必鬚了解 L1 才能處理存款,因此沒有什麽根本性的因素可以阻止此類事情的實施;這主要是技術實施方麵的挑戰(參見:Optimism 的此 RFP 支持靜態呼叫 L1)。
請註意,如果密鑰庫位於 L1,和 L2 集成了 L1 靜態調用功能,因此根本不需要任何證明!然而,如果 L2 不集成 L1 靜態調用,或者密鑰庫位於 L2 上(一旦 L1 變得太昂貴而用戶無法使用,哪怕是一點點,它最終可能必鬚如此),那麽將需要證明。
上述所有方案都要求 L2 訪問最近的 L1 狀態根或整個最近的 L1 狀態。幸運的是,所有 L2 都已經具有一些訪問最近的 L1 狀態的功能。這是因爲他們需要這樣的功能來處理從 L1 到 L2 的消息,尤其是存款。
事實上,如果 L2 具有存款功能,那麽您可以按原樣使用該 L2 將 L1 狀態根移動到 L2 上的合約中:隻需在 L1 上有一個合約,調用區塊哈希 操作碼,併將其作爲存款消息傳遞給 L2。可以在 L2 側接收完整的塊頭,併提取其狀態根。然而,如果每個 L2 都有一種明確的方式來直接訪問完整的最近 L1 狀態或最近的 L1 狀態根,那就更好了。
優化 L2 如何接收最近的 L1 狀態根的主要挑戰是衕時實現安全性和低延遲:
此外,在相反方曏(L1s 讀取 L2):
對於許多 defi 用例來説,去信任的跨鏈操作的某些速度慢得令人無法接受;對於這些情況,您確實需要更快的網橋和更不完善的安全模型。然而,對於更新錢包密鑰的用例,較長的延遲是更可以接受的:你不是延遲交易 幾個小時,你就耽誤了關鍵變化。您隻需將舊鑰匙保留更長時間即可。如果您因爲密鑰被盜而更改密鑰,那麽您確實會在很長一段時間內容易受到攻擊,但這可以減輕,例如。通過錢包有凍結 功能。
最終,最好的延遲最小化解決方案是 L2 以最佳方式實現直接讀取 L1 狀態根,其中每個 L2 塊(或狀態根計算日誌)包含一個指曏最近的 L1 塊的指針,因此如果 L1 恢覆,L2也可以恢覆。密鑰庫合約應該放置在主網上,或者放置在 ZK-rollups 的 L2 上,這樣可以快速提交到 L1。
L2 鏈的區塊不僅可以依賴於之前的 L2 區塊,還可以依賴於 L1 區塊。如果 L1 恢覆經過這樣的鏈接,L2 也會恢覆。值得註意的是,這也是早期(Dank 之前)版本分片的設想工作方式;看這裡 對於代碼。
令人驚訝的是,沒有那麽多。它實際上甚至不需要是 Rollup:如果它是 L3 或 validium,那麽隻要您在 L1 或 ZK Rollup 上保存密鑰庫,就可以在那裡保存錢包。你那件事做 鏈需要直接訪問以太坊狀態根,併且如果以太坊重組願意重組,如果以太坊硬分叉則願意硬分叉的技術和社會承諾。
一個有趣的研究問題是確定一條鏈在多大程度上可以與多種的 其他鏈(例如以太坊和 Zcash)。天真地這樣做是可能的:如果以太坊,你的鏈可能會衕意重組或者 Zcash 重組(如果以太坊則硬分叉或者 Zcash 硬分叉),但是您的節點運營商和您的社區通常具有雙倍的技術和政治依賴性。因此,這種技術可用於連接到其他一些鏈,但成本會增加。方案基於ZK橋 具有有吸引力的技術特性,但它們有一個關鍵弱點,即對 51% 攻擊或硬分叉的魯棒性不強。或許還有更巧妙的解決方案。
理想情況下,我們還希望保護隱私。如果您有多個由衕一密鑰庫管理的錢包,那麽我們要確保:
這會産生一些問題:
使用 SNARK,解決方案在概念上很簡單:默認情況下,證明是信息隱藏的,併且聚合器需要生成遞歸 SNARK 來證明 SNARK。
如今這種方法的主要挑戰是聚合需要聚合器創建遞歸 SNARK,目前速度相當慢。
有了KZG,我們可以使用@vbuterin/non_index_revealing_proof">這項工作涉及非索引揭示 KZG 證明 (另請參閲:該工作的更正式版本填縫紙)作爲起點。然而,盲證明的聚合是一個需要更多關註的開放問題。
不幸的是,從 L2 內部直接讀取 L1 併不能保護隱私,盡管實現直讀功能仍然非常有用,既可以最大限度地減少延遲,也可以用於其他應用程序。