此文謹獻給Alexey Akhunov 和Igor Mandrigin,感謝你們在無狀態性概念上的貢獻。

一. 引言

本文的目的在於向大家介紹一種解決“狀態數據膨脹” 問題的技術路徑—— “無狀態性(statelessness)”。 “狀態數據膨脹” 是所有允許用戶自主寫入狀態數據的公鏈都會面臨的問題,指的是因為用戶及合約的不斷增加,在全節點處保存的狀態數據會越來越多。不斷增加的狀態數據會帶來一系列風險,包括:抬高全節點的運行門檻;使鏈上操作的定價失衡。

在本文中我主要拿以太坊區塊鏈來舉例,這是因為我對以太坊最熟悉,但狀態數據膨脹問題是普遍的,不是以太坊獨有的。我同樣也會舉出我所知的其他項目對這個問題的思考。

為使大家充分理解“無狀態性” 的意義,我少不了要在開篇交代一下問題的背景。然後我會介紹以太坊社區為此提出的幾個概念,以及相關的開放問題/權衡取捨。最後,我會再回到最初的問題,以期通過對問題的多樣描述(以及引出來的解決方案思路),拓寬對該問題的思考。

二. 狀態數據膨脹問題

可以把“區塊鏈協議” 理解為一種讓不定數量的計算機的行為統一步調成一台計算機的協議。那麼,其運行會在參與相關協議的計算機(即“節點”)處產生兩種數據:一種是區塊數據,即我們常說的區塊鏈,這部分數據記錄了這個網絡(這台計算機)在過去發生的所有事情;另一種是狀態數據,即代表當前整個網絡的狀態的數據,對以太坊來說,“狀態” 的內涵包括:哪個賬戶有多少餘額、已經發出過多少筆事務(不包括曾經發出的事務的內容,那是區塊數據);哪個合約的代碼是什麼,其內部的哪個存儲項的值是什麼;還有一些與共識機制運行相關的數據。

狀態數據的特殊性在於:一方面,狀態數據是歷史區塊(所包含的事務)執行之後的結果;另一方面,它又是執行新區塊的前提。因此,在當前的以太坊區塊鏈上,全節點必須保存狀態數據,這樣才能(通過執行區塊來)驗證新收到區塊的合法性。

可以想像,因為用戶和合約的數量會不斷增加,如果不施加一些控制,狀態數據的規模是會不斷增大的。這就是狀態數據膨脹問題。

狀態膨脹問題帶來的影響是確定的:它會讓區塊驗證變得越來越困難。因為同樣是讀取和寫入一個狀態對象,在狀態對像有10 萬個的時候,比之狀態對像只有1000 個的時候,資源開銷是上升的。也正因此,狀態膨脹會使運行全節點的門檻提高(單位時間內,資源的開銷—— 主要是硬盤隨機讀寫—— 不斷上升),還會使EVM 各操作的Gas 開銷比例逐漸失衡,產生對節點的DoS 攻擊向量。 (注:資源開銷的上升幅度與客戶端軟件的實現有關。)

但狀態膨脹問題的原因為何(因此應當如何糾正),則有許多種不同的角度。比如,Vitalik 對該問題的歸因 [1] 是:

“這些操作只需事務的發送者一次性繳交按gas 用量來計量的手續費,但會給整個網絡造成永久的持續性成本”

換言之,問題的根源是支付和成本的不匹配—— 當前的以太坊協議既做不到能夠合理地刪除狀態來給區塊鏈“瘦身” [2],又做不到讓用戶持續為保存自己的狀態付費。假設能做到,這個問題就能得到控制,不會這麼嚴重了。因此,他傾向於“狀態保質期” 方向的改進:用戶創建或更新某個狀態對象之後,只能保證全節點會在一段時間內存儲這個對象;逾期則必須採用額外的手段(因此是額外的支付)來“復活” 這個對象。

對問題的其他歸因和“狀態保質期” 概念,我們後文還會講到。現在我們先轉向“無狀態性(statelessness)”。

注1:Vitalik Buterin,https://ethfans.org/posts/a-theory-of-ethereum-state-size-management

注2:在當前的以太坊協議中,的確有操作(SELFDESTRUCT)可以做到刪除合約的存儲項,也為該操作碼的使用提供了一種粗糙的激勵機制(返還Gas 機制)。但事實證明,返還Gas 機制不僅沒有改善狀態膨脹問題,還促成了Gas Token 的出現,加劇了狀態膨脹問題;而SELFDESTRUCT 則導致了別的一些問題。見《務實地取消SELFDESTRUCT》

三. “無狀態性” 諸概念

(一)無狀態性

“無狀態性” 背後的觀念是:狀態膨脹問題之所以是一個問題,是因為驗證區塊的節點必須先有狀態數據(先得知道某個賬戶有多少錢),然後才能驗證區塊(然後才能知道該賬戶花X 元到底合不合法);但如果我們能做到無需在本地存儲狀態數據就能驗證區塊,那就無需擔心這個問題了。

具體做法是,在廣播區塊時,附帶傳播一份對該區塊內所有事務所訪問狀態的證據,一個完全不保存任何狀態的節點,也可以憑藉這些證據恢復出恰好足以驗證該區塊內所有事務的狀態樹,並且驗證之後可以把這些狀態數據都丟棄。這裡的“所訪問狀態的證據”,通常稱為“見證數據(witness)”。

無狀態性代表著對狀態膨脹問題的釜底抽薪式解決方案,徹底免去區塊驗證對狀態數據的需要,自然就不需要擔心狀態膨脹的問題了。另一方面,各節點還可以自行選擇存儲哪些狀態,允許開發者為自己的使用場景定制所需的客戶端。

但是,從節點的角度看,這意味著一種交換:以增大帶寬開銷為代價,來節約硬盤的讀寫和存儲開銷(儘管讀寫開銷確實是當前全節點的成本中最大的一部分)。那麼見證數據到底有多大?

如果不對以太坊協議作任何改變,見證數據的大小會在MB 級別 [3])。相比之下,當前(區塊Gas 上限為1250 萬)的以太坊區塊數據量約為45 KB [4]。由此看來,見證數據的帶寬開銷是非常大的。過去兩年中,無狀態以太坊研究的主要方向,就是思考如何才能降低見證數據的大小,方向有:(1)代碼默克爾化,減少需要包含在見證數據中的合約代碼數據[5] ;(2)改變以太坊狀態樹的格式,比如將十六進制樹改為二進制樹[6],或者將默克爾樹改為KZG 承諾樹(也就是所謂的Verkle Tree [7]); (3)以區塊為單位提供見證數據,而非以事務為單位,這樣可以免去一些重複的證據。改為二進制樹可以節約一半的帶寬開銷甚至更多;而Verkle Tree 可以產生固定大小的見證數據。

除了帶寬開銷增大以外,無狀態性還帶來了一種革命性的變化:網絡中可能大部分節點都不會保存狀態數據,至少不會保存全量的狀態數據。那麼以往我們習以為常的屬性,在無狀態客戶端為主的網路中就不一定能實現了。這些問題都要重新思考:

當前條件下,用戶無需擔心誰能為自己提供錢包服務;因為自己賬戶的狀態在全網所有全節點處都有備份;但是“無狀態性” 實現後,誰來為用戶提供見證數據呢?用戶如何知道哪裡的節點存儲了自己的狀態?一種樂觀的假設是:出塊者處一定存儲了全部的狀態,否則就會影響其出塊;因此至少出塊者一定能提供這樣的服務。但這會影響錢包服務的可得性嗎? (實際上,在撰文的此刻,我已經不再擔心這個問題了。假設無狀態性的帶寬開銷能降低,全狀態節點的門檻也會降低,定制化狀態節點的門檻也會降低,所以錢包服務的提供門檻實際上是降低了的。可以認為無狀態性確實改變了錢包服務提供的假設,但不應該認為使之惡化了)如果一個節點是無狀態的,僅保存了區塊數據,雖然它能參與歷史區塊廣播和歷史事務廣播,但它沒辦法參與新事務的廣播。準確點來說,TA 是沒法驗證新收到的事務的有效性的。那麼這樣的節點要如何在P2P 網絡中存在(其他對等節點會把它當成一個無用的節點而中斷鍊接)?事務要如何在網絡中傳播?這是否意味著我們不論如何都需要某種以事務為單位提供見證數據的機制?還是說無狀態節點只能在一個專門的次級網絡中生存? (基於後者的解決思路是形成一個可以按需請求狀態數據的次級網絡[8],就像我們常用的BitTorrent 種子下載網絡一樣;當然,為廣播中的事務增加見證數據也是一個辦法)如何為見證數據指定Gas 開銷?又或者說,如何限制見證數據的大小?

上面這個清單僅僅是當前的研究成果,它仍有可能變得更長。這些運行假設的變化,極有可能比它的帶寬開銷上的影響更為重要;如果不分析清楚這些假設,就沒有辦法判斷無狀態性是否真的值得實現,或者何種實現方式更好。

當前,有一種對無狀態性的分類是:

弱無狀態性:以區塊為單位提供見證數據;出塊者仍需保存全部狀態數據強無狀態性:以事務為單位提供見證數據,理論上不需要保持全部狀態數據也可以出塊

在我看來,兩種方向存在短長,但不應認為網絡的最終形態可以被規劃出來。從節約帶寬的角度,弱無狀態性是更優選擇;但相應地也要面對上文所述新事務傳播問題。後文我們還會回到這個分類。

下面我們進入第二個概念:“準-無狀態性”。

注3:Alexey Akhunov,https://ethfans.org/posts/data-from-the-ethereum-stateless-prototype,本篇為理解“無狀態性” 最佳的入門讀物。在Alexey 所測試的主要時間段裡,區塊的平均大小約為20 KB(800 萬Gas),而測算出來的見證數據平均大小在1MB 左右。這意味著,在當前的區塊大小下,必須預期見證數據有更大的大小。

注4:https://etherscan.io/chart/blocksize

注5:Sina Mahmoodi,https://ethfans.org/posts/evm-bytecode-merklization

注6:Igor Mandrigin,https://ethfans.org/posts/stateless-ethereum-binary-tries-experiment

注7:Dankrad Feist,https://notes.ethereum.org/_N1mutVERDKtqGIEYc-Flw

注8:Piper Merriam,https://ethfans.org/posts/state-availability-getnodedata-dht-approach-dev-update

(二)準-無狀態性

準-無狀態性的概念來自這篇文章 [9]。其背後的直覺是:無狀態性對見證數據的要求是能幫助完全無狀態的節點從0 開始建構出能驗證相應區塊的狀態樹,但這很有可能浪費了帶寬資源;因為一旦收到了見證數據之後,節點就已經有一棵稀疏的狀態樹了,這棵樹是可以重用的,犯不著把它全刪了,收到一個新區塊又從0 開始建構。

因此,假定節點在收到一個區塊前,其狀態數據的存量情況是可知的,我們就可以藉助見證數據為之提供一個狀態增量,這個增量加上其初始存量,恰好足以建構出能驗證新區塊的狀態樹。如此一來,我們就既能獲得無狀態性的大部分好處(通過附帶見證數據,讓區塊驗證的硬盤讀寫開銷最小化),又不需要像無狀態性那樣,付出那麼高的帶寬開銷。

而且,準-無狀態性還有一個額外的好處:當狀態數據變得越來越多,狀態樹變得越來越深越來越密,無狀態下的見證數據理論上來說也會不斷增大,即帶寬開銷趨於上升;但準-無狀態性的見證數據僅提供增量數據,所以其見證數據也是最小化的。

麻煩在於,這個“節點的狀態數據存量” 如何可知?理論上來說,除非我們從某個一致的存量開始實行準-無狀態性,否則是無法對這個存量達成同步的。但只需“一致”,這個數目具體是多少,無關緊要。由此我們發現了準-無狀態性的另一個優點:假使狀態數據已經變得過於龐大,我們可以將它們“清零”,從無狀態重新開始,啟動一次新的、由富狀態節點(比如出塊節點)向驗證節點傳送見證數據(和狀態)的進程。

這就是ReGenesis,定期重啟以太坊這台計算機。

注9:Igor Mandrigin,https://ethfans.org/posts/semi-stateless-initial-sync-experiment

(三)Regenesis

ReGenesis 的構想最早由Alexey 提出 [10],更細緻的解讀可見此文 [11]。大意是:定期(比如每100 萬個區塊)將協議設定為空狀態,開始實施準-無狀態的流程—— 每一個區塊在傳播時,都必須附帶一些見證數據,使得一個從上一次regenesis 事件開始清零了狀態數據、並獲得了自那以來所有區塊附帶見證數據的節點,都能驗證該區塊。

也就是說,每次觸發regenesis 事件,一個只求驗證區塊、不求產生區塊的節點就可以把本地的狀態數據清零,憑藉新收到的區塊附帶的見證消息,建構起剛好足以驗證該區塊的狀態樹;每個見證數據,都會帶來增量的狀態數據,只要節點緩存了自己的狀態樹,則見證數據都是剛好夠用的。當節點本地的狀態數據足夠多,甚至有可能出現無需附帶見證數據的區塊。但是,又不必擔心狀態數據的膨脹問題,因為節點會定期清零狀態。

ReGenesis 是一個特別均衡的方案(實際上也是當今的“無狀態以太坊” 研究的主要方向)。而且,因為它追求的是準-無狀態性,雖然ReGenesis 要求實現基於事務的見證數據,它繞過了基於事務見證數據的無狀態性的一個缺點:需要頻繁更新一筆事務的見證數據,每一次狀態根更新(也即每一次出塊),都要求更新未打包事務的見證數據;但是,在準-無狀態性中,準-無狀態節點每收到一個區塊,本地的狀態就會多一些,而事務被打包的時間必定晚於其廣播的時間,所以事務在廣播時附帶的見證數據必定足以應付驗證的需要。

那麼它的缺點在哪裡呢?

(1)如果一筆事務在事先並不能確定自己會訪問哪些交易(這被稱為“動態訪問模式” [12] ),則有可能並不能提供足夠的見證數據並因此失敗。這並不是一個不可解決的問題,因為根據準-無狀態性,只需多次發起並補充見證數據,總能成功。但這總歸意味著用戶可能要多次發送同一筆事務。

(2)不確定ReGenesis 下節點會不會也拋棄區塊數據,所以rollup 這樣layer-2 方案可能會受到影響。

從我們上面推論下來,ReGenesis 很像一種無狀態或者準-無狀態方案。但是,從另一個角度看,ReGenesis 也很像一種“狀態保質期”方案或者“狀態租金” 方案:每過一段時間,所有的狀態對像都會過期、失活,而你為了讓自己的狀態復活,必須支付額外一筆代價;而用戶的一次付費,也只能保證相關狀態在節點處能存儲一段時間,而無法保證能永久存儲。

從這個角度看,ReGenesis 會面臨另一個所有狀態保質期方案都會面對的問題:“復活衝突”。如果有人在已經失活的狀態存儲位置直接創建了一個新狀態(而不是通過提供見證數據來復活這個狀態),那就會產生衝突—— 從前的富狀態節點(存儲著已經失活的舊狀態)無法與無狀態節點(存儲著新建的狀態)達成共識。對應的ReGenesis 上,就是regenesis 事件觸發後,有人嘗試在原本已經有狀態的存儲位置上新建一個狀態(比如直接給自己的賬戶存進10 ETH),一直存儲著狀態數據的富狀態節點,就將無法與剛清零了狀態的無狀態節點,對狀態根達成共識(因為餘額對不上)。

Vitalik 為此提出的解決方案[12] 是:給賬戶安排一個與其創建時期相對應的標識符(例如,同一個地址0x1234,在第0 個regenesis 時段創建的賬戶就標記為(0, 0x1234),而第4 個regenesis 時段創建的賬戶就標記為(4, 0x1234) ),從而明確用戶到底是想復活自己在從前時段創建的狀態,還是想新建一個狀態,從而解決復活衝突問題。

當前,ReGenesis 已經完全被當成一個狀態保質期方案,與弱無狀態性所代表的無狀態性方案相競爭 [12]。但在我看來,由於其運行需要使用見證數據,而圍繞見證數據使用的研究是從無狀態性的研究中生髮出來的,所以無狀態性是一個不應被放棄的視角,尤其是準-無狀態性的概念,非常富有啟發性。

注10:Alexey Akhunov,https://ethfans.org/posts/regenesis-resetting-ethereum-to-reduce-the-burden-of-large-blockchain-and-state

注11:Igor Mandrigin,https://ethfans.org/posts/37566

注12:Vitalik Buterin,https://ethresear.ch/t/resurrection-conflict-minimized-state-bounding-take-2/8739

(四)總結

從無狀態性和準-無狀態性的概念出發,我們最終走向了ReGenesis 這種較為均衡的方案。從狀態保質期的角度出發,也可以得出ReGenesis 相當有競爭力的結論。但是,這絕不意味著無狀態性的研究已經完成或者已被淘汰。事實上,我們還未能確定無狀態性帶來的所有影響是否都已被分析清楚了,因此,也無法斷言已經出現了絕對值得實現的方案。而且,就算方案確定了,工程上獲得安全高效的成果,仍有待時日(比如,假設真的把狀態樹從默克爾樹改為Verkle Tree,工程上需要花多少時間?)。因此,對無狀態性的實現,我並不那麼樂觀。

接下來,我們重新回到狀態膨脹問題,看看對這個問題的不同表述,會不會給我們帶來一些啟發。

四. 問題到底出在哪兒?

狀態膨脹問題到底意味著什麼?它在何種意義上是一個問題?如何為之歸因並提出可行的解決方案?如何衡量一種解決方案是否有價值?

你至少可以從以下幾個方面,來思考狀態膨脹給我們帶來的影響:

(一)它會使區塊驗證的成本不斷升高,因此抬高全節點運行的門檻;

(二)它意味著一種只增不減的永久性負擔,對網絡的長期存續和去中心化是一種威脅;

(三)它意味著鏈上操作的Gas 定價有持續存在的失衡風險(也是DoS 風險);

我們一個一個來。

(一)驗證成本

為什麼狀態數據的增加會提高區塊驗證的成本?因為對以太坊來說,(1)區塊的執行和區塊的驗證是一回事,都是完全執行所有的計算過程;(2)區塊驗證要求本地具備最新的狀態數據;(3)狀態數據的增加意味著對單個狀態對象的讀取和寫入變得更困難。這三個條件中,任一因果關係被打破或被削弱,狀態膨脹給區塊驗證帶來的影響都會被削弱甚至消除。

假如區塊的驗證與執行不是一回事、區塊驗證的開銷是個常量,則狀態膨脹問題不會影響區塊驗證的成本;這就是Mina 等新興區塊鏈採取的思路:每次出塊,出塊者都會為區塊的執行過程生成一個計算完整性的證明,驗證方只需驗證這個證明就可以驗證相關區塊的合法性,而驗證的開銷是個常量,這就打破了狀態膨脹對區塊驗證成本的影響。理論上來說,以太坊也可以引入類似的技術;而我們要付出的代價是:找出一種安全可靠的、能夠為通用計算實現計算完整性證明的工程實現、可能完全改變應用開發者的體驗、需要重新設計鏈上操作的Gas 消耗量比例。

同理,無狀態性就是在打破或說影響第(2)條因果關係。實現無狀態性之後,區塊驗證就不再要求本地存儲最新的狀態數據了,但它還留下了一種風險:隨著狀態數據的增加,見證數據增大(因此驗證區塊的帶寬開銷增大)的風險。

而(3)則向我們指出,優化客戶端同樣有助於減少這個問題對我們的影響。舉例而言:Geth 客戶端1.10 版[13] 實現了狀態快照,該功能可以保證狀態讀取的開銷是一個常量,也即消除了狀態膨脹對狀態讀取的開銷的影響;但是,即使優化到極致,狀態寫入的開銷仍然會隨著狀態數量的增加而增加。

注13:Péter Szilágyi,https://ethfans.org/posts/geth-v1-10-0-introduction

(二)永久性負擔

從這個角度看,問題出在:(1)用戶可強制要求節點存儲自己的狀態;(2)支付與成本在時段上的不匹配,一次付費永久存儲。

無狀態性的激進和革命之處就在於,它針對的是(1),而不是(2),也即它不把這個問題解釋為一個經濟機制問題,也不考慮改變經濟模型來解決這個問題。無狀態性完全消除了節點與本地的一部分特殊數據(狀態數據)交互以驗證區塊的需要,從而完全免去了存儲狀態數據需要。實現了無狀態性之後,存儲部分還是全部狀態完全由節點運營者自己決定,用戶實際上無法強制所有節點來存儲自己的狀態,只能預期礦池或者錢包服務提供商這樣的專業運營商會存儲自己的狀態,而這是完全公平的。

而針對(2)的解決方案可分為兩類:一類的傾向是:一次付費、有限時段存儲;無限時段存儲、持續付費。前者的代表是各種狀態保質期方案;後者的代表是Nervos 區塊鏈。

在Nervos 區塊鏈上,用戶要存儲狀態時就必須綁定一定數量的區塊鏈原生資產CKB,綁定的代幣數量與可寫入的狀態數據大小是成恆定比例的;由此,用戶在存儲狀態時,雖然沒有貨幣支出,但因資產綁定而承受的不便利(或者說損失的機會收益),就是一種持續的、與存儲狀態的時長一一對應的成本。因此,這一模式約束了用戶存儲狀態的行為;而且CKB 的數量就構成了狀態數據的上限,控制了狀態膨脹。

而狀態保質期方案,相比無狀態性就顯得有點半心半意—— 在許多狀態保質期方案中,它雖然能約束狀態數據的大小(因為給定時間段內能刷新的狀態對像數量是有限的),但不一定能降低與特殊數據交互的需要,它需要額外的數據結構來記錄失活狀態的信息,也需要與這一數據交互。解決復活衝突實際上也就是在解決這個問題。

另外,包括ReGenesis 在內的狀態保質期方案也意味著,整個網絡的事務處理容量,會被一類並不創造經濟價值、僅僅是為了繳納租金(或者說購買保險)的狀態復活事務給佔去一塊。這使人疑心狀態保質期到底是不是一個長期可持續的、能獲得民意支持的方向,畢竟,用戶是會越來越多的。

(三)操作碼Gas 定價失衡

鏈上操作的Gas 消耗量的絕對值是沒有意義的,一個操作消耗100 Gas 並不意味著什麼;有意義的是不同操作的Gas 消耗量比例:一個消耗100 Gas 的操作的計算開銷被認為是一個消耗1 Gas 的操作的100 倍。它的意義有兩重:(1)它引導應用開發者優化代碼的方向,假設兩個操作路徑都可以達到同樣的效果,而一條路徑的Gas 開銷更低,開發者就會實現這個路徑;( 2)如果這個比例失衡了,那就意味著某種操作的名義開銷(Gas 消耗量)偏離了其實際開銷,而這樣的操作碼就更有可能被利用來發起對節點的DoS 攻擊。著名的“上海攻擊” 就是這樣:攻擊者在事務中包含了大量Gas 消耗量很低、但節點實際計算開銷很大的操作碼,而處理這些事務會使節點負載過大而掉線。

狀態膨脹就會引發這樣的失衡問題:狀態操作的Gas 開銷是一個常量,但狀態讀寫的開銷實際上並不是一個常量,它會隨著狀態數量的增加而增加。那為什麼狀態操作的Gas 開銷不能實時、動態變化呢?因為狀態讀寫邏輯上是由EVM 來實現的,但實際上並不是,它是由客戶端軟件的數據庫來實現的,不同客戶端的實際開銷既不統一,也無法被EVM 感知。

值得提醒的是:上述兩種效果是會相互疊加的。如果相關操作的名義開銷比例,恰好引導著應用開發者使用這種實際開銷被低估的資源,則問題就會變得更嚴重—— 其實狀態膨脹問題本身就是這樣的一個例子,狀態讀寫的名義開銷定得太低了。

當前以太坊社區的做法是,通過硬分叉來調整不同操作的Gas 消耗量。這就等於是說,以太坊當前的治理程序,充當了EVM 感知狀態操作開銷的信息輸入機制。這樣做當然不能完美地解決這個問題,它同時也提醒了我們,以太坊這台電腦有多麼依賴人類工程師的定期修理。

此外,合理的Gas 定價還要面臨的另一個挑戰是:它要用同一個度量單位,來度量本質上需要不同資源的操作的開銷比例。

談到這一點,是因為無狀態性也受該問題的影響。在當前,節點執行區塊的主要開銷並不是計算,而是狀態的讀寫;而使用見證數據取代了狀態數據之後,主要的開銷就變成了帶寬。當然,出塊者生成見證數據需要計算,但即使我們不考慮這一點,或認定當前的狀態操作名義消耗量已足夠準確,我們仍必須考慮怎麼約束見證數據大小的問題。好的辦法無疑仍是價格,但其Gas 消耗量應如何確定呢? (注:CALLDATA 類型數據的定價就有點像是根據帶寬消耗量來定價。這值得我們深思。)

(四)回到無狀態性

了解了這些問題,我們也許更能明白無狀態性究竟解決了什麼問題,又留下了哪些問題等待解決。實際上,我們再回過頭來看無狀態性,其原理是很單純的:以帶寬開銷換取硬盤讀寫的節約。但是,能截然認為這一定是值當的嗎?假設我們生活在一個硬盤讀寫就是很便宜,而帶寬就是非常稀缺的世界裡呢?或者說,假設日後兩種資源的價格會倒轉過來呢?

換言之,無論選擇無狀態性還是保持原狀,從事後來看可能都是不夠靈活的選擇—— 最理想的情況,應該是節點能自己選擇犧牲哪個換取哪個,並隨時切換,而不是由一個治理程序強制大家選擇某一種,這種選擇再好,終究只是有限頭腦的智慧的產物,而且都不能排除要依賴治理程序(在日後把選擇顛倒過來)的風險。

這是否意味著,最優的方案應該是一個跟當前的以太坊網絡部分重疊、平行運行的無狀態客戶端網絡?用戶能自由加入,自由切換?我們能擁有這樣的方案嗎?

五. 結語

自19 年3 月了解了“無狀態性” 概念以來,我便認定,無狀態性是以太坊最值得研究的底層協議演化方向,唯有它能既解決狀態膨脹問題,又維持以太坊的經濟屬性。今天我仍這麼相信。只是,對狀態膨脹問題的思考,會不斷牽涉到以太坊的底層範式—— 全局狀態和鏈上計算—— 最終具象化為一個問題:如何為鏈上操作制定名義開銷比例(gas cost)?無論要對以太坊作什麼改進,都繞不開這個問題。最終你也會得到跟我一樣的結論:以太坊的設計失衡之處不是一處,而是兩處。無狀態性之後,我們仍有迢迢長路。

的確,本來,對任何彌賽亞的期待,都是一種幻想。此際,讓我們先解決以太坊長期生存道路上最大的障礙:狀態膨脹。

(完)

(文內有許多超鏈接,可點擊左下”閱讀原文“ 從EthFans 網站上獲取)

作者: 阿劍