致謝:郭宇 撰文:李畫,安比實驗室特約研究員
性能是阻礙公鏈發展的瓶頸,提升性能則是絕大多數希望超越以太坊的公鏈的主要設計目標,但當我們站在今天回望時,會發現這些公鏈選擇的方法大多是通過機制的設計來增強一個分散式系統的性能,但受困於分散式系統CAP定理(不可能三角),改善性能是要付出代價的,當這個分散式系統的用途是賬本時,這些代價甚至可能是難以被接受的。以太坊也一直在嘗試各種方法以提升性能,在2.0被推出的前夜,它「試」出了密碼學。
以太坊2.0將是一個以「分散式系統+密碼學」為基礎來運轉的公鏈,這個密碼學不是指被用於簽名和隱私的那部分,而是指作為一個高性能系統的核心組件的那部分。從這個角度而言,或許我們可以說顛覆以太坊的不是別人,而是它自己。它從分散式系統設計的單一思路中跳了出來,走上分散式系統+密碼學組合設計的道路。這篇文章將試著介紹在以太坊2.0中,分散式系統設計如何與密碼學設計結合,實現公鏈在性能上突破。
一
狀態分片:從單賬本到多賬本
區塊鏈是一個分散式賬本,出塊節點是記賬的礦工,它們負責把交易寫入賬本。除了競爭記賬權,出塊節點最重要的工作,或者說本職工作就是檢查自己打包的這些交易是否合法。完成這個工作並不難,因為出塊節點手中握有賬本,它去查一下交易發送方有沒有這筆錢即可。
對於未分片的公鏈,所有節點都持有一個相同的賬本;而為了防止記賬衝突,每次也只允許一個出塊節點記賬。以太坊提出狀態分片,實際上就是把一個賬本分成多個賬本,這樣一來,一些節點在1號賬本記賬,一些節點在2號賬本記賬……(相當於7-11從一個收銀台增加為多個收銀台),多個節點同時記賬,整個公鏈的性能就會得到質的提升。但如果我們把出塊節點與賬本/分片的關係固定,比如確定由a、b、c、d四個節點負責1號賬本,那壞人只需收買a、b、c、d中的一部分就能破壞賬本,公鏈在提升性能的同時,安全性同比例下降。因此,出塊節點需要被隨機、動態地分配到不同賬本,以此保證分片後的公鏈與未分片的公鏈具有相同的安全性。但動態分配會帶來新的問題:節點手中該拿哪一個賬本?它可能會被分配到64個賬本(以太坊計劃啟動64個分片)中的任何一個去記賬。以太坊給出的方案是出塊節點不拿任何一個賬本,或者說,讓出塊節點不需要賬本就能記賬。這會帶來兩大好處,一是不管節點被分配到哪個分片,它都可以立刻開始記賬(出塊)工作,幾乎不用花費時間來獲得以及同步該分片的賬本,節點也因此可以在不同分片間輕鬆跳轉;二是出塊節點不需要存儲賬本,也就不需要高硬體配置,任何人抵押32ETH就能成為一個驗證者,這非常有助於以太坊PoS的去中心化以及整個公鏈的安全。但新問題躍然紙上:如果出塊節點手中沒有賬本,它怎麼知道交易發送方的錢夠不夠?密碼學就在這時候登場了。
二
向量承諾:從查詢到證明
不需要賬本就能記賬聽上去不可思議,但其思路是簡單的:在以前,節點有賬本,一筆交易來後它翻看賬本,查詢交易是否合法;在以後,節點沒有賬本,交易發送方在提交交易的同時需要提交一個密碼學證明(為了區分,後文特指密碼學證明時都用proof表示),自己證明自己的這筆交易是合法的。
可出塊節點為什麼能夠通過一個proof來判斷某筆交易是否合法?這裡涉及到兩個密碼學的重要概念,第一個叫「成員證明」。它指的是通過某種方法,證明個體是群體的一部分。如果能夠證明某個賬戶狀態是整個賬本狀態的一部分,出塊節點當然就能相信這個賬戶狀態,並以此為根據進行交易合法性的判斷。第二個叫「向量承諾」,它可以將群體,不管這個群體有多龐大,壓縮成僅僅一個數,然後給出成員證明,該成員證明表明的是某個個體是屬於這個數背後所關聯的群體的,且能證明個體在群體中的位置,以及進行證明的更新。Merkle樹是可被用於向量承諾的方法之一,我們以它為例來看如何實現成員證明。下圖是一棵Merkle樹,最下一層的葉子節點存儲的是應用數據,其他非葉節點存儲的是其子節點的哈希值。如果知道綠色節點和所有黃色節點的值,就可以從下至上進行三次哈希運算,得到該Merkle樹根的值,也就是6c0a。
那麼,如果驗證方手中有樹根的值(6c0a),證明提供方把綠色節點的值和所有黃色節點的值作為一個proof給驗證方,驗證方是不是就能通過計算三次哈希的值是否等於6c0a來判斷綠色節點的值是否在這棵Merkle樹中?答案是可以。這就是對綠色節點屬於Merkle樹的成員證明,它是以向量承諾的方式完成的,而這也幾乎就是比特幣SPV節點(簡單支付驗證)的工作方式。
如下圖所示,SPV節點不存儲完整的區塊/賬本,但存儲了每個區塊中Merkle樹的樹根(此Merkle樹的葉子節點存儲的是該區塊所有交易),當它需要查詢一筆交易是否存在時,會找全節點要一個該交易的proof,該proof類似於上文中綠色節點和黃色節點值的一個打包(Merkle路徑),然後SPV節點會計算這些值的總的哈希值是否等於自己手中Merkle樹根的值,如果相等,則說明這筆交易是該Merkle樹的一個成員,即這筆交易是存在的。
SPV節點只存儲區塊頭(綠框),區塊頭中包含Merkle樹根(紅框)
SPV節點通過成員證明判斷交易是否存在,該證明系統包含三個部分:節點手中有一個簡短的摘要(樹根);證明提供方給出一個proof;節點計算此proof,看是否與自己手中的摘要相符合。到此,我們就完成了「不需要賬本就能查賬」,它是把查詢思路改為了證明思路;接下來我們要實現的是「不需要賬本就能記賬」。對於以太坊2.0分片上的出塊節點而言,它的證明系統同樣是由摘要、證明、驗證這三部分構成,但它要做到是使用交易發送方(而不是全節點)給出的proof來判斷一筆新交易是否合法(而不是舊交易是否存在),並以此判斷為基礎記賬。
三
無狀態:從證明賬本到證明行為
想像有一個很小的村莊,這個村莊每天只有3筆村民間的交易,村長拿著賬本負責記賬。A現在要給B轉5塊錢,傳統的思路很簡單:村長看A的賬戶上是否有5塊錢,如果有,就記下這筆新交易。現在換一個思路:假設A在今天早上要給B轉5塊錢,村長知道A的賬戶在昨天早上有10塊錢,那麼如果A能夠證明昨天的3筆交易都和他沒有關係,是不是就意味著他的賬戶在今天早上依然有10塊錢?這樣一來,村長是不是不用查賬本就能放心記下這筆新交易?答案是肯定的。如果A昨天有一筆交易怎麼辦?很簡單,A這時不是證明自己沒交易,而是證明自己昨天只有一筆交易,且那筆交易用掉了3塊錢;村長就知道他還有7塊錢,可以記下新交易。這個思路的轉變至關重要,你一定要去理解它,這是「無狀態」這件事的奧妙所在。不難發現,即使是不拿賬本的SPV節點,它在查詢交易時實際上也是要用到賬本,或者說狀態的,只不過它不是自己存儲狀態,而是去找全節點要這個狀態的證明;但在這個新思路下,狀態的作用可以徹底被「行為證明」取代,那麼這條鏈就能夠以無狀態的方式去設計。(註:行為證明這個詞並無出處,是作者為了易於理解這樣描述的)如何實現無狀態?如何藉助於行為證明完成記賬?依然是成員證明的方法。能夠利用Merkle樹來完成這種成員證明嗎?理論上可以,但對於「無狀態」這個應用場景來說,用它的開銷過大。
在
文章評論
冷萃財經原創,作者:Awing,轉載請註明出處:https://www.lccjd.top/2020/06/15/%e4%bb%a5%e5%a4%aa%e5%9d%8a%e9%a2%a0%e8%a6%86%e4%ba%86%e4%bb%a5%e5%a4%aa%e5%9d%8a%ef%bc%9a%e5%bc%95%e5%85%a5%e5%af%86%e7%a0%81%e5%ad%a6%e5%ae%9e%e7%8e%b02-0%e6%80%a7%e8%83%bd%e7%aa%81%e7%a0%b4/?variant=zh-tw
文章評論