1. 程式人生 > >區塊鏈教程Fabric1.0原始碼分析scc(系統鏈碼)

區塊鏈教程Fabric1.0原始碼分析scc(系統鏈碼)

  區塊鏈教程Fabric1.0原始碼分析scc(系統鏈碼),2018年下半年,區塊鏈行業正逐漸褪去發展之初的浮躁、迴歸理性,表面上看相關人才需求與身價似乎正在回落。但事實上,正是初期泡沫的漸退,讓人們更多的關注點放在了區塊鏈真正的技術之上。

Fabric 1.0原始碼筆記 之 scc(系統鏈碼)

1、scc概述

scc,system chain codes,即系統鏈碼。包括:

  • cscc,configuration system chaincode,處理在peer通道配置。
  • escc,endorser system chaincode,對交易申請的應答資訊進行簽名,來提供背書功能。
  • lscc,lifecycle system chaincode,處理生命週期請求,如chaincode的安裝,例項化,升級,解除安裝。
  • qscc,querier system chaincode,提供賬本查詢,如獲取塊和交易資訊。
  • vscc,validator system chaincode,處理交易校驗,包括檢查背書策略和版本在併發時的控制。

scc程式碼分佈在core/common/sysccprovider和core/scc目錄下,目錄結構如下:

  • core/common/sysccprovider目錄:
        * sysccprovider.go,SystemChaincodeProvider和SystemChaincodeProviderFactory介面定義。
  • core/scc目錄:
         sysccapi.go,SystemChaincode結構體及方法。
        
    sccproviderimpl.go,SystemChaincodeProvider和SystemChaincodeProviderFactory介面實現,即sccProviderFactory和sccProviderImpl結構體及方法。
        * importsysccs.go,scc工具函式。

2、介面定義

2.1、SystemChaincodeProviderFactory介面定義

介面定義如下:

type SystemChaincodeProviderFactory interface {
    //建立SystemChaincodeProvider
    NewSystemChaincodeProvider() SystemChaincodeProvider
}
//程式碼在core/common/sysccprovider/sysccprovider.go

全域性變數及相關函式:

var sccFactory SystemChaincodeProviderFactory

//為sccFactory賦值
func RegisterSystemChaincodeProviderFactory(sccfact SystemChaincodeProviderFactory) 
//獲取sccFactory.NewSystemChaincodeProvider()
func GetSystemChaincodeProvider() SystemChaincodeProvider {
//程式碼在core/common/sysccprovider/sysccprovider.go

補充ChaincodeInstance結構體定義:

type ChaincodeInstance struct {
    ChainID          string //ID
    ChaincodeName    string //名稱
    ChaincodeVersion string //版本
}
//程式碼在core/common/sysccprovider/sysccprovider.go

2.2、SystemChaincodeProvider介面定義

介面定義如下:

type SystemChaincodeProvider interface {
    IsSysCC(name string) bool //是否系統鏈碼
    IsSysCCAndNotInvokableCC2CC(name string) bool //確認是系統鏈碼且不可通過CC2CC呼叫
    IsSysCCAndNotInvokableExternal(name string) bool //確認是系統鏈碼且不可通過提案呼叫
    GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error) //獲取賬本的查詢執行器
}
//程式碼在core/common/sysccprovider/sysccprovider.go

3、SystemChaincodeProvider和SystemChaincodeProviderFactory介面實現

SystemChaincodeProviderFactory介面實現,即sccProviderFactory結構體及方法:

type sccProviderFactory struct {
}

//構造sccProviderImpl{}
func (c *sccProviderFactory) NewSystemChaincodeProvider() sysccprovider.SystemChaincodeProvider
//程式碼在core/scc/sccproviderimpl.go

SystemChaincodeProvider介面實現,即sccProviderImpl結構體及方法:

type sccProviderImpl struct {
}

func (c *sccProviderImpl) IsSysCC(name string) bool //IsSysCC(name)
func (c *sccProviderImpl) IsSysCCAndNotInvokableCC2CC(name string) bool //IsSysCCAndNotInvokableCC2CC(name)
//l := peer.GetLedger(cid)
//l.NewQueryExecutor()
func (c *sccProviderImpl) GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error)
//IsSysCCAndNotInvokableExternal(name)
func (c *sccProviderImpl) IsSysCCAndNotInvokableExternal(name string) bool
//程式碼在core/scc/sccproviderimpl.go

4、scc工具函式

systemChaincodes定義:

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
    },
    {
        Enabled:           true,
        Name:              "lscc",
        Path:              "github.com/hyperledger/fabric/core/scc/lscc",
        InitArgs:          [][]byte{[]byte("")},
        Chaincode:         &lscc.LifeCycleSysCC{},
        InvokableExternal: true, // lscc is invoked to deploy new chaincodes
        InvokableCC2CC:    true, // lscc can be invoked by other chaincodes
    },
    {
        Enabled:   true,
        Name:      "escc",
        Path:      "github.com/hyperledger/fabric/core/scc/escc",
        InitArgs:  [][]byte{[]byte("")},
        Chaincode: &escc.EndorserOneValidSignature{},
    },
    {
        Enabled:   true,
        Name:      "vscc",
        Path:      "github.com/hyperledger/fabric/core/scc/vscc",
        InitArgs:  [][]byte{[]byte("")},
        Chaincode: &vscc.ValidatorOneValidSignature{},
    },
    {
        Enabled:           true,
        Name:              "qscc",
        Path:              "github.com/hyperledger/fabric/core/chaincode/qscc",
        InitArgs:          [][]byte{[]byte("")},
        Chaincode:         &qscc.LedgerQuerier{},
        InvokableExternal: true, // qscc can be invoked to retrieve blocks
        InvokableCC2CC:    true, // qscc can be invoked to retrieve blocks also by a cc
    },
}
//程式碼在core/scc/importsysccs.go

涉及scc工具函式如下:

func RegisterSysCCs() //遍歷systemChaincodes,呼叫RegisterSysCC(sysCC)
func DeploySysCCs(chainID string)//遍歷systemChaincodes,呼叫deploySysCC(chainID, sysCC)
func DeDeploySysCCs(chainID string)//遍歷systemChaincodes,呼叫DeDeploySysCC(chainID, sysCC)
func IsSysCC(name string) bool //是否系統鏈碼
func IsSysCCAndNotInvokableExternal(name string) bool //確認是系統鏈碼且不可被髮送到此節點的提案呼叫
func IsSysCCAndNotInvokableCC2CC(name string) bool //確認是系統鏈碼且不可通過chaincode-to-chaincode方式呼叫
//程式碼在core/scc/importsysccs.go

5、SystemChaincode結構體及方法

type SystemChaincode struct {
    Name string //系統鏈碼唯一名稱
    Path string //系統鏈碼路徑,當前未使用
    InitArgs [][]byte //啟動系統鏈碼的初始化引數
    Chaincode shim.Chaincode //實際的shim.Chaincode物件
    InvokableExternal bool //跟蹤是否可以被髮送到此節點的提案呼叫
    InvokableCC2CC bool //跟蹤是否可以通過chaincode-to-chaincode方式呼叫
    Enabled bool //啟用或禁用
}

//註冊系統鏈碼,呼叫inproccontroller.Register(syscc.Path, syscc.Chaincode)
func RegisterSysCC(syscc *SystemChaincode) error
func deploySysCC(chainID string, syscc *SystemChaincode) error //部署鏈碼
func DeDeploySysCC(chainID string, syscc *SystemChaincode) error //停止鏈碼
func buildSysCC(context context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) //編譯鏈碼
func isWhitelisted(syscc *SystemChaincode) bool //是否在白名單,基於chaincode.system配置
//程式碼在core/scc/sysccapi.go