Fabric 1.0原始碼分析(42)scc(系統鏈碼) #cscc(通道相關)

尹成發表於2018-05-21
# Fabric 1.0原始碼筆記 之 scc(系統鏈碼) #cscc(通道相關)

## 1、cscc概述

cscc程式碼在core/scc/cscc/configure.go。

## 2、PeerConfiger結構體

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

## 3、Init方法

```go
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方法

```go
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、其他方法

```go
//校驗創世區塊
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

```go
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)程式碼如下:

```go
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)程式碼如下:

```go
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:

```go
type initializer struct {
    *resources
    ppr *policyProposerRoot
}
//程式碼在common/configtx/initializer.go
```








網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN







網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN

相關文章