乾貨 | 清華公開課 OK公鏈如何解決區塊鏈規模化應用難題?

買賣虛擬貨幣

本文轉載自公眾號“OK區塊鏈”

區塊鏈技術的發展歷程

區塊鏈1.0時代是以比特幣為代表,2008年這個概念被首次提出,2009年正式啟動了比特幣的網路。這個網路有別於普通意義上網際網路,因為它在網際網路上面實現了價值的轉移。

之前網際網路經歷幾十年發展,主要解決的問題是資訊的互聯互通,我們在使用網際網路服務的同時,後面是一個個的服務商和中心化的節點。

在區塊鏈網路裡,它有這樣幾個特點:一是去中心化、二是不可篡改、三是可信任。它用到了電腦科學、密碼學、網路和經濟學的博弈論等等,同時加了一些創新性的設計。

區塊鏈的2.0是以以太坊為代表,主要特點是加入智慧合約(智慧合約是1995年提出的概念)。

受限於當時的環境,計算機依賴於可信的第三方,加上資料的不可篡改,操作涉及到多方會有一些限制。區塊鏈的誕生,帶來了天然的執行基礎平臺,區塊鏈技術與以太坊進行結合,同時擴大了場景。溯源、經濟領域、遊戲等很多應用,都可以在以太坊為代表的區塊鏈2.0上去做。

了區塊鏈3.0時代,是區塊鏈的大規模應用。儘管區塊鏈技術發展了近十年,但真正走到我們身邊的應用很少,可以說幾乎是寥寥無幾。

目前很多的應用,是基於聯盟鏈的企業級應用,像天貓跨境物流的跟蹤、跨境的支付,還有像我們前面公佈的疫苗溯源方案。

掣肘規模化應用的根源

為什麼發展了那麼久,炒的也很熱,但區塊鏈在應用上還沒有深入到使用者的身邊去?我們認為主要是它的可擴充套件性受到很大的限制,這也是目前絕大多數公鏈所努力攻破的一個點。

區塊鏈的可擴充套件性到底有哪些問題呢?比如去年年底風靡全球的一個遊戲“加密貓”,直接導致了以太坊的嚴重堵塞。原因就是以太坊從設計上,不能支撐大規模的交易,導致了它在打包、入塊的流程上受到了阻礙。

而傳統中心化的交易平臺,比如Visa和支付寶,Visa的處理能力是2.4萬的TPS,支付寶“雙十一”峰值32.5萬TPS的峰值,和比特幣和以太坊最大理論的峰值(比特幣是7,以太坊是15)相比有天壤之別。

什麼原因讓它的效能這麼低下呢?區塊鏈裡有“三元悖論”,這是以太坊提出的概念,意思是說區塊鏈領域不可能在同一時間、同一層面從去中心化、安全性和可擴充套件性三個方面做到提升。

2008年比特幣設計的時候,主要解決是資產的價值轉移,而在資產裡面很重要的一個特點就是要安全性。比如說要理財、投資,肯定考慮資金的安全性,這是首要的。

在安全上的基礎上,我們才能考慮的是它的收益,如果你的本金都沒了,其實你投資的價值也就很少。

像比特幣和以太坊,為了提升去中心化和安全性,設計的時候每一個節點、每一筆交易都需要全網去廣播,全網節點去做驗證,每一個塊也是需要全網去同時爭取這樣一個記賬的過程。

當然,從這兩個點上就失去了它的可擴充套件性,全網的效能制約點就相當於取決於每個節點單點性。加入的節點越多,效能不僅沒有得到提升,訊息的擴大、通訊的複雜度反而更高,讓它的可擴充套件性受到了極大的限制。

比如EOS比較“聰明”,犧牲了去中心化,用了21個超級節點的概念,但前提認為這21個超級節點是可信的。共識基於21個超級節點之間去達成,雖然提供可擴充套件性,效能也得到比較大的提升,但是犧牲了去中心化區塊鏈本質的特點。

另外有一些區塊鏈公鏈,為了提升去中心化和可擴充套件,只用了一些分散的儲存計算,從全網裡面選出一小部分節點來做共識,選出一小部分節點,不同的節點之間儲存的賬本不一樣,這就讓去中心化和擴充套件性有一定的提升。但是這樣的話就會讓它的安全性降低,攻擊的難度也降低。

四大擴容方案

目前在區塊鏈的擴容方案裡,可擴充套件性有四種方法:DAG、二層擴容、共識創新和分片技術。

DAG(有向無環圖):

DAG也叫有向無環圖,是計算機領域裡一個比較重要的資料結構。意思是從一個節點出發,沿著箭頭的方向,不管從哪個路徑走都不會回到這個節點本身。

我們看到在傳統區塊鏈,比如比特幣和以太坊裡面,儲存方面是一條主鏈的結構,按照時間順序由一個個的區塊組成,當一個區塊入塊了,剩下所有的節點去競選下一個區塊的記賬權,從而來獲取記賬的分紅。

我們可以認為,這是一個同步的過程,一是全網同步的去出同一個區塊,另外對每一筆交易全網都要去做驗證,並且每個節點儲存區塊鏈的資訊,帶來的好處就是保證了嚴格的一致性。

而DAG裡面它改變了這樣一個儲存結構,它認為區塊鏈裡面比特幣、以太坊等,每一個塊包含了多筆交易,並且基於時間順序來做的。

在DAG這個網路裡面,每一個這樣的節點只是一筆交易,不是一個塊的概念。後面的一筆交易透過一定的策略,會連到前面的多筆交易上面去,並且會對前面這樣一個交易做一個驗證。

這樣做的好處,就是它把這樣一個原來同步的儲存改成了非同步,理論上來說是支援無限的擴充套件。TPS也可以無限的大,但是它有一個問題,就是如果有一個節點,後面沒有人連結到他,相當於沒有人驗證他這一筆交易的有效性,就永遠得不到確認。

另外由於沒有使用強一致性,尤其是智慧合約執行的時候,它執行一段時間有可能會導致出現“雙花”、不一致的現象,安全性並沒有得到廣泛的驗證。在這種儲存結構裡,由於比特幣和以太坊都是這種儲存結構,執行了十年,也沒出現問題,它的安全性經過了實際工程的檢驗。

另外在DAG裡,每一筆交易之間的溯源,因為它的圖複雜度極高,和區塊鏈裡單鏈的結構來比,它的複雜度極高。

二層擴容:

其中的邏輯是把鏈分成兩種,原來的鏈還是比特幣、以太坊的主鏈,但另外又生成了側鏈,將複雜的交易和頻繁的交易放到鏈下,最終的確認放到主鏈上去做,這樣做的好處就是減少了主鏈的壓力。

但最後總體的效能瓶頸很明顯還是主鏈,最高像以太坊來說也就是15,對效能的提升很有限。

Algorand是圖靈獎得主Micali提出公鏈的設計方案,他認為這個方案突破了“不可能三角”,共識演算法採用了VRF+POS+BA*的演算法。

它的設計的思路是,比特幣和以太坊裡每一筆交易要全網廣播、全網做驗證,這裡只是隨機選出來一小部分節點,讓一小部分節點去做出塊的提名人、驗證人和出塊節點。

共識的範圍降到了幾個節點之間,用一些演算法保證節點選取的隨機性,得到了一定的安全保證,所以說加快了交易的吞吐量。但是這個方案目前並不完善,可擴充套件性也是有限的,它的理論值是2000,但最終的理論值是200,實測會到1000左右。

Dfinity是另外一個從共識方法上去改進區塊鏈可擴充套件性的一條公鏈,一度被認為是區塊鏈的3.0。它的思路和Algorand有點相似,也是將整個網路選舉出一小塊的局域的幾個節點,在這個節點之間再選出共識的委員會,在這個委員會用了BLS多籤的方法出塊。

一定程度上來說,兩個方面,一是共識組由全網變成區域性的網路,第二是在共識的方法上做了創新,用了BLS多籤的方案,也是提升了交易量。

分片技術(Sharding):

和前面兩個共識相比,隨機選取一小個節點來說,就更近了一步。在比特幣、以太坊裡效能取決於單點的效能,加入的節點越多,網路沒有更好,反而更壞。

是不是存在這樣一種方案讓它可以並行?比如說把它切分到一塊,這就有了分片技術。分片是資料庫裡面的概念,提供資料庫橫向擴充套件的方法,透過將資料庫切分到不同的資料庫上,來提升伺服器對資料庫訪問IO的可擴充套件性。

把分片用在區塊鏈裡面,透過一定的機制和方法,將整個區塊鏈網路分成若干的共識組,每個共識組交易量之和,就是整個這條鏈的整體吞吐量。

這個地方設計了幾個重點,第一是如何進行共識組的選舉?選出來的共識組,如果裡面有大量的拜占庭節點(可以理解為壞的節點),相當於在這個節點組裡安全性受到極大的挑戰。

另外,就是分片的大小是不是合理。如果分片太小了,幾個拜占庭節點有可能影響分片的安全性。如果分片太大,影響片內的交易太多,也會影響一定的吞吐量。當然,分片太小還有一個問題,就是跨片的交易會多,跨片的交易還不如原來的一個網路。

分片技術目前分為三個:網路分片、交易分片和狀態分片。

交易分片是在網路分片的基礎上去實現,透過將整體網路分成若干分片,每個分片並行進行交易,但是全網所儲存的還是一個賬本。

每個節點的儲存壓力依然是存在,狀態分片的好處就是每個分片只儲存本分片的部分賬本,這樣的話從交易和儲存兩方面去提升它的擴充套件性。隨著分片的越多,整體網路效能也就越大。這也是OK公鏈選擇的方式,也是我們選擇分片的原因之一。

這是我們的設計目標,我們在“不可能三角”這個理論下做的一些工作。保證一定的去中心化和一定安全的前提下,去提升公鏈的可擴充套件性。其實在比特幣和以太坊裡面,也嘗試過有很多其他的方法,比如說是增加區塊的大小,一個區塊是不是能打包更多的交易,第二個是縮短區塊的出塊時間,時間縮短。但是這些方案一是有一定問題,二是對效能的提升也極其有限。

五大角度解讀OK公鏈技術選型

關於OK公鏈的技術選型,我們選擇了這樣的分片技術,理由有二:

其一,它能夠從儲存和交易兩個方面去提升區塊鏈的可擴充套件性;

其二,它的理論模型並不複雜,在可推導的理論模型裡面,我們能證明它是能滿足一定的去中心化和安全性,並且還能夠對可擴充套件性做一定的提升。

它的難點我們在前文已經介紹了,而且其在工程上也是非常複雜,目前在整個業界裡還沒有一個公開出來的分片技術。

我們可以從網路分片、交易分片、狀態分片、片內共識、分片伸縮等五個方面來具體解釋和了解。

第一,網路分片;

在P2P網路裡我們分成了若干的共識組,在每個共識組裡再去執行一定的共識機制。這些共識組內有一個Leader節點。

我們再把這些共識組分成兩類:一是委員會、二是普通分片,也可以稱之為交易分片。

委員會扮演兩個作用:一是對整個網路進行管理;二是管理自身委員會內部的成員。而所有委員會的內部成員,可以分為三種:委員會的成員、分片的礦工、普通礦工。

邏輯上比較複雜的是,究竟如何選舉委員會、如何進行分片,來保證整個公鏈的安全性,同時實現片內的交易更多,跨片的交易更少?

這裡共分為4大階段,首先是準備階段。

我們定義為一個epoch(在下面有兩個管理區塊,兩次委員會的輪替之間的間隔)一個epoch結束時,各分片統計本分片內符合條件的賬戶作為侯選礦工,上報給委員會。

這是為了防止女巫攻擊,我們使用了PoS股權證明的方法,每一個參與挖礦的礦工,必須交一定的保證金,這樣想註冊大量礦工節點去執行拜占庭攻擊的時候,成本會有一定的提升,這也是我們對安全性的第一步保證。

其次分別是開始和POW階段,委員會收集到礦工的集合,然後廣播競選的訊息,各個礦工開始計算自己的PoW,並將計算結果提交給委員會,此處計算PoW不是為了挖礦,只是為了算隨機值,作為分片和選舉的依據。

最後是確定階段,委員會蒐集到PoW的訊息,按照雜湊值的排序選出新的委員會節點和分片節點(雜湊值最小的節點是委員會的節點),並且將競選結果寫入管理區塊,這個管理區塊是在委員會里面進行共識,全網廣播,同時宣佈新一輪的epoch開始。

這裡我們需要著重強調的有幾個地方。第一,我們用了PoS來抵制女巫攻擊;第二,PoW不是進行挖礦,只是計算隨機值,對資源的消耗也比較少一些。

第二,交易分片;

進行網路分片只是第一步 ,只有實現了交易分片,才能使各個分片能並行處理,減少冗餘計算和增加整個系統的吞吐性。

在交易分片裡面會涉及到兩方,一個是傳送方,一個是接收方。我們採用的方法就是以傳送方的地址進行分片,這樣的好處就是傳送方進行雙發訊息的時候,交易在同一個區塊裡進行打包共識,很容易被發現,一定程度上是讓雙花攻擊的難度變大。

同時,我們允許一個使用者用一對公鑰在每一個分片裡面建立賬戶(可以簡單理解為一個使用者用一個公鑰可以在每一個分片裡面建賬戶,文章後面我們會介紹它的好處)。

第三,狀態分片;

狀態分片裡面的設計思路,是讓片內的交易逐步增多,讓跨片的交易逐步減少,而並不是排斥這種跨片的交易。一個跨片交易所執行的步驟,就是分片a和分片b,分片a裡的使用者a和分片b裡的使用者b進行交易,有兩個步驟減少a的餘額和增加b的餘額。

現在,我們提出了一個支票的概念,就是分片a裡出塊以後,透過一個“支票”發給分片b處理,分片a在出塊以後透過一個區塊,會發出支票的訊息。

在這個裡面有三個分片,分片a、分片b和分片c,其中有三個是跨分片交易。為了減少通訊複雜度,在區塊裡面,每個分片相關的交易會打包成一個支票區塊。

將多筆支票打包成一個支票的區塊,發給分片a和分片b,分片b裡面兩筆支票打包成一個支票區塊,發給分片b,c裡面有一筆,這樣的話整個系統在跨分片交易的時候,通訊複雜度是O(n)方,在跨分片交易足夠少,因為分片也不會特別大,這是一個很容易實現的方案。

另外,我們在儲存上面使用了雙鏈的結構,每個分片記憶體儲兩條鏈,一個是狀態區塊,一個是交易區塊,交易區塊是隻儲存本分片的交易,而狀態區塊它是由交易區塊和支票區塊派生而來的。

那一筆跨分片的交易是如何進行的?我們將其分成了兩個階段:

第一個階段,假設a和b之間轉賬,這裡有一個分片派生出來三個“支票”區塊,分別是C12和C13、C21和C23,C31和C32,六個跨分片的支票區塊和三個交易區塊;

第二個階段,透過廣播將支票區塊傳送到對應的分片裡去,對應的分片接收支票區塊,透過交易區塊和支票區塊生成最終的狀態區塊。

另外,分片裡面智慧合約和以太坊裡面的智慧合約有不一樣的地方,就是它有跨分片的智慧合約呼叫。

如何理解跨分片的智慧合約呼叫?首先,呼叫分片2裡面的交易區塊,鎖定賬戶餘額,傳送呼叫資訊到分片b,分片b呼叫相應的合約,修改合約的狀態,收取交易的gas費用,將剩餘的gas費用返回給分片1,涉及到三次更新和兩次的跨分片交易。

為了減少跨分片呼叫,我們在設計的時候,只支援分片內的呼叫,而不支援跨分片的呼叫。原因是相互關聯、相互呼叫的合約不會部署在同一個分片上,這對於開發者來說是比較合理,也是容易做到的。

另外使用者可以在任意分片裡建立自己的賬戶。比如說分片1裡的使用者,要想呼叫分片2裡合約的話,可以在分片2裡面去建賬戶,把跨分片變成了一個片內智慧合約的呼叫交易。這從一定程度上我們希望把相關的業務都放在一個分片裡,這樣相關性越高,片內交易也就越高,併發性也就越好。相當於我們支援了一個片內的合約呼叫:使用者到合約、合約到合約、合約到使用者。

還有一個方法是在分片2裡建一個使用者,我們可以用跨分片的交易來做到。首先分片1裡面的使用者,呼叫分片2裡的合約,給分片2裡面的使用者做一筆轉賬交易,然後分片2裡面的使用者再呼叫這個合約,這就是跨分片之間智慧合約的呼叫的流程。

第四,片內共識;

分片技術有一個值得注意的點,每個分片裡節點數是固定的,比較方便用其他的共識演算法。缺點是它存在51%的算力的攻擊,因為它是一個開放的網路,誰都可以動態接入、動態退出,而分片裡面每一個分片的使用者數是一定的,比較方便用其他的共識演算法,比如PBFT演算法的好處,第一它能抵三分之一的拜占庭節點,它的網路依然能保證安全執行。

我們進一步改進了PBFT。首先,Leader打包一個區塊(我們前面介紹的分片裡面都有一個Leader的角色,PBFT共識裡面需要有一個Leader,他是負責發起共識的一個發起方。),廣播給其他節點,每個節點去驗證這個區塊,驗證透過的其他節點再廣播這個區塊摘要。

如果一個節點收到2f+1(f是容忍的拜占庭節點的個數)個其它節點發來的摘要都和自己相等,就向全網廣播一條Commit訊息,即可提交新區塊及其交易到本地的區塊鏈的狀態資料庫。在這裡,我們可以告訴他們通訊的複雜度,假設節點數是n的話,這個複雜度就是O(n²)方。

另外,我們用了BLS的簽名,有兩個特點。一是聚合、一是短簽名,可以將多筆交易聚合成一個簽名,這樣把訊息通訊的複雜度和儲存簽名的大小做到了降低,而且不需要進一步通訊就能生成一個多重簽名,減少通訊的次數。

我們改進了PBFT的演算法,這裡的邏輯首先同樣是Leader打包區塊,廣播給其他的節點,每個節點來驗證這個區塊,驗證透過區塊簽名傳送給Leader。

leader收集到2f+1個簽名之後,可以聚合成一個多重簽名sig1,leader將sig1和sig1參與方bitmap1廣播給其他節點,其他節點對sig1和bitmap1的合法性進行驗證。

為了確保全網賬本一致,還需對block+sig1+bitmap1進行一輪多籤;leader收集到2f+1個簽名之後,可以聚合成一個多重簽名sig2。leader將sig1,sig2和對應的bitmap2傳送給其他節點,其他節點驗證透過後將block+sig1+bitmap1寫入賬本,透過改進PBFT的演算法,將訊息的複雜度從O(n²)方變成了O(n)。

還有一個就是Leader的輪替,如果Leader是拜占庭節點的話,會阻礙區塊的產生,常用方案第一個是Round-Robin順序選取的方法,一個是VRF生成隨機生成區塊。

第五,分片伸縮;

在分片裡比較難的就是分片伸縮,這裡有兩個操作:一是新增分片,一是凍結分片。

新增分片的時候,各個分片會出現負載過重的情況,網路中有足夠多的礦工可以安全性的去維護這個分片,達到一個新分片所安全執行的理論值,這個時候我們透過線上的委員會的監控和線下社羣的投票,由委員會修改引數,來增加這分片。

凍結分片是在狀態分片裡比較難做的,相當於在每個狀態分片裡,每個分片儲存的區域性賬本,如果一個分片砍掉的話,這個分片裡的賬本有可能失效。

在這種情況下,每個分片的節點少,不滿足安全性的時候,也是透過委員會和社羣共識之後,該分片遷移到其他分片。這個分片裡面的賬本由委員會來維護。下一次新建的時候再有委員會交給分片,這從一定程度上保證了全域性賬本的一致性。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;