Hyperledger Fabric的Transaction處理流程
在介紹Transaction處理流程之前,我們先來了解區(qū)塊鏈網(wǎng)絡(luò)的最重要的組成部分->peer節(jié)點。通過分析peer節(jié)點與其他組件之間的關(guān)系來逐步了解Fabric中transaction的處理流程。
我們通過一下幾個方面來進行了解:
- fabric的網(wǎng)絡(luò)結(jié)構(gòu)
- Peer節(jié)點和賬本和鏈碼的關(guān)系
- applications和peers的關(guān)系
- peers和channels的關(guān)系
- peers和organizations的關(guān)系
- peers和identity的關(guān)系
- peers和orderers的關(guān)系
Fabric的網(wǎng)絡(luò)結(jié)構(gòu)
區(qū)塊鏈網(wǎng)絡(luò)由賬本(ledger)、智能合約(smart contracts)、背書節(jié)點(orderers)、通道(channels)、應(yīng)用(applications)、組織(organizations)、成員關(guān)系服務(wù)提供商(MSP)等部分組成。

- 信息描述:client端的application通過sdk向被選成背書節(jié)的peer發(fā)送交易提案。peer節(jié)點調(diào)用鏈碼模擬執(zhí)行交易。生成讀寫集,返回給client端。client端接收返回結(jié)果,生成交易發(fā)送給排序節(jié)點進行排序。排序節(jié)點對交易進行排序,在達到配置閾值要求時生成區(qū)塊。并廣播到所有peer節(jié)點(實際過程是先發(fā)送給所有主節(jié)點,主節(jié)點在發(fā)送到各自對應(yīng)的所有peer節(jié)點)。peer節(jié)點對交易進行驗證,驗證通過更新世界狀態(tài),將區(qū)塊追加到區(qū)塊鏈中。
Peer節(jié)點和賬本和鏈碼的關(guān)系
peer節(jié)點是區(qū)塊鏈網(wǎng)絡(luò)的基礎(chǔ)組成部分,peer存儲了區(qū)塊鏈賬本數(shù)據(jù),智能合約也是在peer節(jié)點上運行的。下圖展示了peer節(jié)點、賬本和鏈碼這三者之間的關(guān)系。

- 信息描述:區(qū)塊鏈網(wǎng)絡(luò)包含三個peer節(jié)點,分別是P1,P2,P3。三個peer節(jié)點都維護了一份相同的賬本數(shù)據(jù)L1,都運行了同一個鏈碼S1.
當peer節(jié)點剛創(chuàng)建時,是不包含賬本和鏈碼的。當它加入到區(qū)塊鏈網(wǎng)絡(luò)中,安裝完鏈碼之后,才會同步賬本數(shù)據(jù)。
多賬本(Multiple Ledgers)
一個peer節(jié)點可以維護多套賬本,如下圖:

- 信息描述:peer節(jié)點P1同時維護了兩套賬本L1和L2,其中L1賬本由鏈碼S1維護,L2賬本由鏈碼S1和鏈碼S2同時維護。
多鏈碼(Multiple Chaincodes)
一個peer節(jié)點同時也可以維護多套鏈碼,如下圖:

- 信息描述:Peer節(jié)點P1同時維護兩套賬本L1和L2。其中L1賬本由鏈碼S1和S2維護,賬本L2由鏈碼S1和鏈碼S3維護。其中鏈碼S1可以同時維護賬本L1和賬本L2。
結(jié)論:一個鏈碼可以適用于多個賬本,而一個賬本也可以同時由多個鏈碼來維護。
applications和peers的關(guān)系
在上面網(wǎng)絡(luò)結(jié)構(gòu)中,描述了交易執(zhí)行的流程,客戶端發(fā)起交易提案,經(jīng)過背書后,生成交易發(fā)送給排序節(jié)點排序,并生成區(qū)塊,最后提交給提交節(jié)點進行校驗并提交。

注意事項:
其中鏈碼的執(zhí)行是由application通過sdk調(diào)用,通過peer節(jié)點執(zhí)行的。
交易通過排序節(jié)點提交到peer節(jié)點后,如果通過校驗會直接將讀寫集的寫集作為結(jié)果更新世界狀態(tài),并不會再重新執(zhí)行一次鏈碼處理流程。</br>
校驗失敗的交易會被標記成無效,區(qū)塊依舊會追加到區(qū)塊鏈中,但是不會更新世界狀態(tài)。
查詢交易不會執(zhí)行上述圖片中的4、5步。在提案結(jié)果返回后結(jié)束。
peers和channels的關(guān)系
上面已經(jīng)描述了application、peer、賬本、鏈碼之間的關(guān)系。但是它們之間的交互并不是沒有限制的。鏈與鏈之間通過通道來隔離。只有加入到同一個通道的組件之間才能進行交互。如下圖:

- 信息描述:區(qū)塊鏈網(wǎng)絡(luò)N包含通道C,包含兩個peer節(jié)點P1和P2,P1和P2都安裝了同一套鏈碼S1,維護同一套賬本L1.網(wǎng)絡(luò)外的應(yīng)用程序A,通過加入到通道中,與網(wǎng)絡(luò)進行通信,發(fā)起交易。
channel并不是一個實體,它只是一個邏輯概念。
peers和organizations的關(guān)系
peer節(jié)點是區(qū)塊鏈網(wǎng)絡(luò)的最基礎(chǔ)的組成部分。但是區(qū)塊鏈網(wǎng)絡(luò)并不是按peer為單位進行管理的,而是按組織。如下圖:

- 信息描述:區(qū)塊鏈網(wǎng)絡(luò)N包含了8個peer節(jié)點,和一個通道C。其中P1、P2節(jié)點屬于組織1,P3、P4、P5屬于組織2,P6、P7屬于組織3,P8屬于組織4.組織1中的peer節(jié)點P1、組織2中的peer節(jié)點P3 P4、組織3中的peer節(jié)點P7、組織4中的peer節(jié)點P8都加入到了同一個通道C中。同時應(yīng)用程序A1、A2、A3、A4,分別加入了對應(yīng)的組織。
注意事項:一個組織中的peer節(jié)點可以加入到不同的通道中。一個peer節(jié)點屬于一個組織。應(yīng)用程序可以鏈接到所加入的組織中的其中一個節(jié)點。
peers和identity的關(guān)系
關(guān)于加入到鏈中的peer的身份管理,如下圖:

當一個peer加入到一個通道,它所屬的組織會通過MSP給這個peer分配一個數(shù)字證書。在上面這個圖例中,P1、P2通過CA1分配證書,P3、P4通過CA2分配證書。通道C通過配置的通道配置策略CP來確認peer節(jié)點和組織的關(guān)系。
一個peer只能屬于一個組織,所以一個peer也只是對應(yīng)一個MSP,一個MSP可以給多個peer分配證書。
peers和orderers的關(guān)系
排序節(jié)點負責(zé)對交易進行排序,并負責(zé)生成區(qū)塊。一個交易執(zhí)行的主要過程大致分成三部分,第一部分:發(fā)起提案,由背書節(jié)點對提案進行背書簽名。第二部分:發(fā)起交易,由排序節(jié)點進行排序,并聲稱區(qū)塊。第三部分:分發(fā)到所有peer節(jié)點進行校驗,然后更新賬本。排序節(jié)點處于交易的核心位置。
接下來我們分別看這三部分的處理流程:
提案處理

- 信息描述:區(qū)塊鏈網(wǎng)絡(luò)N,包含通道C、排序節(jié)點O1、peer節(jié)點P1、P2,都安裝了鏈碼S1,維護同一套賬本L1,由applicationA1,發(fā)起交易請求。A1發(fā)起交易提案,由P1、P2背書后,將結(jié)果返回至A1。其中P1、P2屬于不同的組織。
問題:一筆交易應(yīng)該由哪些背書節(jié)點進行背書?
答:這個是由背書策略決定的,背書策略定義了需要經(jīng)過一組組織確認,交易才會被認可。背書策略可以手工指定。
問題:背書的過程是怎么樣的?
答:背書節(jié)點模擬執(zhí)行鏈碼生成結(jié)果之后,背書節(jié)點通過自身的私鑰對返回結(jié)果進行加密。這也是背書策略驗證是否收集到足夠背書的一個證明。
打包生成區(qū)塊
背書節(jié)點接收很多application的交易,并對這寫交易進行排序,根據(jù)配置文件配置的區(qū)塊生成配置來生成區(qū)塊。

- 信息描述:區(qū)塊鏈網(wǎng)絡(luò)N,包含通道C、排序節(jié)點O1、peer節(jié)點P1、P2。這個網(wǎng)絡(luò)中有多個application發(fā)起了交易,order接收這些交易。對收集到的交易進行排序,并生成區(qū)塊B2。排序結(jié)果與排序節(jié)點接收到交易的先后次序沒有關(guān)系。
在配置文件fabric/examples/e2e_cli/configtx.yaml中有兩個配置,定義了區(qū)塊的生成策略。
BatchTimeout:從區(qū)塊的第一筆交易開始,創(chuàng)建一個計時器,當超過這個超時時間,還沒有足夠的交易,那么會將所有未打包的交易進行打包生成區(qū)塊。
BatchSize:這個配置又主要包含三個部分。如下:MaxMessageCount:區(qū)塊包含的最大交易數(shù)量。
AbsoluteMaxBytes:區(qū)塊最大的大小。(不包括交易頭部)
PreferredMaxBytes:每個區(qū)塊建議的大小。Kafka對于相對小的消息提供更高的吞吐量;區(qū)塊大小最好不要超過1MB。
打包生成的區(qū)塊是一定會被加入到區(qū)塊鏈中的,如果是無效交易,會被標示成無效,但是交易依舊是存在于區(qū)塊中。區(qū)塊中的交易是不能修改的。
校驗區(qū)塊并更新賬本

- 信息描述:區(qū)塊鏈網(wǎng)絡(luò)N包含通道C、排序節(jié)點O1、peer節(jié)點P1、P2,排序節(jié)點O1將排序后生成的區(qū)塊B2,分發(fā)給P1、P2。P1、P2在對區(qū)塊中的交易進行過校驗之后,將區(qū)塊追加到鏈碼L1中。這個過程中是不需要執(zhí)行鏈碼的。