fabric2.0 概念, peer、账本和排序服务
1.Peers
Peers是網絡的基本元素,持有賬本和智能合約(鏈碼),代表信息及其對應的處理方式。
如圖所示,P1、P2、P3每個Peer都保存一份賬本的副本和智能合約的副本,這樣提供了一種冗余機制,避免了單點失效,事實上,每個Peer可以持有多個賬本和鏈碼。而應用和管理員等想要訪問某些資源,必須通過peer來實現,所以其是非常基本且重要的。
一個鏈碼可以有1個或者1個以上的賬本,每個賬本可以有對應的0個或0個以上個鏈碼,圖中賬本L1對應鏈碼S1,L2對應S1與S2,雖然一個賬本沒有對應的鏈碼是完全可以的,但是這種情況極為罕見,大多數情況下都應該至少有一個鏈碼。
應用和peer的查詢交互操作包括三個簡單的步驟,而更新交互包含額外的兩步。
應用在需要訪問賬本和鏈碼時使用Fabric SDKAPI來調用鏈碼、生成交易,驗證、提交交易到賬本中,最終在整個過程完成后交易會收到消息提示。
應用A連接到peer P1
應用A向P1發起提議
2.1. peer使用提議的參數調用鏈碼S1,來查詢或者更新賬本L1
2.2. 鏈碼S1生成查詢或者更新提議的回復
返回提議回復到應用A,如果是一個查詢操作,到這里就已經結束了
應用A從所有回復中構建交易到order O1節點
4.1. O1節點收集網絡中的各種交易,將其打包到區塊里面,然后發送區塊到所有peer節點,包括P1
4.2. P1首先對塊內交易進行驗證,然后用其來更新賬本L1
在L1被更新之后,P1生成事件,返回應用A,告知其整個過程已經完成
對于查詢操作,一般只需要一個Peer節點就可以完成了,應用也可以通過連接多個Peer節點來獲得更加實時的信息等。而更新操作會包含額外的步驟,在第3步中回復的并不是更新成功的通知,而是表示該節點同意節點的更新,具體更新還需要等待其他節點通過共識過程同意更新之后再執行,即4、5步的內容。
每個channel可以包含多個peer,每個peer也可以加入多個channel,可以將channel類比為通訊工具中的群組,channel中除了peer以外,還有order與application,P1與P2可以使用通道C直接進行交流。channel是由若干物理上存在的peer所形成的邏輯結構,peer為通道的訪問、管理等提供訪問點。
區塊鏈網絡由多個組織所形成與管理,peer是這些組織的連接點,被各個組織所擁有,每個組織可以有多個peer節點。而網絡的形成也是由各組織提供資源才能形成,會隨著組織提供資源的多少而進行規模的伸縮,只要有組織存在,網絡就會存在,不管中間是否有新的網絡加入或者之前的網絡離開,因此也能看出網絡的去中心化的特性。網絡中必須要有peer,但是不一定要有application,application由組織具體的業務邏輯等確認。對于查詢操作,application通常只連接組織自己的peer就足夠了,但是對于更新操作,就需要連接多個peer來滿足背書策略。
網絡中的每一個peer都有其所屬組織的管理員頒發的證書。當一個peer鏈接到通道時,會通過channel MSP來由其電子證書確定其所屬組織。在物理上,peer可以位于云端、位于本地機器上等,但是其所屬組織情況是由其身份(Identify)決定的,而不是由其物理所在決定的。
應用對賬本的更新過程共分為三個階段。
- application從背書策略要求的peer上收集賬本更新提議的背書,但此時peer并未完成真正的賬本更新。
- 將背書收集在一起作為一個交易打包成區塊,收集過程由application完成,而打包由order完成。
- 將區塊發放給各個peer,將其驗證之后,對賬本進行實際更新操作。驗證失敗的交易會被扣留下來用于審計等工作,不會用于更新賬本。
整個工作流過程被稱為共識,共識過程之后,所有的peer都在交易的順序和內容上達成了一致,共識是個多步的過程,應用只有在這個過程全部結束之后才會受到完成提示,在不同的peer上這個時間可能各不相同。
2.ledger
賬本存的是業務邏輯相關的重要事實,包括當前值以及引起當前值的交易歷史,可以類比為存折銀行賬戶余額以及其交易流水,它本身不存錢,但是卻代表了存折持有者的財富,賬戶余額是可變的,但是交易流水是不可變的,而區塊鏈則保證了這種不可變性。
賬本有兩個相關的組件組成—世界狀態和區塊鏈。世界狀態是一個持有當前值的數據庫,方便數據的獲取,狀態默認是一個鍵值對,可以容易的CURD。區塊鏈則是一個交易日志,記錄了到當前的世界狀態的所有改變,交易存儲在塊內,數據結構與世界狀態大不相同,因為要保證可變性。
可以邏輯上認為網絡中有一份賬本,而事實上有很多賬本的副本,這些副本會通過共識保持一致,這也是分布式賬本技術(DLT)的應用。
2.1.世界狀態
應用程序可以使用簡單的賬本API來增刪讀狀態,狀態值可以是簡單的字符串(Audi)或者一種復合結構({type:BMW…})。
世界狀態以數據庫的方式來實現,這樣使得存儲與讀取都更加有效率,Fabric也可以通過配置來使用不同的數據庫來更加適配應用,目前包括LevelDB和CouchDB,前者適合與存儲簡單的鍵值對,后者則適合JSON結構的文檔,會支持更復雜的查詢與更新。
應用幾乎不能調用智能合約,當交易被包含在區塊鏈中之后才會收到通知,所以應用不能直接更新世界狀態,世界狀態是由被足夠背書節點簽署后的交易更新的。這樣將應用和世界狀態進行了隔離。
除了數據本身,世界狀態還有版本號,每次更新世界狀態都會使得版本號增加,每次更新狀態時都會檢查版本號來確保防止并發更新的情況出現,確保按序更新。
賬本剛創建的時候世界狀態是空的,隨著后面的交易增加才會增加世界狀態,而且任何時候,世界狀態都可以根據區塊鏈重建,當peer創建時,也是通過這種方式來同步世界狀態的,而且當peer出現異常失效時,也可以通過這種方式來重建世界狀態。
2.2.區塊鏈
區塊鏈存儲了賬本狀態的之前版本與變成當前狀態的方式。區塊鏈是由一系列相連的區塊構成的,每個區塊包含一系列交易,每個交易都代表一條對世界狀態的查詢或者更新。區塊順序或者交易順序都由排序服務(ordering service)實現。
每個區塊頭都包含整個區塊的交易和上一個區塊頭的哈希,通過密碼學方式讓所有交易鏈接起來,形成區塊鏈,給賬本帶來安全性,因為修改交易就必須處理之前的交易。第一塊是創世塊,作為賬本起點,里面沒有任何用戶交易,而是包含初始網絡通道狀態的配置交易(channel configuration)。
區塊鏈通常以文件的方式實現,因為區塊鏈的操作基本上就是添加,而很少查詢,所以用文件方式實現很好。
2.2.1.區塊
區塊由三個部分組成
區塊頭
- 區塊號:從0(創世塊)開始,每增加一個區塊,其區塊號就加一。
- 當前塊哈希:當前區塊所有交易的哈希。
- 前一個區塊頭哈希:前一個區塊頭的哈希,用于形成一條鏈。
塊數據
按順序排列的所有交易,在排序服務創建時寫入區塊。
塊元數據
包含區塊創建者的證書和簽名,用于網絡各節點對其進行驗證。隨后,塊提交者將每個事務的有效/無效指示器添加到位圖中,該位圖以及累積狀態更新的哈希值也駐留在塊元數據中,以便檢測狀態分叉。
這部分不會用于計算塊哈希。
2.2.2.交易
交易存在于區塊的塊數據節中。
一個交易主要由五部分組成,其他的一些對于理解賬本的數據結構就并不那么重要了。
交易頭(H4)
交易頭存儲交易必須的元數據,比如相關的鏈碼名稱以及他的版本。
簽名(S4)
包含一個客戶端應用程序創建的簽名,該簽名由客戶端私鑰創建,用于檢查交易細節沒有被篡改。
提議(P4)
這部分將應用程序提供的用于賬本更新的參數輸入進行編碼存儲,這部分也將用于賬本更新時的參數輸入。
回應(R4)
該部分獲取了世界狀態更新前后的值,作為一個讀寫集(RW-set)。也是智能合約的輸出,如果交易被成功驗證,將會用其去更新賬本。
背書(E4)
這是一個來自背書策略所要求的組織的簽署的交易響應列表。
在真實的區塊鏈環境中,每一個鏈碼都會有自己對應的世界狀態,因此有命名空間的說法,相同的命名空間的智能合約才能訪問對應的世界狀態,因此世界狀態是有命名空間的屬性。而區塊鏈則沒有命名空間屬性,它里面含有來自多個含有不同命名空間的智能合約的交易。
而在Fabric中,每個通道都有一個隔離的賬本,也就是一個完全隔離的區塊鏈和世界狀態,包括命名空間,而應用可以通過連接不同的通道來使得不同通道之間的賬本進行訪問。
3.排序服務
比特幣和以太坊基于概率的共識算法進行共識,保證賬本最終一致,但是可能出現分叉的情況,這與Fabric不同。Fabric有一個特殊的節點,叫做orderder(也稱為排序節點)來進行交易排序,多個排序節點一同提供排序服務。因為fabric的設計依賴于確定性的共識算法,因此每次驗證都需要保證最終一致和正確性,不能引起分叉,而不僅僅是最終一致。
除了最終一致,分離鏈碼執行和背書也給了Fabric在性能和可擴展性上的優勢,消除了執行和排序服務都在同一個節點時可能帶來的瓶頸。
Orders也有訪問控制,限制了誰可以讀寫和修改他們。這些是在通道建立時寫在配置文件中的。和peer一樣,order節點也是屬于一個組織的,這個組織也應當有自己的CA。
orderers的交易處理流:
階段一:提議
在這一階段,客戶端應用程序會發送交易提議到可以調用智能合約來產生賬本更新提議并進行背書的peers的子集。背書節點并不會立即把這個賬本更新提議應用到自己的賬本副本去,而是返回這個賬本更新提議到客戶端去。
階段二:排序并打包交易到區塊
第一階段完成后,客戶端應該會受到來自各peer的背書的交易提議回應。
在這一階段,客戶端提交包含包含交易回應的交易到排序服務節點。排序服務會在同一時間收到來自各個應用程序的交易。排序服務可能由多個節點構成,他們協作來提供排序服務。他們的工作就是將收到的交易進行排序,然后打包成塊,這些塊會變成最終區塊鏈中的區塊。
區塊中的交易數取決于通道配置中的值以及設定的出塊時間參數(BatchSize和BatchTimeout)。區塊之后會被保存在orderer的賬本中,然后分發到channel中的各peers中,orderer賬本中的這些區塊也可以在peer重新連接或者新加入的情況下,在連接排序服務時發送給peer進行同步。
需要注意的是,排序服務的規則并不是交易到達orderer的時間順序,而是和peer保持相同定義的一個順序,peer稍候也會使用這個順序來對塊進行驗證。因為排序服務可能有很多節點,交易到每個節點的時間可能并不一樣,所以時間順序也很難實現。
階段三:驗證提交
階段三中,首先orderer會把區塊分發給所有連接到他的peer,并不是所有的peer都需要連接到order中,因為peer也可以通過gossip協議把區塊發給其他的peer。每一個peer會獨立的驗證區塊,具體來說,會驗證區塊中的每一個交易,確保其被足夠的peer簽名背書。
對于排序服務,order有不同的實現。
Raft(目前推薦的方式)
Raft是一個CFT(crash fault tolerant)排序服務,即任何節點發生崩潰都可以進行動態的恢復,從而保持了高可用性,從order群中選舉出領導者之后,剩下的節點都稱為追隨者,領導者做什么,追隨者都會照做。Raft排序服務會比Kafka排序服務更加容易設立(不需要設立zookeeper,沒有版本問題)以及管理,而且Kafka并不是一個完全去中心化的方案。
每一個通道都有一個單獨的Raft協議實例,實例內部可以自己選舉主節點。選舉之類的操作對peer和客戶端是透明的。
總結
以上是生活随笔為你收集整理的fabric2.0 概念, peer、账本和排序服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows磁盘管理工具Diskpar
- 下一篇: springMVC学习笔记二