Vitalik最新博文:多維Gas定價探討

作者:Vitalik,以太坊創辦人;翻譯:0xjs@金色財經

在以太坊中,直到最近,資源都是有限的,並使用一種稱為「Gas」的單一資源定價。 Gas是處理給定交易或區塊所需的「計算量」的量度。 Gas 將多種類型的「努力」融合在一起,最值得注意的是:

  • 原始計算(例如ADD, MULTIPLY)

  • 讀取和寫入以太坊儲存(例如SSTORE,SLOADETH 轉帳)

  • 數據頻寬

  • 產生區塊的ZK-SNARK 證明的成本

例如,我寄來的這筆交易(https://etherscan.io/tx/0xc5195b64cc333b8098d71fbd0f032e05d4545917e3b0be8d123ab06e1ad7998e)總共花了47,085 Gas。這分為(i) 21000 Gas 的“基本成本”,(ii) 作、包含部分交易的調用資料位元組的1556 Gas,(iii) 用於讀取和寫入儲存的16500 Gas,(iv) 用於生成日誌的2149 Gas,其餘用於EVM 執行。用戶必須支付的交易費用與交易消耗的gas成正比。一個區塊最多可包含3000萬Gas,並且Gas 價格透過EIP-1559 目標機制不斷調整,確保區塊平均包含1500萬Gas。

這種方法有一個主要效率:因為所有東西都合併到一個虛擬資源中,所以它導致了非常簡單的市場設計。優化交易以最小化成本很容易,優化區塊以收取盡可能高的費用相對容易(不包括MEV),並且沒有奇怪的激勵措施鼓勵某些交易與其他交易捆綁在一起以節省費用。

但這種方法也有一個主要的低效率問題:它將不同的資源視為可以相互轉換,而網路可以處理的實際潛在限制卻並非如此。理解這個問題的一種方法是看這張圖:

Gas 限制強制執行以下約束:x1*data+x2*computation

如果有?個資源具有不同安全限制,那麼一維gas可能會降低吞吐量高達一個因子?。因此,長期以來人們對多維Gas的概念很感興趣,透過EIP-4844,我們今天實際上在以太坊上運行了多維Gas。這篇文章探討了這種方法的好處以及進一步增強這種方法的前景。

Blobs:Dencun中的多維Gas

今年年初,以太坊平均區塊大小為150 kB。該大小的很大一部分是Rollup資料:為了安全起見,2 層協定將資料儲存在鏈上。這些數據非常昂貴:儘管Rollup交易的成本比以太坊L1 上的相應交易低約5-10 倍,但對於許多用例來說,這個成本仍然太高。

為什麼不降低calldata 的Gas 成本(目前每個非零位元組16 Gas,每個零位元組4 Gas),以使Rollup更便宜?我們以前這樣做過,我們可以再做一次。這裡的答案是:最壞情況下的區塊大小是30000000/16=1875000非零字節,而且網路已經幾乎無法處理該大小的區塊。如果成本再降低4 倍,則最大容量將增加到7.5 MB,這將帶來巨大的安全風險。

這個問題最終透過在每個區塊中引入一個單獨的易於Rollup的資料空間(稱為「blob」)來解決。這兩種資源有不同的價格和不同的限制:在Dencun 硬分叉之後,一個以太坊區塊最多可以包含(i) 3000 萬Gas,以及(ii) 6 個blob,每個blob 可以包含約125 kB 的調用資料。這兩種資源都有單獨的價格,透過單獨的類似EIP-1559 的定價機制進行調整,目標是每個區塊平均使用1500 萬Gas 和3 個blob。

結果,rollups 的成本降低了100 倍,rollups 上的交易量增加了3 倍以上,而理論上的最大區塊大小僅略有增加:從約1.9 MB 增加到約2.6 MB。

hDPkkS6r6z3Z4Zc1EIqeuRpQxcgE8mMyQgudaxuo.pngRollup交易費用,由Growthepie.xyz提供。 Dencun 分叉發生於2024 年3 月13 日,引入了多維定價的blob。

多維gas和無狀態客戶端

在不久的將來,無狀態客戶端的儲存證明也會出現類似的問題。無狀態客戶端是一種新型客戶端,它將能夠驗證區塊鏈而無需在本地儲存大量或任何資料。無狀態客戶端透過接受該區塊中的交易需要接觸的以太坊特定部分的證明來實現這一點。

fDkIgLSlTiwsYU6ZE7keURO89844EPvRvkAJVj12.png無狀態客戶端接收一個區塊,以及證明區塊執行涉及的狀態特定部分(例如帳戶餘額、程式碼、儲存)的當前值的證明。這允許節點在沒有任何儲存本身的情況下驗證區塊。

一次儲存讀取需要花費2100-2600 Gas,取決於讀取類型,而儲存寫入成本更高。平均而言,一個區塊會執行大約1000 次儲存讀寫(包括ETH 餘額檢查、SSTORE呼叫SLOAD、合約程式碼讀取等操作)。然而,理論上的最大值是30000000/2100=14285次讀取。無狀態客戶端的頻寬負載與該數字成正比。

今天,該計劃是透過將以太坊的狀態樹設計從Merkle Patricia 樹轉移到Verkle 樹來支援無狀態客戶端。然而,Verkle 樹不具備量子抗性,對於更新的STARK 證明系統來說並不是最佳選擇。因此,許多人有興趣透過二元Merkle 樹和STARK支援無狀態客戶端- 要么完全跳過Verkle,要么在Verkle 過渡幾年後,一旦STARK 變得更加成熟,就進行升級。

二元雜湊樹分支的STARK 證明有很多優點,但它們有一個關鍵弱點,即證明需要很長時間才能產生:雖然Verkle 樹每秒可以證明超過十萬個值,但基於哈希的STARK 通常只能每秒證明幾千個哈希,證明每個值需要一個包含許多哈希值的「分支」。

考慮到今天從超優化的證明系統(例如Binius和Plonky3)以及專門的哈希(例如Vision-Mark-32)預測的數字,我們很可能在一段時間內處於一種可以不到一秒實際證明1,000個值的狀態,但不是14,285 個值。每個區塊平均沒問題,但最壞情況下的區塊(可能由攻擊者發布)會破壞網路。

我們處理這種情況的「預設」方式是重新定價:使儲存讀取更加昂貴,以將每個區塊的最大值減少到更安全的程度。然而,我們已經這樣做過很多次了,如果再這樣做的話,太多的應用程式會變得太昂貴。更好的方法是多維Gas:分別對存儲訪問進行限制和收費,將平均使用量保持在每個區塊1,000 次存儲訪問,但將每個區塊的限制設置為例如2,000次。

更普遍的多維Gas

另一個值得考慮的資源是狀態大小成長:增加以太坊狀態大小的操作,全節點將需要持有完整狀態。狀態規模成長的獨特之處在於,限制狀態成長的理由完全來自長期持續的使用,而不是高峰。因此,為狀態規模增加操作(例如,從零到非零SSTORE、合約創建)添加單獨的Gas 維度可能有價值,但目標不同:我們可以設定浮動價格來針對特定的平均使用量,但根本不設定每個區塊的限制。

這顯示了多維Gas的強大特性之一:它讓我們分別詢問以下問題:(i)每種資源的理想平均使用量是多少,以及(ii)每個區塊的安全最大使用量是多少。我們不是根據每個區塊的最大值來設定Gas 價格,而是平均使用量,其有2?自由度來設定2?參數,並根據對網路安全的情況調整每一項。

更複雜的情況,例如兩個資源具有部分累加的安全考慮,可以透過使操作碼或資源花費一定數量的多種類型的gas來處理(例如,零到非零SSTORE可能花費5000 無狀態客戶端證明的gas和20000儲存膨脹的gas)。

每筆交易取最大值:取得多維Gas的較弱但更簡單的方法

讓x1是資料的Gas 成本,x2是計算的Gas 成本,因此在一維Gas 系統中我們可以寫出一筆交易的Gas 成本gas=x1*data+x2*computation

在新方案中,我們將交易的Gas 成本定義為:gas=max(x1*data,x2*computation)

也就是說,交易不是根據資料加計算來收費,而是根據它消耗的兩種資源中哪一種資源比較來收費。這可以很容易地擴展到覆蓋更多維度(例如max(…,x3*storage_access))。

應該很容易看出這如何在保證安全性的同時提高吞吐量。理論上一個區塊中的最大資料量仍然是GASLIMIT/x1,與一維Gas方案完全相同。同理,理論最大計算量為GASLIMI/x2,再次與一維Gas方案完全相同。然而,任何消耗數據和計算的交易的Gas 成本都會降低。

這大約是提議的EIP-7623中採用的方案,以減少最大區塊大小,同時進一步增加blob 計數。 EIP-7623 中的精確機制稍微複雜一些:它保持目前的calldata 價格為每位元組16 Gas,但增加了每位元組48 Gas 的「底價」;交易支付( 16 * bytes + execution_gas) 和( 48 * bytes) 中較高者。因此,EIP-7623 將區塊中理論最大交易調用資料從約1.9 MB 減少到約0.6 MB,同時保持大多數應用程式的成本不變。這種方法的好處是它與目前的一維gas方案相比變化非常小,因此非常容易實現。

它有兩個缺點:

1.即使區塊中的所有其他交易只使用很少的該資源,但大量佔用一種資源的交易仍然會不必要地收取大量費用。

2、它激勵數據密集型和計算密集型交易合併到一個捆綁包中以節省成本。

我認為,EIP-7623 風格的規則,無論是對於交易調用資料還是其他資源,都可以帶來足夠大的好處,即使存在這些缺點,也是值得的。然而,如果我們願意投入(顯著更高的)開發努力,就有一種更理想的方法。

多維EIP-1559:更困難但理想的策略

讓我們先回顧一下「常規」EIP-1559 的工作原理。我們將重點放在EIP-4844 中針對blob 引入的版本,因為它在數學上更加優雅。

我們追蹤一個參數,excess_blobs。在每個區塊期間,我們設定:

excess_blobs <-- max(excess_blobs + len(block.blobs) - TARGET, 0)

這裡TARGET = 3。也就是說,如果一個區塊的blob 數量多於目標,excess_blobs則增加,如果區塊的blob 數量少於目標,則減少。然後我們設定blob_basefee = exp(excess_blobs / 25.47),其中exp是指數函數的近似值exp(x)。

tHBgkC3iz4o2eXwCcVLTpl85ZmiKRAz3eWbQhsNf.png也就是說,每當excess_blobs增加約25 倍時,blob 基本費用就會增加約2.7 倍。如果blob 變得太貴,平均使用量就會下降,然後excess_blobs開始下降,從而自動再次降低價格。 Blob 的價格不斷調整,以確保平均而言,區塊是半滿的- 也就是說,每個區塊平均包含3 個Blob。

如果使用量出現短期峰值,則會出現限制:每個區塊最多只能包含6 個blob,在這種情況下,交易可以透過提高優先費來相互競爭。然而,在正常情況下,每個blob 只需要支付blob_basefee加一點額外的優先權費用,作為被納入的誘因。

這種Gas 定價在以太坊中已經存在多年:早在2020 年,EIP-1559就引入了非常相似的機制。透過EIP-4844,我們現在有兩個單獨的Gas 和Blob 浮動價格。

d5CLeXftkp28H9Hwu4T6iAdJMr6Jv6oUNhxWUwyh.png

2024 年5 月8 日一小時內的Gas 基本費用,單位為gwei。來源:ultrasonic.money

原則上,我們可以為儲存讀取和其他類型的操作添加更多單獨浮動的費用,但有一個警告,我將在下一節中詳細說明。

對於用戶來說,這種體驗與今天非常相似:你不再支付一筆基本費用,而是支付兩項基本費用,但你的錢包可以將其從你那裡抽象化出來,只向你顯示你可以預期支付的預期費用和最高費用。

對於區塊建構者來說,大多數時候最佳策略與今天相同:包括任何有效的內容。大多數區塊都未滿——無論是gas還是blob。一個具有挑戰性的情況是,當有足夠的gas或足夠的blob超過區塊限制時,建構者需要潛在地解決多維knapsack問題以最大化其利潤。然而,即使存在相當好的近似演算法,在這種情況下,透過制定專有演算法來優化利潤所獲得的收益也比使用MEV 進行相同操作所獲得的收益要小得多。

對於開發者來說,主要挑戰是需要重新設計EVM 及其周邊基礎設施的功能,這些基礎設施目前是圍繞一個價格和一個限制設計的,而設計為適應多個價格和多個限制的設計。應用程式開發人員面臨的一個問題是優化變得稍微困難:在某些情況下,你不能再明確地說A 比B 更有效率,因為如果A 使用更多的calldata 而B 使用更多的執行,那麼當calldata 為便宜,當calldata 昂貴時則較昂貴。然而,開發者仍然能夠透過根據長期歷史平均價格進行最佳化來獲得相當好的結果。

多維定價、EVM 和子呼叫(sub-calls)

有一個問題不會出現在blob 中,也不會出現在EIP-7623 中,甚至不會出現在calldata 的「完整」多維定價實作中,但如果我們嘗試單獨對狀態存取或任何其他資源進行定價,則會出現這個問題:子呼叫中的gas 限制。

EVM 中的Gas 限制存在於兩個地方。首先,每筆交易都會設定一個Gas 限制,限制了該交易中可以使用的Gas 總量。其次,當一個合約呼叫另一個合約時,該呼叫可以設定自己的gas limit。這允許合約調用他們不信任的其他合約,並且仍然保證他們在調用後仍有剩餘的gas來執行其他計算。

PsgS2q0mfzKArApnxgSrlE7SajtgfdBNnbI05o0F.png

帳戶抽象交易的蹤跡,其中一個帳戶呼叫另一個帳戶,並且僅向被呼叫者提供有限數量的gas,以確保即使被呼叫者消耗了分配給它的全部gas,外部呼叫也可以繼續運作。

挑戰在於:在不同類型的執行之間使Gas 成為多維的,似乎需要子呼叫來為每種類型的Gas 提供多個限制,這將需要對EVM 進行真正深入的更改,並且與現有應用程式不相容。

這就是為什麼多維gas提案通常停留在兩個維度的原因之一:資料和執行。資料(無論是交易calldata 還是blob)僅在EVM 外部分配,因此EVM 內部無需更改任何內容即可使calldata 或blob 單獨定價。

我們可以想出一個「EIP-7623式的解」來解決這個問題。這是一個簡單的實作:在執行期間,對儲存作業收取4 倍的費用;為了簡化分析,我們假設每個儲存作業為10000 gas。交易結束,退款min(7500 * storage_operations, execution_gas)。結果是,在扣除退款後,用戶需要支付以下費用:

execution_gas + 10000 * storage_operations – min(7500 * storage_operations, execution_gas)

這等於:

max(execution_gas + 2500 * storage_operations, 10000 * storage_operations)

這反映了EIP-7623 的結構。另一種方法是即時追蹤storage_operations和execution_gas,並根據呼叫操作碼時上漲的金額max(execution_gas + 2500 * storage_operations, 10000 * storage_operations)多少收取2500 或10000 gas。這避免了交易需要過度分配天gas,而這些gas主要透過退款來收回。

我們沒有獲得子呼叫的細粒度許可:子呼叫可能會消耗交易的所有「津貼」以進行廉價的儲存操作。但我們確實得到了足夠好的東西,其中進行子調用的合約可以設置限制,並確保一旦子調用完成執行,主調用仍然有足夠的gas來執行它需要執行的任何後處理。

我能想到的最簡單的「完整的多維定價解決方案」是:我們將子呼叫gas限制視為成比例。也就是說,假設有

?個不同類型的執行,每筆交易設定多維度限制?1…??。假設在目前執行點,剩餘gas

為?1…??。假設CALL呼叫了一個操作碼,帶有子呼叫gas limit S。讓s1=S,進而s2=s1/g1*g2,s3=s1/g1*g3, 等等。

也就是說,我們將第一種類型的gas(實際上是虛擬機執行)視為一種特權“帳戶單位”,然後分配其他類型的gas,以便子呼叫在每種類型建獲得相同百分比的可用gas。這有點難看,但它最大限度地提高了向後相容性。如果我們想讓方案在不同類型的gas之間更加“中立”,以犧牲向後相容性為代價,我們可以簡單地讓子調用gas limit參數代表剩餘gas的一小部分(例如[1…63] / 64)。

然而,無論哪種情況,值得強調的是,一旦開始引入多維執行gas,固有的醜陋程度就會增加,這似乎很難避免。

因此,我們的任務是做出一個複雜的權衡:我們是否接受EVM 級別的一些更醜陋的東西,以便安全地釋放顯著的L1 可擴展性收益,如果是這樣,哪種具體建議最適合協議經濟學和應用程式開發人員?

很可能,它不是我上面提到的任何一個,並且仍然有空間想出更優雅、更好的東西。

特別感謝Ansgar Dietrichs、Barnabe Monoton 和 Davide Crapis的回饋和審查。

Total
0
Shares
Related Posts