區塊鏈教程Fabric1.0源代碼分析scc(系統鏈碼)cscc(通道相關)-兄弟連區塊鏈教程

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

Fabric 1.0源代碼筆記 之 scc(系統鏈碼) #cscc(通道相關)

1、cscc概述

cscc代碼在core/scc/cscc/configure.go。

2、PeerConfiger結構體

type PeerConfiger struct {
    policyChecker policy.PolicyChecker
}
//代碼在core/scc/cscc/configure.go

3、Init方法

func (e *PeerConfiger) Init(stub shim.ChaincodeStubInterface) pb.Response {
    //初始化策略檢查器,用於訪問控制
    e.policyChecker = policy.NewPolicyChecker(
        peer.NewChannelPolicyManagerGetter(),
        mgmt.GetLocalMSP(),
        mgmt.NewLocalMSPPrincipalGetter(),
    )
    return shim.Success(nil)
}
//代碼在core/scc/cscc/configure.go

4、Invoke方法

func (e *PeerConfiger) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    //args[0]爲JoinChain或GetChannels
    args := stub.GetArgs()
    fname := string(args[0]) //Invoke function
    sp, err := stub.GetSignedProposal() //獲取SignedProposal

    switch fname {
    case JoinChain: //加入通道
        //此處args[1]爲創世區塊
        block, err := utils.GetBlockFromBlockBytes(args[1])
        cid, err := utils.GetChainIDFromBlock(block)
        err := validateConfigBlock(block)
        err = e.policyChecker.CheckPolicyNoChannel(mgmt.Admins, sp)
        return joinChain(cid, block)
    case GetConfigBlock:
        err = e.policyChecker.CheckPolicy(string(args[1]), policies.ChannelApplicationReaders, sp)
        return getConfigBlock(args[1])
    case GetChannels:
        err = e.policyChecker.CheckPolicyNoChannel(mgmt.Members, sp)
        return getChannels()

    }
}
//代碼在core/scc/cscc/configure.go

5、其他方法

//校驗創世區塊
func validateConfigBlock(block *common.Block) error
func joinChain(chainID string, block *common.Block) pb.Response
func getConfigBlock(chainID []byte) pb.Response
func getChannels() pb.Response
//代碼在core/scc/cscc/configure.go

5.1、joinChain

func joinChain(chainID string, block *common.Block) pb.Response {
    err := peer.CreateChainFromBlock(block) //創建chain
    peer.InitChain(chainID)
    err := producer.SendProducerBlockEvent(block)
    return shim.Success(nil)
}
//代碼在core/scc/cscc/configure.go

5.1.1、創建Chain(或channel)

peer.CreateChainFromBlock(block)代碼如下:

func CreateChainFromBlock(cb *common.Block) error {
    cid, err := utils.GetChainIDFromBlock(cb) //獲取ChainID
    var l ledger.PeerLedger
    l, err = ledgermgmt.CreateLedger(cb) //創建Ledger
    return createChain(cid, l, cb)
}
//代碼在core/peer/peer.go

createChain(cid, l, cb)代碼如下:

func createChain(cid string, ledger ledger.PeerLedger, cb *common.Block) error {
    envelopeConfig, err := utils.ExtractEnvelope(cb, 0) //獲取配置Envelope
    configtxInitializer := configtx.NewInitializer() //type initializer struct
    gossipEventer := service.GetGossipService().NewConfigEventer() //獲取gossipServiceInstance

    gossipCallbackWrapper := func(cm configtxapi.Manager) {
        ac, ok := configtxInitializer.ApplicationConfig()
        if !ok {
            // TODO, handle a missing ApplicationConfig more gracefully
            ac = nil
        }
        gossipEventer.ProcessConfigUpdate(&chainSupport{
            Manager:     cm,
            Application: ac,
        })
        service.GetGossipService().SuspectPeers(func(identity api.PeerIdentityType) bool {
            // TODO: this is a place-holder that would somehow make the MSP layer suspect
            // that a given certificate is revoked, or its intermediate CA is revoked.
            // In the meantime, before we have such an ability, we return true in order
            // to suspect ALL identities in order to validate all of them.
            return true
        })
    }

    trustedRootsCallbackWrapper := func(cm configtxapi.Manager) {
        updateTrustedRoots(cm)
    }

    configtxManager, err := configtx.NewManagerImpl(
        envelopeConfig,
        configtxInitializer,
        []func(cm configtxapi.Manager){gossipCallbackWrapper, trustedRootsCallbackWrapper},
    )
    if err != nil {
        return err
    }

    // TODO remove once all references to mspmgmt are gone from peer code
    mspmgmt.XXXSetMSPManager(cid, configtxManager.MSPManager())

    ac, ok := configtxInitializer.ApplicationConfig()
    if !ok {
        ac = nil
    }
    cs := &chainSupport{
        Manager:     configtxManager,
        Application: ac, // TODO, refactor as this is accessible through Manager
        ledger:      ledger,
    }

    c := committer.NewLedgerCommitterReactive(ledger, txvalidator.NewTxValidator(cs), func(block *common.Block) error {
        chainID, err := utils.GetChainIDFromBlock(block)
        if err != nil {
            return err
        }
        return SetCurrConfigBlock(block, chainID)
    })

    ordererAddresses := configtxManager.ChannelConfig().OrdererAddresses()
    if len(ordererAddresses) == 0 {
        return errors.New("No ordering service endpoint provided in configuration block")
    }
    service.GetGossipService().InitializeChannel(cs.ChainID(), c, ordererAddresses)

    chains.Lock()
    defer chains.Unlock()
    chains.list[cid] = &chain{
        cs:        cs,
        cb:        cb,
        committer: c,
    }
    return nil
}
//代碼在core/peer/peer.go

補充initializer:

type initializer struct {
    *resources
    ppr *policyProposerRoot
}
//代碼在common/configtx/initializer.go
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章