fabric源碼解析8——peer的System Chaincode

fabric源碼解析8——peer的System Chaincode

綜述

關於System Chaincode,下文中以系統鏈碼稱之。這是個人翻譯,依據是Chaincode本質是註冊存儲到鏈上的一段邏輯代碼,因此個人習慣稱Chaincode爲鏈碼,fabric文檔中也變相的稱爲智能合約。但是,因爲Chaincode是專用名詞,個人覺得不翻譯而直接使用是最好的。

start.go中的serve函數裏,在爲peerServer註冊ChaincodeSupport服務的函數registerChaincodeSupport(peerServer.Server())中,實現了註冊System Chaincode:scc.RegisterSysCCs()

系統鏈碼的核心代碼在/fabric/core/common/sysccprovider/fabric/core/scc下,scc也就是System Chaincode的縮寫。系統鏈碼分爲五種:cscc,escc,lscc,qscc,vscc,均爲各個系統鏈碼的縮寫。系統鏈碼均實現了/fabric/core/chaincode/shim/interfaces.go中定義的Chaincode接口,從此點就可以看出,系統鏈碼也屬於Chaincode,只不過作用稍微特殊一點:

  • cscc:configuration system chaincode
  • lscc:lifecycle system chaincode
  • escc:endorser system chaincode
  • vscc:validator system chaincode
  • qscc:querier system chaincode

sysccprovider目錄下的文件有:

  • sysccprovider.go - 定義系統鏈碼服務提供者接口

scc目錄下的文件有:

  • sysccapi.go - 系統鏈碼的各種api操作
  • importsysccs.go - 導入五種預定義的系統鏈碼
  • sccproviderimpl.go - 定義了系統鏈碼服務提供者的具體實現和其操作

結構圖

這裏寫圖片描述

預定義和註冊

/fabric/core/scc/importsysccs.go中:

//預定義的五個系統鏈碼存放到數組中
var systemChaincodes = []*SystemChaincode{
    {
        Enabled:           true,
        Name:              "cscc",
        Path:              "github.com/hyperledger/fabric/core/scc/cscc",
        InitArgs:          [][]byte{[]byte("")},
        Chaincode:         &cscc.PeerConfiger{},
        InvokableExternal: true, // cscc is invoked to join a channel
    },{...},{...},{...},{...},
}
//註冊五個系統鏈碼
func RegisterSysCCs() {
    for _, sysCC := range systemChaincodes {
        RegisterSysCC(sysCC)
    }
}

RegisterSysCCs遍歷systemChaincodes中所有的系統鏈碼,並依次調用RegisterSysCC進行註冊。RegisterSysCC在/fabric/core/scc/sysccapi.go中定義:

//系統鏈碼開啓且處於白名單中
if !syscc.Enabled || !isWhitelisted(syscc) {...}
//最終將系統鏈碼註冊到系統中
err := inproccontroller.Register(syscc.Path, syscc.Chaincode)

inproccontroller.Register定義在/fabric/core/container/inproccontroller/inproccontroller.go

//存放安裝的chaincode,以chaincode所在的path爲key
typeRegistry = make(map[string]*inprocContainer)
//註冊到typeRegistry
func Register(path string, cc shim.Chaincode) error {
    tmp := typeRegistry[path]
    if tmp != nil {
        return SysCCRegisteredErr(path)
    }
    typeRegistry[path] = &inprocContainer{chaincode: cc}
    return nil
}

Register函數以系統鏈碼Path成員值爲key,包含系統鏈碼的inprocContainer對象爲value,將系統鏈碼放入typeRegistry映射中。至此,系統鏈碼註冊完畢。

釋義

以下文字翻譯自Fabric 文檔中關於系統鏈碼(System Chaincode)的部分。

系統鏈碼與一般chaincode一樣,有相同的編程模型,比不過系統鏈碼是運行在peer程序中,即其是peer程序的一部分,而一般的chaincode是單獨運行在一個容器中的。因此,系統鏈碼是內建在peer程序中且不遵循一般chaincode那樣的生命週期。特別的,install,instantiate和upgrade操作也不應用於系統鏈碼。

系統鏈碼區別與一般的chaincode的目的是縮短grpc在peer結點與chaincode之間通信的時間消耗(因爲peer結點在一個容器,chaincode是單獨的一個容器),並權衡管理上的靈活性。比如,一個系統鏈碼可以僅通過升級peer程序的二進制包來得到升級。系統鏈碼可以用預定義的元素註冊並編譯到peer程序中,而且不需要有類似於背書策略或背書功能等這樣的冗雜的功能。

系統鏈碼被用在fabric中,去操縱整個系統的配置表現,這樣的話可以隨時把系統改變到合適的狀態。

當前存在的系統鏈碼名單:

  • LSCC Lifecycle system chaincode,處理生命週期請求。我理解的生命週期請求應該指的是一個chaincode的安裝,實例化,升級,卸載等對其生命週期起關鍵作用的一系列操作請求。
  • CSCC Configuration system chaincode,處理在peer程序端的頻道配置。
  • QSCC Query system chaincode,提供賬本查詢接口,如獲取塊和交易信息。
  • ESCC Endorsement system chaincode,通過對交易申請的應答信息進行簽名,來提供背書功能。
  • VSCC Validation system chaincode,處理交易校驗,包括檢查背書策略和版本在併發時的控制。

在修改或替換系統鏈碼時必須注意,特別是LSCC,ESCC和VSCC,因爲它們處於重要的交易環節中。以vscc爲例,因爲區域鏈中的交易數據都是持久性的,因此當vscc在提交一個block到賬本中之前先驗證該塊,這不值什麼,重要的是在同頻道中的所有peer必須計算出相同的證書(由驗證輸出的證書)以避免賬本產生衝突。因此特別需要注意的是vscc被修改或替換時,要避免和以前所產生的交易數據產生衝突。

發佈了30 篇原創文章 · 獲贊 142 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章