1. 程式人生 > >區塊鏈開源實現hyperledger fabric架構詳解(轉載)

區塊鏈開源實現hyperledger fabric架構詳解(轉載)

hyperledger fabric是區塊鏈中聯盟鏈的優秀實現,主要程式碼由IBM、Intel、各大銀行等貢獻,目前v1.1版的kafka共識方式可達到1000/s次的吞吐量。本文中我們依次討論:區塊鏈的共通特性、fabric核心概念、fabric的交易執行流程。本文來源於筆者欲對公司部分業務上鍊而進行培訓的PPT,故圖多文字少,不要怕太長。

1、區塊鏈解決方案的特性

1.1 分散式帳本

區塊鏈核心概念是分散式帳本,就像下面的圖1所示,同樣的帳本(全量的交易資料,詳見下節)在任意一臺節點(不包括客戶端)上都有。所以,其優點是資料很難造假,造假後也可以通過追溯記錄來追究法律責任。而缺點就是極大的浪費,傳統服務每份資料都儘量少存幾份,即使存了三份拷貝都已經考慮到諸多異常,並使服務可用性達到N個9了。而區塊鏈這種特性,同時造成的另一個問題是帳本不能太大,至少不能超過區塊鏈網路中最小結點的儲存以及處理能力。所以,這制約了總交易資料(下文為方便概念介紹,統稱為帳本ledger)的條數,進而也影響了能寫入區塊鏈的單條交易資料的大小。

圖1 區塊鏈分散式帳本示意圖

什麼是區塊鏈呢?我很喜歡《區塊鏈技術進階與實戰》一書中對它的定義:區塊鏈是一種按照時間順序將資料區塊以順序相連的方式組合成的一種鏈式資料結構。如果覺得有點抽象,那麼我們再來看看下面的圖2。

圖2-區塊鏈資料結構示意

圖2中就是賬本,它由多個區塊構成了一個有時序的連結串列,而每個區塊裡含有多條交易trasaction(縮寫為tx)構成的連結串列。圖2下方有一個WorldState世界狀態,這其實是為了提升效能用的。比如,key1共交易了10000次,為了獲取它的當前狀態值,需要正向執行這10000次交易,這就得不償失了。如果這1萬次交易裡,每次新交易執行完,都同步更新一個數據庫(在fabric裡用的是levelDB),這樣查詢當前狀態時,只需要查詢該資料庫即可,如圖3所示。

圖3-fabric levelDB狀態資料庫

圖3中,區塊鏈帳本是在FileSystem檔案系統中儲存的,而Level DB存放世界狀態。

1.2 智慧合約smart contract

區塊鏈的發展過程中,一般1.0時代就是數字貨幣時代,代表是比特幣,而2.0時代就是智慧合約(現在是3.0時代,各種聯盟鏈即為代表)。

智慧合約是執行在區塊鏈上的模組化、可重用的自動執行指令碼,有了它我們就可以完成複雜的業務邏輯,例如同一個區塊鏈上有多份合約,而每份合約可以約定不同的參與者(企業或者相關方)。也可以指定每份合約裡每個子命令做一批特定的事,大家可以把它想象成關係資料庫裡的事務。如圖4所示,我們可以在合約裡指定允許哪些企業的節點可以參與到交易流程中來(在fabric裡這叫共識策略)。

圖4-智慧合約圖示

在fabric中,智慧合約叫做chaincode,它有6個狀態,如下所示:

  • Install → Instantiate → invocable → Upgrade → Deinstantiate → Uninstall.

實際上智慧合約就是一段程式碼,fabric官方認可的是GO語言。首先我們需要把合約程式碼上傳到區塊鏈上,這一步的狀態就叫Install。

接著,需要做初始化操作。比如,現在的資料是存放在mysql中的,那麼上線時需要用Instantiate把資料遷移至鏈上,這也算初始化。初始化後,chaincode就進入invocable可呼叫狀態了。

通用我們可以通過CLI命令列或者程式裡用SDK呼叫合約(v1.1前還有RestApi呼叫,現已放棄)。

聯盟鏈由於跨多家企業、多個地區甚至國家,很難使得合約保持一致的版本,因此,每個合約都有版本號。而版本升級時,就是Upgrade狀態。

最後兩個狀態對應著合約下鏈。

智慧合約可以在供應鏈等較複雜的業務場景下起到很大的作用,如下面的圖5所示:

圖5-智慧合約技術的應用示意

1.3 資料一致性(共識演算法)

既然區塊鏈是一個去中心化的分散式系統,那麼自然只能通過投票來決定一致性了:少數服從多數。當然,多少算多數呢?不同的共識演算法下,結果並不相同。比如paxos演算法(參見筆者的《paxos演算法如何容錯的–講述五虎將的實踐》)就是超過一半,而PBFT則需要三分之二以上。

這裡有一個拜占庭將軍問題需要注意,如何理解該問題可以參見這份翻譯過的The_Part-Time_Parliament(Paxos演算法中文翻譯)文件。簡言之,就是投票的拜占庭將軍(伺服器)們有2種不可靠的形式。第一是遲鈍(資料包延遲)、失憶(資料包丟失以及資料包重發)、失蹤(伺服器宕機)等不含背叛的行為,第二則是有將軍是間諜(伺服器被攻破)。如paxos這樣的演算法屬於第一種,Fault-tolerance,它不能容忍伺服器上有惡意程式碼;而如PBFT(Practical Byzantine Fault Tolerance)這樣的演算法是第二類,Byzantine-Fault-tolerance,它能夠容忍一定數量的拜占庭將軍節點存在,如PBFT、SBFT、RBFT演算法等。

第二類Byzantine-Fault-tolerance共識演算法雖然看上去很美,但並不成熟,特別是效能低下,比如PBFT是一個多項式複雜度的演算法O(N^2),節點過多時(大於100)效能急驟下降。第一類通常是O(N)複雜度,在某些場景下使用效果還不錯,比如fabric v1.1的kafka共識機制就是這樣的演算法,下文我們會詳述。

像比特幣、以太坊等採用的共識演算法又有所不同,例如比特幣的POW工作量證明演算法,它定義一小時內(通過調整運算難度實現,比如調整近似程度)有一個lucky node節點,該節點是通過證明自身的努力(hash值逆解)而幸運選出,選出後它就可以為這段時間的交易做決定(似乎挺像總統選舉^_^)。詳情參見我這篇文章:《區塊鏈技術學習筆記》

1.4 非對稱加密

區塊鏈通過非對稱加密技術實現身份驗證與資料加密。其實就是我們日常在用的SSL技術。

為了方便理解,我們需要先介紹PKI(Public Key Infrastructure),它是一種遵循標準的利用公鑰加密技術為電子商務的開展提供一套安全基礎平臺的技術和規範。有一個CA(Certificate Authority)權威機構負責向用戶(包括服務提供者與使用者)提供數字證書,包括公鑰與私鑰,同時CA機構還需要提供一個CRL(Certificate Revocation List)證書吊銷列表,如下面的圖6所示。

圖6-CA機構頒發數字證書以及提供CAL

這樣,區塊鏈可以通過PKI體系實現安全認證。PKI有三個關鍵點,我們下面詳述。

1.4.1 數字證書 Digital Certificate

比如Mary Morris符合X.509規範的數字證書裡,其Subject屬性裡就含有她的資訊,包括國家C=US、所屬的州或者省份ST=Michigan、所在城市L=Detroit、所屬單位O=Mitchesll Cars、其他資訊OU=Manufacturing、公用資訊CN=Mary Morris/UID=123456等,也含有其他資訊,如下面的圖7所示。

圖7-PKI數字證書

1.4.2 公鑰與私鑰

CA頒發了兩個證書:公鑰與私鑰,其中,私鑰僅服務提供者儲存,而公鑰則可被所有人(服務使用者)儲存。

所謂非對稱加密,就是公鑰加密的訊息僅私鑰可以解密;同理,私鑰加密的訊息,僅公鑰可以解密。對應於前者,可以實現客戶端訪問伺服器時加密訊息,例如訪問安全級別高的頁面時提交的表單資訊都需要用公鑰加密,確保只有伺服器才能解密網路報文。對應於後者,則可實現簽名功能,如下面的圖8所示。

圖8-PKI中私鑰簽名後用公鑰驗簽名

圖8中Mary Morris用私鑰對一段資訊的內容(若內容過大則可先HASH後獲得小點的字串)加密後,生成簽名附加在訊息中。接收者可從CA機構獲取到公鑰,用公鑰解密簽名後,再與內容比對,以確定訊息是否來自MaryMorris及內容是否被篡改。對於檔案來說也是一樣,小檔案直接加密,大檔案先生成hash再對hash加密,如下面的圖9所示。

圖9-對檔案的簽名

1.4.3 證書信任鏈

CA證書分為兩類:RCA(Root CA)根證書以及ICA(Intermediate CA)中間證書。這些證書由RCA開始構成一個證書信任鏈,如下面的圖10所示。

圖10-CA證書信任鏈條

有許多CA證書權威機構,各自有其RCA。如果RCA得不到信任,那麼其下的ICA也無法認證通過。

當然,自己的伺服器也可以生成RCA。

在Fabric裡,允許不同的企業使用不同的RCA,也可以使用相同的RCA和不同的ICA。這與下文中的MSP密切相關。

1.5 小結

我們來總結下區塊鏈,它主要是為了解決社會上的信任問題而存在的,為此,它付出了沉重的效能、可用性代價。它怎麼做到的呢?通過4點實現:1、資料到處存放;2、操作記錄不可更改;3、傳輸資料可信;4、業務指令碼約束。

那麼,這個信任問題的解決,帶來了2個非功能性的約束:資料一致性和可用性。其中可用性包括兩點:1、交易在可接受的時間內達成。比如比特幣的分叉就會造成嚴重問題。2、吞吐量達標。而比特幣每秒只能有7次交易,這顯然太低了。

2、fabric核心概念

hyperledger fabric符合上面說過的區塊鏈的所有特性。我們必須先了解它的一些概念,才能進一步理解其架構設計。由於英文資料居多,所以這些概念我都以英文描述為準:

  • chaincode:智慧合約,上文已提到。每個chaincode可提供多個不同的呼叫命令。
  • transaction:交易,每條指令都是一次交易。
  • world state:對同一個key的多次交易形成的最終value,就是世界狀態。
  • endorse:背書。金融上的意義為:指持票人為將票據權利轉讓給他人或者將一定的票據權利授予他人行使,而在票據背面或者粘單上記載有關事項並簽章的行為。通常我們引申為對某個事情負責。在我們的共識機制的投票環節裡,背書意味著參與投票。
  • endorsement policy:背書策略。由智慧合約chaincode選擇哪些peer節點參與到背書環節來。
  • peer:存放區塊鏈資料的結點,同時還有endorse和commit功能。
  • channel:私有的子網路,事實上是為了隔離不同的應用,一個channel可含有一批chaincode。
  • PKI:Public Key Infrastructure,一種遵循標準的利用公鑰加密技術為電子商務的開展提供一套安全基礎平臺的技術和規範。
  • MSP:Membership Service Provider,聯盟鏈成員的證書管理,它定義了哪些RCA以及ICA在鏈裡是可信任的,包括定義了channel上的合作者。
  • org:orginazation,管理一系列合作企業的組織。

2.1 開發概念

fabric聯盟鏈的開發人員主要分為三類:底層是系統運維,負責系統的部署與維護;其次是組織管理人員,負責證書、MSP許可權管理、共識機制等;最後是業務開發人員,他們負責編寫chaincode、建立維護channel、執行transaction交易等,如下面的圖11所示。

圖11-fabric技術人員的分層

fabric大致分為底層的網路層、許可權管理模組、區塊鏈應用模組,通過SDK和CLI對應用開發者提供服務,如下面的圖12所示。

圖12-fabric開發模組圖

我們的開發流程主要包括寫智慧合約,以及通過SDK呼叫智慧合約,及訂閱各類事件,如圖13所示。

圖13-開發環節

2.2 MSP

每個管理協作企業的ORG組織都可以擁有自己的MSP。如下圖14所示,組織ORG1擁有的MSP叫ORG1.MSP,而組織ORG2業務複雜,所以維護了3個MSP。

圖14-ORG可管理自己的MSP

MSP出現在兩個地方:在channel上有一個全域性的MSP,而每個peer、orderer、client等角色上都維護有本地的區域性MSP,如圖15所示。

圖15-在channel上的Global MSP以及在參與角色上的Local MSP

本地MSP只儲存有Global MSP上的子集,內容儲存在本地檔案系統上,而全域性MSP可在邏輯上認為是配置在系統上的,它實際也在每個參與者上儲存一份拷貝,但會維持一致性。

MSP也分級,如圖16中所示,底層的network MSP負責網路層的准入,其MSP由ORG1擁有,而上面的某個channel的MSP則由ORG1和ORG2共同管理。

圖16-MSP是分級的

一個MSP下含有以下結構,如圖17所示。

圖17-MSP結構

可見,MSP結構包括:

  • RCA根證書
  • ICA中間證書
  • OU組織單位
  • 管理員證書
  • RCL吊銷證書列表
  • 結點上的具體證書
  • 儲存私鑰的keystore
  • TLS的根證書與中間證書

3、fabric交易提交流程

3.1 peer結點的部署

peer結點上儲存有賬本ledger以及智慧合約,如下圖所示:

channel是一個邏輯概念,可以通過MSP隔離全網不同組織的參與者,如下圖所示:

當有多方參與者時,例如4個org組織、8個peer結點時,其中channel連線了P1、P3、P5、P7、P8這五個節點,其他3個節點加入了其他channel,其部署圖如下所示:

加入MSP來管理身份時,如P1和P2由ORG1.MSP管理,而P3和P4的證書則由ORG2.MSP管理,他們共同使用一個channel,則如下圖所示:

3.2 交易的執行流程

去中心化的設計,必然需要通過投票(多數大於少數)來維持資料一致性,而任何投票都必須經歷以下三個過程:

  1. 有一方先提出議案proposal,該議案有對應的一批投票者需要對該結果背書,這些投票者依據各自的習慣投票,並將結果反饋;
  2. 統計投票結果,若獲得多數同意,才能進行下一步;
  3. 將獲得多數同意的議案記錄下來,且公之於眾。

而這三步fabric當然也少不了,當然它的稱法就有所不同,其對應的三步如下:

  1. 由client上的CLI或者SDK進行proposal議案的提出。client會依據智慧合約chaincode根據背書策略endorse policy決定把proposal發往哪些背書的peer節點,而peer節點進行投票,client彙總各背書節點的結果;
  2. client將獲得多數同意的議案連同各peer的背書(包括其投票結果以及背書籤名)交給orderring service,而orderer會彙總各client遞交過來的trasaction交易,排序、打包。
  3. orderer將交易打包成區塊block,然後通知所有commit peer,各peer各自驗證結果,最後將區塊block記錄到自己的ledger賬本中。

我們看一個具體的例子,若channel上有三個peer背書者,client提交流程如下圖所示:

詳細解釋下上圖的流程:

  1. 首先,client發起一個transaction交易,含有<clientID, chaincodeID, txPayLoad, timestamp, clientSig>等資訊,指明瞭3W要素:訊息是誰who在什麼時間when傳送了什麼what。該訊息根據chaincode中的背書策略,發向EP1、EP2、EP3這三個peer節點。
  2. 這三個peer節點模擬執行智慧合約,並將結果及其各自的CA證書籤名發還client。client收集到足夠數量的結果後再進行下一步。
  3. client將含背書結果的tx交易發向ordering service。
  4. ordering service將打包好的block交給committing peer CP1以及EP1、EP2、EP3這三個背書者,背書者此時會校驗結果並寫入世界狀態以及賬本中。同時,client由於訂閱了訊息,也會收到通知。如果我們從程式設計的角度來看,則流程會更清楚:

參見上圖,A是我們的應用程式,其步驟如下:

  1. A首先連線到peer。
  2. A呼叫chaincode發起proposal;與此同時,P1收到後先模擬執行,再產生結果返回給A。
  3. A收到各peer返回的結果。
  4. A向O1發起交易;與此同時,O1產生區塊後會通知peer,而peer會更新其賬本。
  5. 最後通過訂閱事件A收到了結果。

最後再細看下這三個階段。

3.2.1 proposal提案階段

可以看到,A1發出的<T1, P>,收到了<T1, R1, E1>和<T1, R2, E2>兩個結果。

3.2.2 package打包階段

O1在一個channel上會收到許多T交易,它會將T排序,在達到block的最大大小(一般應配1M以下,否則效能下降嚴重,kafka擅長處理小點的訊息)或者達到超時時間後,打成區塊P2。

3.2.3 驗證階段

O1將含有多條交易T打成區塊的B2發往各peer節點,而P1和P2將B2加入各自的L賬本中。

4、小結

本文偏重於概念的解釋,由於篇幅所限,未涉及fabric的系統搭建(請參考筆者的這篇文章《區塊鏈開源實現fabric快速部署及CLI體驗》),也未描述共識演算法在異常情況下如何維持一致性,這留待下一篇文章解決。fabric的許多思想是值得我們進一步研究的,其優秀的實現可以幫助我們通過fabric獲得區塊鏈在信任創新上的思路。

(轉載本站文章請註明作者和出處 陶輝筆記 ,請勿用於任何商業用途)