BTC
ETH
HTX
SOL
BNB
查看行情
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

觀點:以“狀態” 視角理解以太坊及其未來

以太坊爱好者
特邀专栏作者
本文約8109字,閱讀全文需要約12分鐘
各種發展方向如何利用和改變以太坊範式?
AI總結
展開
各種發展方向如何利用和改變以太坊範式?

編者按:本文來自以太坊愛好者(ID:ethfans),Odaily經授權轉載。

編者按:本文來自

以太坊愛好者(ID:ethfans)
以太坊愛好者(ID:ethfans)
,Odaily經授權轉載。

一級標題

一. 引言

編者按:本文來自
以太坊愛好者(ID:ethfans)
以太坊愛好者(ID:ethfans)
,Odaily經授權轉載。
一級標題
編者按:本文來自
以太坊愛好者(ID:ethfans)
以太坊愛好者(ID:ethfans)
,Odaily經授權轉載。
一級標題
一. 引言
自2015 年創世以來,以太坊區塊鏈已歷經五個寒暑。五年的時間不僅把作為一種理念的以太坊協議1 變成現實、使這套協議變得更加成熟、更加具體,也使這樣一套設計的特性和權衡關係暴露出來。這些權衡關係,作為設計上的挑戰,自然也吸引了並持續吸引著無數聰明才智,嘗試提升以太坊的可用性;其中匯聚了最多努力和想像力的,當屬為提高“可擴展性” 而提出的一系列方案。
本文想指出的是,就像以太坊範式面臨著設計上的取捨,所有這些可擴展性方案也面臨著取捨;而評價這些取捨的值得與不值得,需要我們回到以太坊本身,回到以太坊節點和以太坊用戶的真實問題和真實需要。而“狀態” 視角,作為理解以太坊本身的視角,正好能幫助我們廓清這些方案的設計,並揭示我們的所得和所失。

本文將從解釋“狀態” 的含義開始,揭示以太坊的終極之矛和阿喀琉斯之踵,然後探討各種改進方向。 “富狀態性” 是以太坊智能合約“可組合性” 的來源,但也是以太坊網絡最大的弱點。由此,我們可以見出現在常被人提起的哪些方案會影響“可組合性”,哪些“可擴展性” 的意義更明顯。

二. 以太坊作為一種範式
(一)富狀態性與可組合性
什麼是“狀態”?狀態就是一個系統在某一個時刻的具體情形。以實現密碼學貨幣的區塊鍊為例,一個區塊鏈在某一個時刻的狀態就是該時刻,該區塊鏈上所有地址的資產分佈(A 地址有10 個幣,B 地址有100 個幣,等等)(究其實,我們擁有的,只不過是一些狀態,是我們的頭腦和社會共識,將這些狀態解讀為“資產”)。
在此視角下,每一套區塊鏈協議都可以粗略地分成兩個部分,一部分是共識機制,另一部分是狀態轉換規則(有時也被稱為“共識規則”);前者定義了出塊規則,它指明了所有參與該區塊鏈的節點在什麼時候需要在本地更新區塊鏈數據庫的狀態(例如,作為一個以太坊區塊鏈的節點,每當收到一個附帶了符合難度要求的工作量證明的區塊,該節點就更新本地的區塊鏈數據庫的最新狀態);而狀態轉換規則,則定義了什麼交易是有效的(“一個賬戶不能花用超出自己餘額的錢”),也定義了節點在處理交易時,應當如何更新狀態(“這筆交易表示A 賬戶轉了5 個幣給B 賬戶,那麼A 賬戶餘額就減去5,B 賬戶餘額的加上5”)。
對比特幣來說,其共識機制是“PoW + 中本聰共識”,而其狀態轉換規則基於UTXO。對以太坊來說,其出塊機制是“PoW + Ghost 規則”,其狀態轉換規則基於賬戶。
那麼,到底是什麼東西讓以太坊變成一個有突破性的創新呢?
我們時常聽說,以太坊之所以特別,在於其“引入了圖靈完備的編程語言,支持可編程性” 等等。實際上這種說法並不准確2。因為允許使用更複雜的編程語言並不意味著什麼,其實比特幣也可以編程;允許比特幣使用solidity 編程語言並不能得到一個以太坊。以太坊真正特殊的地方在於“富狀態性(rich statefulness)”3 :它允許一個合約調用另一個合約,並且,除了區塊容量本身,不對這種調用的層級數量施加任何的限制。
B 合約可以根據A 合約公開的代碼來調用A 合約、改變A 合約的狀態;調用B 合約的C 合約也可以間接地調用A 合約、改變A 合約的狀態…… 由此,一個狀態,雖然保存在A 合約裡,但其控制邏輯,可以如此重重疊疊不斷累加;如果把狀態理解為資產,這等於是讓資產的使用權(使用條件)可以不斷得到更嚴格、更複雜的控制;這意味著,從理論上來說,一個狀態的更新邏輯能夠無限接近於現實生活中的金融合約(因為所有的金融合約都可以通過簡單的邏輯疊加、組合出來)。這種允許累加任意多層的控制的屬性,才是最關鍵的,而怎麼編程這種控制,反而是次要的。

此外,以太坊還允許用戶給區塊鏈寫入狀態,使這些狀態成為全局狀態的一部分,並要求節點按照合約自定義的邏輯來更新狀態。由此,一個合約能夠把自身的狀態向以太坊上的所有其它賬戶公開,前述的富狀態性真正有了用武之地。

沒錯,現在我們已經像收集龍珠那樣集齊了三種屬性:

(1)鏈上計算範式:合約可以要求節點按自己定義的邏輯來執行計算;

(2)全局狀態:合約的狀態可以成為全局狀態的一部分,向所有其他賬戶公開;
(3)富狀態性:合約之間可以相互調用,且棧層數量沒有限制,因此控制邏輯可以層層累加;
現在我們可以召喚出以太坊的最強之矛了:“可組合性”(貨幣樂高)!
(二)狀態數據爆炸問題
(一)Layer-2 方案
“可組合性”太美好了,以至於不像是真的,對嗎?沒錯,上述三種屬性的三位一體,實際上是一把雙刃劍。
以太坊的狀態轉換過程可以抽象為:狀態轉換函數以舊的狀態和事務(transaction)列表為輸入,輸出新的狀態。這意味著,以太坊的全驗證節點必須在本地維護著以太坊區塊鏈的最新狀態,以便能執行狀態函數並以結果來驗證一個區塊的有效性(同時也是與其他的以太坊節點達成共識)。

矛盾之處在於:對於合約及開發者來說,合約的狀態作為以太坊全局狀態的一部分,保存在以太坊的節點上,合約的狀態更新由以太坊節點來計算(而且還是由發起計算請求的用戶來付費的),這種“無服務器” 的架構非常舒服;但是,這些狀態只要一次付費就會永久保存在以太坊的全驗證節點中,雖然每次更新都需要付費,但無法避免節點本地保存的狀態數據會不斷累積、膨脹。

狀態數據的膨脹之所以是一個問題,在於它會為全驗證節點帶來越來越高的硬盤(隨機)讀寫負擔。狀態數據不像區塊數據,區塊數據是靜態的,持久化保存後並不需要頻繁讀寫;但狀態數據每多一個區塊就要讀寫許多次;而隨著狀態數據量的增大,讀寫的負擔也會越來越重。在過去幾年中,我們時常聽到有人說以太坊的全節點難以部署,一大原因即在於此。前一段時間Infura 的免費以太坊節點服務崩潰4,導致許多依賴Infura 的服務崩潰,算是給大家鳴響了一個警鐘—— 原來以太坊的節點維護如此不易,讓大家寧願選擇信任他人。
這個問題也並不容易解決。在過去幾年中,以太坊的多次硬分叉升級都提高了訪問狀態的操作碼的Gas 消耗量,正是為了以經濟代價遏制合約創建新的狀態。但這顯然只是治標的辦法,因為根本上邏輯並沒有變,狀態數據要持續存留在以太坊節點處,但創造狀態數據的用戶只需付一次費。也有人提出,為改變這一點,需要引入某種“狀態租金” 機制,要求保存了狀態的合約不斷支付租金,否則就終止該合約的可用性。但是,這種機制存在難以想像的複雜度,一方面,難以確定合理的收取租金的方法,另一方面,也難以確定合理的支付對象。所以狀態租金機制的研究在2019 年也停滯了5。還有項目(如Nervos)嘗試以持幣量的多少來界定可用的狀態空間大小,因此狀態數據的大小將總是有上限的,這就避免了狀態膨脹問題,但這也改變了原生資產的經濟屬性。
到目前為止,除了“無狀態性”,我沒有看到令人滿意的、從根本上解決這個問題的方法,而“無狀態性”,我們現實地說,也面臨許多挑戰。這個我們後文再說。
接下來,我們以“狀態” 視角,來理解諸種可擴展性方案的設計和權衡。
(二)分片
三. 以太坊的發展方向

在此章節中,我們會分析四種以太坊的發展方向:Layer-2 方案、分片、無狀態性和Rollup 方案。這個分類是完全不合理的,因為rollup 是Layer-2 方案的子集;而無狀態性是分片的前置技術;甚至於,將它們並列也是不合理的,因為Layer-2 方案幾乎不需要改動以太坊的底層,而分片和無狀態性則有這樣的要求。這樣做只是為了敘述和認識的方便。

(一)Layer-2 方案
Layer-2 方案背後的理念來源於一種簡單但非常精準的直覺:以太坊之所以會面臨吞吐量的瓶頸,是因為組成以太坊網絡的節點的帶寬、計算能力和維護狀態數據的能力都是有限的,而且很難提高;單純要求整個網絡的節點在單位時間內處理更多的交易,節點的運行要求必然上升,這就損及了去中心化;但是,從使用的角度看,並不需要讓所有的狀態都放在以太坊上,也不需要讓所有的狀態計算都在以太坊上發生;我們可以把一個合約的中間狀態(或者所有狀態)都保存在別的地方,用戶的交互(也即狀態的更新)也不在以太坊區塊鏈上發生;僅當用戶認為有必要結算某個狀態時,再將該狀態發送到以太坊上,由以太坊來加以確認。
一句話:如果我們沒法讓網絡在單位時間內對更多的事務達成共識,那就提高單筆事務的內涵。
經典的Layer-2 方案“狀態通道” 最徹底地體現了這種思想:當參與一個通道的兩個用戶將資金鎖入合約後,此後兩人之間的交易都不會發到鏈上,他們彼此之間使用其他通訊工具來交流簽名消息,並以此達成彼此對通道內狀態的共識(因此無論他們之間收發多少消息、形成多少狀態數據,都不會成為以太坊的負擔);直到兩人認為不再需要交互了(或者有必要暫時結算一次了),就把共同認可的狀態及兩人的簽名發送到以太坊上,以太坊這才更新該合約的狀態,並根據此狀態為兩人結算資金。
如果你把Layer-2 方案當成合約的一種設計模式,你會更清楚地看到—— Layer-2 方案選擇了不去利用全局狀態。另一個合約並不能實時地知道某個Layer-2 合約內部到底是什麼狀態(用戶A\B\C 都各有多少錢),因為這些狀態並不在鏈上,也因此,一個Layer-2 合約就無法與其它合約相組合了。
雖然如此,Layer-2 方案也換來了極有價值的東西:更快的交易速度(雖然被確認的中間狀態沒有主鏈狀態這麼安全)、更低的手續費、更小的主鏈節點負擔。
但Layer-2 方案為什麼在過去幾年中都沒有結出果實呢?因為在Rollup 方案出現以前,其他方案,包括狀態通道和Plasma,都沒法證明鎖入自己合約的資金與鎖入帶狀態合約中的同樣安全(既不會被凍結,也不會被盜走) 。在狀態通道方案中,如果你沒有時刻監控區塊鏈,你的交易對手可以通過向主鏈提交舊的狀態,來“盜” 走你的錢;在Plasma 方案中,往往你需要依賴於運營者來為你提供自己狀態的證明,因此它對運營者本身是很難設防的。

這跟以太坊主網帶狀態合約的使用體驗完全不同。除去合約的代碼風險,你存入合約的錢,如非有人發動51% 攻擊取消你的所得交易,否則不會被盜;除非有人一直通過51% 攻擊來審查你的交易,否則你必定可以將自己的資金取出。 (在後文中,我們會看到Rollup 方案是怎麼解決這個問題的。)

(二)分片
另一種改進以太坊、提高以太坊吞吐量的直覺是:以太坊的吞吐量有限,源於每個全節點都必須處理所有鏈上交易;如果我們可以讓每個節點只處理一部分交易,不同組的節點分別(並行化地)處理不同的交易,那麼整個系統在單位時間內的吞吐量就等於這幾組節點的單組處理量的總和;即,單個節點的負擔並沒有增加,但整個系統的吞吐量提高了(而且分組越細,吞吐量的乘數越大)。這就是所謂的“分片”。
關於分片化架構,一個有趣的問題是其確切定義。在經典的、非分片化的區塊鏈架構中,全節點必須(1)重複所有計算;(2)維護所有狀態;(3)傳播所有區塊/交易。有人認為,只需打破一者,就算是分片化的了;但從更嚴格的視角看,必須打破所有三者,才能達到理論所推導的吞吐量提升效果6。取不同的定義,帶來的效果也很不同。此處,我所採取的定義是,一個節點至少無需維護整個系統所有的狀態。
在以太坊基金會的研究團隊所構想的分片架構中,整個系統的狀態被分割成了幾個部分,各部分是並行更新的,也就是說,一個分片並不能實時地了解另一個分片的內部狀態。當位於分片A 的合約A' 嘗試調用分片B 上的合約B' 時,並不能假設處理者擁有分片B 的狀態,也因此,處理的結果必須等待分片B 完成狀態更新後才能返回。由此,跨分片的交易必須忍受事務處理中最難以忍受的代價:時延。關鍵在於,此種時延是不能用貨幣代價來加以抽象的。因為分片B 也並不知道分片A 上發生了一筆需要調用自身的交易,因此只能等待一個可信的通信層為自己播報這條交易。
(四)Rollup 方案
單位時間內能夠創造的價值越高,時延越不可忍受;而這意味著,假設有某個DeFi 應用集中的分片,這些應用根本不會通過跨分片的交易來調度其它分片上的處理能力,因為這根本沒有意義,滿足不了DeFi 應用對時延的要求。同樣,這也意味著,這個DeFi 應用集聚的分片,其單分片處理能力就是其處理能力上限(與單條區塊鏈沒有區別)。在深山老林裡造房子和修路,解決不了大都市里人們的生活空間問題。
(有人認為,這些“閒置” 的分片吞吐量可以為更小眾的應用所用。我認為,Layer-2 方案能達到同樣的效果,而且對底層的改動更少,更安全。)
(三)無狀態性(statelessness)
無狀態性是唯一直面了狀態數據膨脹問題的升級方向7。
在當前的以太坊協議中,交易自身並不攜帶自身所訪問的狀態的信息,正是因此,處理交易的節點才必須維護狀態數據,作為執行狀態轉換函數的前置條件。也正因此,狀態數據的膨脹才是一個問題(提高節點負擔)。

而無狀態性的關鍵,正是讓交易/區塊自身附帶所訪問狀態的信息,因此,一個區塊僅憑自身就是可驗證的,無需處理交易的節點具有狀態。

實際上,無狀態性是通過改變以太坊區塊的結構,改變以太坊區塊的驗證方式。無需維護狀態數據,也就免去了讀寫硬盤的需要,區塊驗證的速度也可以更快。此外,各節點既可以完全不維護狀態數據,也可以根據自己的需要,維護某些合約的狀態數據。
但是,誠實地說,無狀態性目前還面臨許許多多的設計挑戰。具體來說:(1)無狀態性要求為區塊/交易附加所訪問狀態的證明(witness),這部分數據的規模可能非常大,以太坊當前的區塊數據大小大概是20~40 KB,但witness 數據的大小可能在MB 級別(視所訪問狀態量的大小而定);(2)只有維護了所有狀態的節點才能組裝出witness,那麼誰來為普通用戶提供狀態呢? (實際上,可以把這個視為以太坊運作假設的一個轉變:原來所有的全節點都能參與挖礦;但無狀態性實現之後就不是了);(3)如何為交易的gas 消耗量定價?尤其因為witness 有時效性,並不能根據操作碼來確定組裝witness 耗費了多少計算量。

ETH
开发者
投资
歡迎加入Odaily官方社群