Vitalik: 存儲的定價應該獨立于執行嗎?

來源 | ethresear.ch

作者 | Vitalik Buterin

特別感謝 @barnabe 在早些時候提出了類似的想法。

正如我關于資源定價的舊文章里詳細討論的那樣,以太坊的 gas 實際上是為三種不同的資源付費,

  • 帶寬 (事務中必須被下載的數據)
  • 計算 (驗證和執行事務所需時間)
  • 存儲 (歷史記錄,但更重要的是狀態,例如賬戶余額、nonces、合約代碼和合約存儲)

存儲不同于其他兩項開銷。帶寬和計算消耗的都是短暫開銷,它觸碰到短暫存儲界限是這樣的情況:一個節點在一個區塊內能做多少計算或數據下載是有限度的,一旦該區塊被打包了,下載和驗證該區塊的開銷基本上都會消失 (未來只有少數同步節點需要處理它)。另一方面,存儲則是一項永久的開銷。如果一個區塊的狀態大小增加 100 MB,這個區塊在當下被處理沒有問題,但當一系列這樣的區塊持續生成一個月后,整個以太坊會變得不可用。一時嚴重的狀態增長帶來的突發影響是可以忽略不計的,但長期的影響則是最嚴重的,因為每生成一個狀態都永久地增加網路的負荷。

采用了 state expiry 和弱無狀態方案后,長期來說狀態的影響肯定會大大減少:狀態不再永久成為網路的負擔,一個狀態將只會在一年內增加網路負荷,而且即使在那一年里,也只有少數節點需要實際存儲該狀態,但即使如此,這個長期開銷還是會存在的,且仍然需要被定價,

存儲大小的一般情況 vs 最壞情況

無論是在當前的協議 (普遍認為是不可持續的),還是有 state expiry 的改良方案,對狀態建模的一個弱點是狀態膨脹的一般與最壞情況間有巨大差異,想想當前的協議,當前狀態的總容量是大約 5.5 億個對象,或約 32 GB (不包括 trie 的開銷),如果我們把在前一年沒有被觸及的狀態都拿走,狀態總容量很容易下降一半,

那最壞的情況是什么?創建合約代碼按每字節 200 gas 來收費,如果我們把一個區塊分為三個事務,每個事務創建一個合約,我們可以用 “12334800 gas + 3 * 55000 gas” 作為合約創建開銷來創建三個 20558 字節的合約,假設平均出塊時間是 13.1 秒,那么每年會出31556925 / 13.1 = 2408925 個區塊,因此,一年的狀態大小增長是~61800 * 2408925 = 148871600381.67938字節,或大約 138 GB。

這接近 10 倍的差異是非常顯著的!而且 16 GB 特別符合現實消費者的硬件 RAM (如果不行,我們可以修改 gas 價格或狀態失活期使其可行),但 138 GB 是辦不到的,如果我們可以使最壞的情況更接近于一般情況,那就更好了。

基于 EIP 1559 的兩個方案

解決這個問題的一個自然方法是,用 EIP-1559 對短暫和永久開銷定價,但使調整期 (adjustment period) 不一樣。對于短暫的開銷,在單個區塊里會有 10% 的變化幅度。但是對于永久的開銷,我們會讓價格調整得更慢,如果我們以 AMM 開銷曲線機制作為基礎,對于存儲,我們可以考慮有一個條曲線代表每個月的目標比率是 1 GB,開銷增長取決于我們比目標高出多少。例如,每超出目標 1 GB,存儲開銷可能翻倍,在這個參數里,最壞情況區塊的存儲價格可能需要大約 3 天時間才會翻倍。如果存儲增長超過目標 10 GB,存儲開銷會比正常情況下高出 1000 倍,使得進一步填充存儲在經濟上變得不可行。

實現這點有兩個方法:

  • 用 gas 購買存儲。也就是說,用 SSTORE 創建一個新的存儲槽,這會像今天一樣消耗 gas,但消耗 gas 的數量是會變的。這有一個缺點,即保留了時間點的錯誤激勵 (用戶會選擇在周末 gas 價格低的時候增加存儲,盡管這樣對網路并沒有好處)。
  • 用 ETH 購買存儲。事務 (和調用) 會需要提供 gas 以外的另一種資源 (我們會稱之為 mana 😄),這種資源除了用不同的參數,會以與 gas 相似的機制進行收費。這個方法的缺點是它使調用規則變得復雜,且要求新增一個操作碼 CALL,

還有兩個混合選項:

  • 我們可以用 ETH 來定價存儲,但以 gas 來收費。(因此,如果基本費用上漲 2 倍,然后填充一個存儲槽所需的 gas 會自動減半)。我們可以把用來擴大存儲的 ETH 從 EIP-1559 的 gas 價格更新規則、甚至區塊 gas limit 里排除出去,
  • 對 gas 進行更全面的改革,把它拆分為三個概念:gas、執行點、和存儲點。1 gas = 1 wei;一個分配 gas 的事務只意味著它把一些 wei 轉化為一種特殊形式,可用于支付各種資源,在它如何在調用和子調用間的傳遞方式上,這種形式的運作形式與 gas 一樣,但是,現在有兩種開銷是由 AMM 來管理的:執行點的開銷和存儲點的開銷。不同于執行處理一個操作碼現在消耗的是 N gas,它消耗的是 N 執行點,意味著對N * execution_point_costgas 收費。填充一個存儲槽消耗 1 個存儲點,因此storage_point_costgas 會被收費。

還需注意的是,state expiry 的路線圖是包括移除 gas 返還的。這是由于技術原因,存儲槽不能“變空”然后可用于返還;它們只能被設為 0,而 0 的記錄必須保留在狀態里,直到該 epoch 結束且該狀態失活。這大大減少了以前存儲租金方案嘗試的困擾,

原文鏈接:https://ethresear.ch/t/should-storage-be-priced-separately-from-execution/9101

0 条回复 A文章作者 M管理員
    暫無討論,說說你的看法吧