java随记

坚持就是胜利!

 

Fabric 1.1源代码分析之 系统链码初始化过程(哥哥篇)

# Fabric 1.1源代码分析之 Fabric 1.1源代码分析 系统链码初始化过程

* 链码这一块的代码非常的绕。基本上就是一个大循环。限于水平或者其它原因,差露可能难免,各位看官包涵则个...

## 1、系统链码

* 系统链码跟智能合约链码涉及到的文件差不多,流程也差不多。只是智能合约是grpc,系统链码是chan实现调用.
LSCC Lifecycle system chaincode,处理生命周期请求。我理解的生命周期请求应该指的是一个chaincode的安装,实例化,升级,
卸载等对其生命周期起关键作用的一系列操作请求。
CSCC Configuration system chaincode,处理在peer程序端的channel配置。
QSCC Query system chaincode,提供账本查询接口,如获取块和交易信息。
ESCC Endorsement system chaincode,通过对交易申请的应答信息进行签名,来提供背书功能。
VSCC Validation system chaincode,处理交易校验,包括检查背书策略和版本在并发时的控制。

## 2、系统链码注册
* 在/core/chaincode/shim/interfaces_stable.go中实现了下面的接口
```go
type Chaincode interface {
    // Init is called during Instantiate transaction after the chaincode container
    // has been established for the first time, allowing the chaincode to
    // initialize its internal data
    Init(stub ChaincodeStubInterface) pb.Response

    // Invoke is called to update or query the ledger in a proposal transaction.
    // Updated state variables are not committed to the ledger until the
    // transaction is committed.
    Invoke(stub ChaincodeStubInterface) pb.Response
}
```

* 在core/scc/sysccapi.go中定义了SystemChaincode结构体,其中定义了 Chaincode接口变量
```go
type SystemChaincode struct {
    //Unique name of the system chaincode
    Name string

    //Path to the system chaincode; currently not used
    Path string

    //InitArgs initialization arguments to startup the system chaincode
    InitArgs [][]byte

    // Chaincode is the actual chaincode object
    Chaincode shim.Chaincode

    // InvokableExternal keeps track of whether
    // this system chaincode can be invoked
    // through a proposal sent to this peer
    InvokableExternal bool

    // InvokableCC2CC keeps track of whether
    // this system chaincode can be invoked
    // by way of a chaincode-to-chaincode
    // invocation
    InvokableCC2CC bool

    // Enabled a convenient switch to enable/disable system chaincode without
    // having to remove entry from importsysccs.go
    Enabled bool
}
```

* 在 core/scc/importsysccs.go文件中对系统链码进行了初始化,并且每个Chainoce指定了具体实现
```go
//see systemchaincode_test.go for an example using "sample_syscc"
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.NewLifeCycleSysCC(),
        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
    },
}
```
* 注册流程图
![](systemcoderegist.png)


## 3、系统链码初始化
* 系统注册完成后会对链码初始化.跟一般chaincode稍有不同的是chaincode在合约里通过grpc与peer节点交互。
而系统链码则是在协程里通过chan 实现交互.下面代码创建两个 peerRcvCCSend := make(chan *pb.ChaincodeMessage)
    ccRcvPeerSend := make(chan *pb.ChaincodeMessage) ,是客户端和服务端共同的参数
```go

func (ipc *inprocContainer) launchInProc(ctxt context.Context, id string, args []string, env []string, ccSupport ccintf.CCSupport) error {
    peerRcvCCSend := make(chan *pb.ChaincodeMessage)
    ccRcvPeerSend := make(chan *pb.ChaincodeMessage)
    var err error
    ccchan := make(chan struct{}, 1)
    ccsupportchan := make(chan struct{}, 1)
    //启动客户端处理
    go func() {
        defer close(ccchan)
        inprocLogger.Debugf("chaincode started for %s", id)
        if args == nil {
            args = ipc.args
        }
        if env == nil {
            env = ipc.env
        }
        err := _shimStartInProc(env, args, ipc.chaincode, ccRcvPeerSend, peerRcvCCSend)
        if err != nil {
            err = fmt.Errorf("chaincode-support ended with err: %s", err)
            _inprocLoggerErrorf("%s", err)
        }
        inprocLogger.Debugf("chaincode ended with for %s with err: %s", id, err)
    }()
//启动服务端处理
    go func() {
        defer close(ccsupportchan)
        inprocStream := newInProcStream(peerRcvCCSend, ccRcvPeerSend)
        inprocLogger.Debugf("chaincode-support started for %s", id)
        err := ccSupport.HandleChaincodeStream(ctxt, inprocStream)
        if err != nil {
            err = fmt.Errorf("chaincode ended with err: %s", err)
            _inprocLoggerErrorf("%s", err)
        }
        inprocLogger.Debugf("chaincode-support ended with for %s with err: %s", id, err)
    }()

    select {
    case <-ccchan:
        close(peerRcvCCSend)
        inprocLogger.Debugf("chaincode %s quit", id)
    case <-ccsupportchan:
        close(ccRcvPeerSend)
        inprocLogger.Debugf("chaincode support %s quit", id)
    case <-ipc.stopChan:
        close(ccRcvPeerSend)
        close(peerRcvCCSend)
        inprocLogger.Debugf("chaincode %s stopped", id)
    }
    return err
}

```


* 初始化流程图
![](systemcodeinit.png)


## 4、系统链码的执行
...

posted on 2018-06-12 15:00 傻 瓜 阅读(534) 评论(0)  编辑  收藏 所属分类: 杂项


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(7)

我参与的团队

随笔分类

随笔档案

文章分类

友情链接

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜