概述
在 Hyperledger Fabric 中,鏈碼(Chaincode)又稱為智能合約(下文中我們統一稱為鏈碼),是用Go,node.js或Java編寫的程式,主要用於操作賬本上的資料。使用者的應用程式通過鏈碼與 Fabric 賬本資料進行互動。
一個完整的 Fabric 區塊鏈應用程式套件含使用者的應用程式和使用者編寫的鏈碼兩部分。使用者的應用程式通過區塊鏈網路中部署的 Peer 節點調用鏈碼,使用者鏈碼通過區塊鏈網路的 Peer 節點來操作賬本資料。如下圖所示:
Fabric 中的 Peer 節點提供了調用鏈碼相關服務的介面。使用者的應用程式可以通過調用相關介面和 Fabric Peer 進行互動, Peer 節點通過與鏈碼容器進行互動,完成應用程式和鏈碼之間的互動。
使用者的應用程式可以通過以下兩種方式與 Fabric Peer 進行互動:
利用 Fabric 提供的 SDK 與 Fabric Peer 進行互動,具體參看 Fabric SDK。
利用阿里雲BaaS提供的 API 介面 與 Fabric Peer 進行互動。
生命週期
鏈碼開發編寫完成後,並不能直接使用,需要經過一系列的操作之後才能應用在 Hyperledger Fabric 網路中進而處理用戶端提交的交易。這一系列的操作是由鏈碼的生命週期來負責管理。
Fabric 1.x 中管理 Chaincode 的生命週期主要有如下幾個命令:
package: 對指定的鏈碼進行打包的操作。
install: 將已編寫完成的鏈碼安裝在網路節點中。
instantiate: 對已安裝的鏈碼進行執行個體化。
upgrade: 對已有鏈碼進行升級。鏈代碼可以在安裝後根據具體需求的變化進行升級。
Fabric 2.x 中管理 Chaincode 的生周期主要有如下幾個命令:
package: 對指定的鏈碼進行打包的操作。
approveformyorg: 在網路提議某個已編寫完成的鏈碼。
commit: 在網路中正式提交已編寫完成的鏈碼,預設超過半數成員通過提議後才會生效。
Tips:在阿里雲BaaS的控制台上,使用者可以直接完成鏈碼的上傳、安裝、執行個體化等操作,不需要依賴命令列來完成。
鏈碼類型
在 Hyperledger Fabric 中,鏈碼一般分為:
系統鏈碼
使用者鏈碼
系統鏈碼
系統鏈碼負責 Fabric 節點自身的處理邏輯,包括系統配置、背書、校正等工作。系統鏈碼僅支援 Go 語言,在 Peer 節點啟動時會自動完成註冊和部署,所以安裝,執行個體化和升級不適用於系統鏈碼。
系統鏈碼主要包括以下幾種:
生命週期系統鏈碼(LSCC):Lifecycle System Chaincode,負責對使用者鏈碼的生命週期進行管理。
配置系統鏈碼(CSCC):Configuration System Chaincode,負責處理 Peer 端的 Channel 配置。
查詢系統鏈碼(QSCC):Query System Chaincode,提供賬本查詢 API,如擷取區塊和交易等資訊。
使用者鏈碼
使用者鏈碼是由應用程式開發人員根據業務情境需求使用 Golang、node.js 或 Java 語言編寫的操作區塊鏈分散式總帳的狀態的業務處理邏輯代碼,使用者鏈碼運行在鏈碼容器中,通過 Fabric 提供的介面與賬本狀態進行互動。
使用者鏈碼在區塊鏈應用上處於非常關鍵的一環,它直接接受使用者商務邏輯的調用,並對區塊鏈分散式總帳資料進行操作。
背書策略
每個智能合約都有與之相關的背書策略。該背書策略可確定哪些組織必須批准智能合約產生的交易,然後才能將其確認為有效交易。在上傳鏈碼及執行個體化鏈碼時,需要為其指定對應的背書策略。
背書策略舉例:
OR ('Org1MSP.peer','Org2MSP.peer')表示此通道中的兩個組織任何一方背書即可;AND (‘Org1MSP.peer’,’Org2MSP.peer’)表示需要此通道中的兩個組織背書。
更多參考:Fabric設計->背書策略
交易執行流程
在 Hyperledger Fabric上,一筆交易的執行需要 Peer節點、orderer節點、CA節點及client端共同參與。
Peer節點:該節點是參與交易的主體,可以說是代表每個參與到鏈上的成員,它負責儲存完整的賬本資料即區塊鏈資料,負責共識環節中的執行智能合約,驗證區塊和交易並將合法交易提交(commit)到賬本中。
Orderer節點:該節點接受包含背書籤名的交易請求進行排序並打包生產新的區塊,主體功能便是對交易排序從而保證各Peer節點上的資料一致性。
CA節點:該節點負責對加入鏈內的所有節點進行授權認證,包括上層的client端,每一個節點都有其頒發的認證用於交易流程中的身份識別。
client:Fabric對於client端提供了SDK讓開發人員可以更容易的對接到區塊鏈內的交易環節,交易的發起便是通過SDK進行。
交易的執行流程主要包含如下4大步驟:

該交易的執行流程圖來自於Fabric社區的開源技術文檔(已採用知識共用署名 4.0 國際許可協議進行許可)。
由client端發起一個交易請求,client會根據鏈碼的背書策略決定把該筆交易發往哪些背書的peer節點,由peer節點進行投票,client匯總各背書節點的結果。上圖中的背書策略要求Peer1、Peer2及Peer3參與交易,所以client將請求分別發給 Pee1、Peer2 和 Peer3。
三個 Peer 節點接收到交易請求後執行對應的鏈碼並對結果進行簽名然後分別將輸出結果返回給client。
client將收到所有的執行結果後連同各peer的背書(包括其投票結果以及背書籤名)後打包發送給 Orderer節點。
Orderer 將接收到的該次交易在交易池裡進行排序並組合打包產生一個新的區塊,並將新的區塊發送給所有的Peer節點,每個Peer節點接收到新區塊後,對其中的每一筆交易結果的簽名進行驗證是否符合背書策略,以及比對讀寫集合與本地的版本是否相同,如滿足所有條件則將新的區塊寫入本地賬本內完成交易。
更多參考:Fabric設計->交易流程
注意事項
跨通道的鏈碼間調用
如果被調用鏈碼與調用鏈碼位於不同的通道,則僅允許讀取查詢。 也就是說,在另一個通道上的被調用鏈碼僅僅是一個查詢,它不參與後續提交階段的狀態驗證檢查。
相同通道下的鏈碼間調用
如果被調用鏈碼與調用鏈碼位於相同通道,則其被調用鏈碼產生的讀寫集會被加入調用鏈碼對應的交易,即共用同一筆交易而不會產生不同的交易。
鏈碼shim包依賴
鏈碼中需要依賴shim包(ChainCodeStub)來與Peer節點通訊,部分語言shim包也提供了擴充介面(例如處理調用者身份)。在鏈碼執行個體化編譯時間Peer節點預設提供了與節點版本一致的shim包,如果您的鏈碼依賴其他相容版本(v1.4.x)的shim包,請一併打包在鏈碼檔案中。
2020年4月29日之前建立的節點版本為v1.4.2,之後建立的節點版本為v1.4.5
Golang 依賴:
老版本:github.com/hyperledger/fabric/core/chaincode/shim、github.com/hyperledger/fabric/protos/peer
新版本:github.com/hyperledger/fabric-chaincode-go/shim、github.com/hyperledger/fabric-protos-go/peer
Java 依賴:fabric-chaincode-shim-1.4.x.jar、fabric-chaincode-protos-1.4.x.jar