探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

作者:Faust,極客web3

關於Plasma為何被長期埋沒,以及Vitalik會大力支持Rollup,線索主要指向兩點:在以太坊鏈下實現DA是不可靠的,很容易發生數據扣留,而數據扣留一旦發生,欺詐證明就難以展開; Plasma的機製設計本身對智慧合約極為不友好,尤其難以支援合約狀態遷移到Layer1。這兩點使得Plasma基本上只能採用UTXO或近似的模型。

為了瞭解上述兩個核心觀點,我們先從DA和資料扣留問題講起。 DA的全名是Data Avalibility,字面譯作資料可用性,現在被很多人誤用,以至於和」歷史資料可查「嚴重混淆。但實際上,」歷史資料可查「以及」儲存證明「是Filecoin和Arweave等早已解決的問題。根據以太坊基金會和Celestia的說法,DA問題單純探討數據扣留場景。

Merkle Tree和Merkle Root及Merkle Proof

為了說明資料扣留攻擊與DA問題究竟指什麼,我們需要先簡單講一下Merkle Root和Merkle Tree。在以太坊或絕大多數公鏈中,用一種稱作Merkle Tree的樹狀資料結構,充當全體帳戶狀態的摘要/目錄,或記錄每個區塊內打包的交易。

Merkle Tree最底層的葉子節點,由交易或帳戶狀態等原始資料的hash構成,這些hash兩兩一組求和,反覆迭代,最終可以算出一個Merkle Root.

Merkle Root有一個性質:如果Merkle Tree底層某個葉子節點發生變化,計算得到的Merkle Root也會改變。所以,對應不同原始資料集的Merkle Tree,會有不同的Merkle Root,就好比不同的人有不同的指紋。而被稱為Merkle Proof的證明驗證技術,利用了Merkle Tree的這個性質。

以上圖為例,如果李剛好只知道圖中Merkle Root的數值,不知道完整的Merkle Tree包含哪些資料。我們要向李剛證明,Record 3的確和圖中的Root有關聯性,或者說,證明Record 3的哈希存在於Root對應的那棵Merkle Tree上。

我們只需要把Record3,以及標記為灰色的那3 個digest資料塊,提交給李剛,而不必把整個Merkle Tree或其所有葉子節點都提交過去,這就是Merkle Proof的簡潔性。當Merkle Tree底層記錄的葉子特別多時,例如包含了2的20次冪個資料塊(約100萬),Merkle Proof最少只需要包含21個資料塊。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

(圖中的資料塊30和H2就可以構成Merkle Proof,證明資料塊30存在於H0對應的Merkle Tree上)

在比特幣、以太坊或跨鏈橋中,常用到Merkle Proof的這種「簡潔性」。我們所知的輕節點,其實就是上文提到的李剛,他只從全節點接收區塊頭header,而不是完整的區塊。這裡需要強調,以太坊用稱為State Trie的梅克爾樹,充當全體帳戶的摘要。只要State Trie關聯的某個帳戶狀態發生變化,State Trie的Merkle Root——稱為StateRoot就會變化。

在以太坊的區塊頭中,會記錄StateRoot,同時也會記錄交易樹的Merkle Root(簡稱Txn Root),交易樹和狀態樹的一個區別,在於底層葉子所代表的資料不同。假如第100號block內包含300筆交易,則交易樹的葉子,代表的就是這300筆Txn。

另一個區別在於,State Trie整體的資料量特別大,它的底層葉對應著以太坊鏈上所有地址(實際上還有很多過時的狀態哈希),所以State Trie對應的原始資料集不會發布到區塊中,只在區塊頭記錄下StateRoot。而交易樹的原始資料集就是每個區塊內的Txn數據,這棵樹的TxnRoot會被記錄在區塊頭裡。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

由於輕節點只接收區塊頭,只知道StateRoot和TxnRoot,不能根據Root反推出完整的Merkle Tree(這是由Merkle Tree和哈希函數的性質決定的),所以輕節點無法獲知區塊內包含的交易數據,也不知道State Trie對應的帳戶發生了哪些變化。

如果王強要向某個輕節點(前面提過的李剛)證明,第100號block中包含某筆交易,已知輕節點知道100號block的區塊頭,知道TxnRoot,那麼上述問題轉化為:證明這筆Txn存在於TxnRoot所對應的那棵Merkle Tree上。這時候,王強只要提交對應的Merkle Proof即可。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

在許多基於輕客戶端方案的跨鏈橋中,常常會用到上面講到的,輕節點和Merkle Proof的輕量與簡潔性。比方說,Map Protocol等ZK橋,會在ETH鏈上設定一個合約,專門接收其他鏈的區塊頭(例如Polygon)。當Relayer向ETH鏈上的合約,提交Polygon第100個區塊的header後,合約會驗證header的有效性(例如是否湊足了Polygon網路內2/3 POS節點的簽章)。

如果Header有效,且某用戶聲明,自己發起了從Polygon到ETH的跨鏈Txn,該Txn被打包進了Polygon第100個區塊。他只要透過Merkle Proof,證明自己發起的跨鏈Txn,能對應上100號區塊頭的TxnRoot(換句話說,就是證明自己發起的跨鏈Txn 在Polygon的100號區塊內有記錄)。只不過ZK橋會透過零知識證明,壓縮驗證Merkle Proof所需的計算量,進一步降低跨鏈橋合約的驗證成本。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

DA與資料扣留攻擊問題

講完了Merkle Tree和Merkle Root、Merkle Proof,我們回到文章最開頭說到的DA與數據扣留攻擊問題,這一問題早在2017年以前就被人探討過,Celestia原始論文有對DA問題的來源進行考古。 Vitalik本人則在2017~18年的一個文件中,談到出塊者可能故意隱瞞block的某些資料片段,對外發布不完整的區塊,這樣一來,全節點就無法確認交易執行/狀態轉換的正確性。

此時,出塊者可以盜取用戶資產,例如把A帳戶中的幣全部劃轉到別的地址,而全節點無法判斷A本人是否有這麼做,因為他們不知道最新區塊包含的完整交易數據。

在比特幣或以太坊等Layer1公鏈中,誠實全節點會直接拒收上述無效區塊。但輕節點則不同,他們只從網路接收區塊頭Header,只知道StateRoot和TxnRoot,不知道Header和兩個Root對應的原始區塊是否有效。

在比特幣白皮書中,其實有對這種情況作出腦洞,中本聰曾認為,大多數用戶會傾向於運行配置要求較低的輕節點,而輕節點無法判斷區塊頭對應的block是否有效,如果某個block無效,誠實全節點會向輕節點發出警報。

但中本聰並沒有對這個方案進行更細緻的分析,後來Vitalik和Celestia創始人Mustafa在這個idea之上,結合其他前人的成果,引入了DA數據採樣,確保誠實全節點能夠還原出每個區區塊的完整數據,並在必要時刻發出警報。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

註:DA資料採樣(DAS)與Celestia並不是本文要探討的重點,有興趣的讀者可以閱讀《極客web3》過往文章:《對資料可用性的誤解:DA=資料發布≠歷史資料檢索》

Plasma的詐欺證明

簡單來說,Plasma是一種只將Layer2的區塊頭發佈到Layer1上的擴容方案,區塊頭以外的DA資料(完整的交易資料集/每個帳戶的狀態變化)只在鏈下發布。換句話說,Plasma就像基於輕客戶端的跨鏈橋一樣,在ETH鏈上用合約實現了Layer2的輕客戶端,當用戶聲明要把資產從L2跨到L1時,要提交Merkle Proof,證明自己的確擁有這些資產。

資產從L2跨到L1的驗證邏輯,和前文中談到的ZK橋比較類似,只不過Plasma的橋接模型是基於詐欺證明,而不是ZK證明,更接近所謂的「樂觀橋」。 Plasma網路中從L2到L1的提款請求不會被立刻放行,而是有一個“挑戰期”,至於挑戰期的目的是什麼,我們會在下面講解。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

Plasma對資料發布/DA沒有嚴格要求,排序器/Operator只是在鏈下廣播每個L2區塊,有意願取得L2區塊的節點去自行取得。之後,排序器會把L2區塊的Header發佈到Layer1。比如說,排序器先在鏈下廣播第100號區塊,之後把區塊的header發佈到鏈上。如果100號區塊中包含無效交易,任何Plasma節點都可以在「挑戰期間「結束前,向ETH上的合約提交Merkle Proof,證明第100號區塊頭能關聯到某筆無效交易,這就是詐欺證明涵蓋的一個場景。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

Plasma的詐欺證明應用場景還包括以下幾種:

1.假設Plasma網路的進度到了200號區塊,此時A用戶發起提款聲明,稱自己在第100號區塊時,有10枚ETH。但實際上,A用戶在100號區塊之後,曾把帳上的ETH花掉。

所以,A的行為其實是:花掉10枚ETH後,聲明自己在以前有10枚ETH,並試著把這些ETH提走。這就是典型的“雙重提款”,雙花。此時,任何人都可以提交Merkle Proof,證明A用戶最新的資產狀況,不滿足其提款聲明,也就是證明A在100號區塊後,沒有提款聲明的那些錢(不同的Plasma方案針對這種情況的證明方法不一致,帳戶地址模型遠比UTXO的雙花證明麻煩的多)。

2.如果是基於UTXO模型的Plasma方案(過去主要都是這種),區塊頭中是不包含StateRoot的,只有TxnRoot(UTXO不支援以太坊式的帳戶位址模型,也沒有State Trie這種全域狀態設計)。換言之,採用UTXO模型的鏈只有交易記錄,沒有狀態記錄。

此時,排序器本身可能發動雙花攻擊,例如把某個已經被花掉的UTXO再花一次,或是給某個用戶憑空增發UTXO。任何一個用戶都可以提交Merkle Proof,證明該UTXO的使用記錄在過往區塊中出現過(被花過),或者證明某個UTXO的歷史來源有問題。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

3.對於EVM相容/支援State Trie的Plasma方案,排序器有可能提交無效的StateRoot,比如說,在執行了第100個區塊中包含的交易後,StateRoot應該轉換為ST+,但排序器往Layer1提交的卻是ST-。

這種情況下的詐欺證明比較複雜,需要在以太坊鏈上重播第100號區塊中的交易,計算量和所需的輸入參數會消耗大量gas。早期採用Plasma的團隊難以實現如此複雜的詐欺證明,所以大多採用了UTXO模型,畢竟基於UTXO的詐欺證明很簡潔,也好實現(首個上線詐欺證明的Rollup方案Fuel,就是基於UTXO的)

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

資料扣留與Exit Game

當然,上述詐欺證明能生效的場景,都是在DA/資料發布有效時,才成立的。如果排序器搞資料扣留,不在鏈下發布完整的區塊,Plasma節點就無法確認Layer1上的區塊頭是否有效,當然也無法順利發布詐欺證明。

此時,排序器可以盜取用戶資產,例如私自把A帳戶的幣全部劃轉到B帳戶,再從B帳戶給C轉賬,最後用C的名義發起提款。 B和C帳戶是排序器自己擁有的,B->C這筆轉帳就算對外公示,也無傷大雅;但排序器可以扣留A->B這筆無效轉帳的數據,人們無法證明B和C的資產來源有問題(要證明B的資產來源有貓膩,就要指出」給B轉帳的某筆Txn「的數位簽章有誤)。

基於UTXO的Plasma方案有針對性的舉措,例如任何人發起提款時,都要提交資產的全部歷史來源,當然後來有更多的改良措施。但如果是EVM相容的Plasma方案,會在這塊顯得軟弱無力。因為如果涉及與合約相關的Txn,在鏈上驗證狀態轉換過程會產生巨量成本,所以支援帳戶位址模型和智慧合約的Plasma,不好實現針對提款有效性的驗證方案。

此外,撇開上面的話題,無論是基於UTXO還是基於帳戶地址模型的Plasma,一旦發生資料扣留,基本上都會引發人們的恐慌,因為你不知道排序器都執行了哪些交易。 Plasma的節點會發現不對勁,但又無法針對性的發布詐欺證明,因為詐欺證明所需的數據,Plasma排序器沒發出來。

這時候,人們只能看到對應的區塊頭,但不知道區塊裡面都有什麼,不知道自己的帳戶資產變成了什麼樣,大家會集體發起提款聲明,用對應著歷史區塊的Merkle Proof嘗試提款,引發被稱作“Exit Game”的極端場景,這種情況會導致“踩踏”,使得Layer1嚴重擁堵,並仍會導致一些人資產受損(沒有接收到誠實節點通知或者不刷推特的人,根本不會知道排序器正在盜幣)。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

所以,Plasma是一種不可靠的Layer2擴容方案,一旦發生資料扣留攻擊,就會觸發“Exit Game”,很容易讓用戶蒙受損失,這是其被廢棄的一大原因。

Plasma難以支持智能合約的原因

在講過了Exit Game和資料扣留問題後,再來看Plasma為什麼難以支持智能合約,主要是兩個理由:

其一,如果是Defi合約的資產,該由誰來提領到Layer1?因為這本質上就是把合約的狀態從Layer2遷移到Layer1,假設有人往DEX的LP池子充了100個ETH,之後Plasma的排序器作惡了,人們要緊急提款,這時候用戶的100個ETH都也為DEX合約所控制,請問這個時候這些資產該由誰提到Layer1上?

最好的方法,似乎是先讓用戶從DEX贖回資產,再由用戶自己去把錢提到L1上,但問題是Plasma排序器已經作惡了,隨時可能拒絕用戶請求。

那麼,如果我們事先給DEX合約設定Owner,允許他在緊急情況下,把合約資產提到L1上呢?顯然這會賦予合約Owner公共資產的所有權,他可以隨時把這些資產提到L1上並跑路,這豈不是太可怕了?

顯然,該怎麼處置這些由Defi合約所支配的“公共財產”,是一個巨大的雷。這其實涉及公權力分配的難題,此前響馬曾在訪談《高性能公鏈難出新事,智能合約涉及權力分配》中談到過這點。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

其二,如果不允許合約遷移狀態,會使其蒙受巨額損失;如果允許合約把自己的狀態遷移到Layer1,會出現Plasma詐欺證明難以解決的雙重提款:

例如,我們假設Plasma採用以太坊的帳戶地址模型,支援智能合約,有混幣器,目前存入了100枚ETH,混幣器的Owner由Bob控制;

假設Bob在第100個區塊時,從混幣器中提走50枚ETH。之後Bob發起提款聲明,把這50枚ETH跨到了Layer1上;

之後,Bob用過去的合約狀態快照(例如第70個區塊),把混幣器過去的狀態遷移到Layer1上,這會把混幣器「曾經擁有」的100枚ETH也跨到Layer1上;

顯然,這是典型的“雙重提款”,也就是雙花。有150枚ETH被Bob提到了Layer1,但Layer2網路用戶只向混幣器/Bob付出100枚ETH,有50枚ETH被憑空抽走。這很容易把Plasma的儲備金抽乾。理論上人們可以發起詐欺證明,證明混幣器合約的狀態在第70個區塊之後有變化。

但假如在第70號區塊之後,所有和混幣器合約產生交互的Txn,都沒有改變合約狀態,除了Bob抽走50枚ETH那筆交易;如果你要出示證據,指出混幣器合約在第70號區塊後有變化,就要在以太坊鏈上把上述提及的所有Txn跑一遍,最終才能讓Plasma合約確定,混幣器合約狀態的確發生過變化(之所以這麼複雜,是由Plasma本身的構造決定的)。如果這批Txn數量極大,詐欺證明根本無法在Layer1上發布(會超出以太坊單一區塊的gas上限)。

探究Plasma不支持智能合約的原因:資料扣留與詐欺證明

https://ethresear.ch/t/why-smart-contracts-are-not-feasible-on-plasma/2598

理論上,上面的雙花場景中,似乎只要提交混幣器當前的狀態快照(其實就是對應StateRoot的默克爾證明),但實際上,由於Plasma不在鏈上發布交易數據,合約無法確定你提交的狀態快照是否有效。這是因為排序器本身可能發動資料扣留,提交無效的狀態快照,惡意指證任何一名提款者。

比如說,當你聲明自己帳上有50枚ETH並發起提款時,排序器可能私自把你帳戶清0,然後發動資料扣留,把一個無效的StateRoot發到鏈上,並提交對應的狀態快照,誣告你帳戶裡沒錢了。這時候大家沒辦法證明排序器提交的StateRoot和狀態快照無效,因為他發動了資料扣留,你得不到詐欺證明需要的足量資料。

為了防止這種情況,Plasma節點在出示狀態快照證明某人有雙花行為時,還要重播這段時間內的交易記錄,這可以防止排序器用資料扣留來阻止別人提款。而在Rollup中,如果遇到上述雙重提款,理論上不需要重播歷史交易,因為Rollup不存在資料扣留問題,會”強制要求”排序器在鏈上發布DA資料。 Rollup排序器如果提交一個無效StateRoot-狀態快照,要么無法通過合約驗證(ZK Rollup),要么很快就會被挑戰(OP Rollup)。

其實除了上面談到的混幣器的例子外,多簽合約等場景一樣可以導致Plasma網路發生雙重提款。而欺詐證明對這種場景的處理效率很低。在ETH Research中有對這種情況作出分析。

綜上所述,由於Plasma方案不利於智能合約,基本上不支持合約狀態遷移到Layer1,主流的Plasma只好選用UTXO或類似的機制,因為UTXO不存在資產所有權衝突問題,並且能很好的支持欺詐證明(尺寸小很多),但代價是應用場景單一,基本上只能支援轉帳或訂單簿交易所。

此外,因為詐欺證明本身對DA資料有較強的依賴,如果DA層不可靠,將難以實現高效率的詐欺證明系統。而Plasma對於DA問題的處理太簡陋,無法解決資料扣留攻擊問題,隨著Rollup的崛起,Plasma慢慢淡出了歷史舞台。

Total
0
Shares
Related Posts