美文网首页Fabric
fabric源码学习笔记2-chaincode启动过程

fabric源码学习笔记2-chaincode启动过程

作者: 莫名FCJ | 来源:发表于2017-09-28 10:30 被阅读68次

    简介

    chaincode即用户链码,它提供了基于区块链分布式账本的状态处理逻辑。
    fabric中,chaincode默认运行在docker容器中。
    peer通过调用docker api来创建和启动chaincode容器。
    chaincode容器启动后跟peer之间创建gRPC连接,双方通过发送ChaincodeMessage来进行交互通信。
    chaincode容器利用core.chaincode.shim包提供的接口来向Peer发起请求。

    chaincode典型结构

    用户只需关注Init()和Invoke()函数的实现,在其中利用shim.ChaincodeStubInterface结构实现跟账本的交互逻辑。

    package main
    
    import (
        "errors"
        "fmt"
        "github.com/hyperledger/fabric/core/chaincode/shim"
    )
    
    type DemoChaincode struct { }
    
    func (t *DemoChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response {
        // more logics using stub here
        return stub.Success(nil)
    }
    
    func (t *DemoChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response
        // more logics using stub here
        return stub.Success(nil)
    }
    
    func main() {
        err := shim.Start(new(DemoChaincode))
        if err != nil {
            fmt.Printf("Error starting DemoChaincode: %s", err)
        }
    }
    

    启动过程

    chaincode首先是个普通的golang程序,其main方法调用了shim层的Start方法。
    首先会进行初始化,包括读取默认配置,创建到Peer的gRPC连接。
    主要包括NewChaincodeSupportClient和chaincodeSupportClient.Register两个方法。
    初始化完成后,创建有限状态机结构(FSM,github.com/looplab/fsm)。
    FSM会根据收到的消息和当前状态来触发状态转移,并执行提前设置的操作。
    Peer侧也利用了类似的FSM结构来管理消息响应。
    之后,利用创建好的gRPC连接开始向Peer发送第一个gRPC消息:ChaincodeMessage_REGISTER,将自身注册到Peer上。
    注册成功后开始消息处理循环,等待接收来自Peer的消息以及自身的状态转移(nextState)消息。

    后续过程中,chaincode和Peer利用FSM完成一系列对消息的响应运作:
    1、Peer收到来自链码容器的ChaincodeMessage_REGISTER消息,将其注册到本地的一个Handler结构,返回ChaincodeMessage_REGISTERD消息发给链码容器。
    之后更新状态为established(已建立),并发送ChaincodeMessage_READY消息给链码侧,更新状态为ready。
    2、链码侧收到ChaincodeMessage_REGISTERD消息后,不进行任何操作,注册成功,更新状态为established(已建立)。
    收到ChaincodeMessage_READY消息后更新状态为ready。
    3、Peer侧发出ChaincodeMessage_INIT消息给链码容器,准备触发链码侧初始化操作。
    4、链码容器收到ChaincodeMessage_INIT消息,通过Handler.handleInit()方法进行初始化。
    主要包括初始化所需的ChaincodeStub结构,以及调用链码代码中Init()方法。初始化成功后,返回ChaincodeMessage_COMPLETED消息给Peer。
    此时链码容器进入可被调用(Invoke)状态。
    5、链码被调用时,Peer发出ChaincodeMessage_TRANSACTION消息给链码。
    6、链码收到ChaincodeMessage_TRANSACTION消息,会调用Invoke()方法。
    根据Invoke方法中用户实现的逻辑,可以发出包括ChaincodeMessage_GET_HISTORY_FOR_KEY、ChaincodeMessage_GET_QUERY_RESULT、
    ChaincodeMessage_GET_STATE、ChaincodeMessage_GET_STATE_BY_RANGE、ChaincodeMessage_QUERY_STATE_CLOSE、
    ChaincodeMessage_QUERY_STATE_NEXT、ChaincodeMessage_INVOKE_CHAINCODE等消息给Peer侧。
    Peer侧收到这些消息,进行相应处理,并回复ChaincodeMessage_RESPONSE消息。
    最后链码侧会回复调用完成的消息ChaincodeMessage_COMPLETE给Peer侧。
    在上述过程中,Peer和链码还会不定期发送ChaincodeMessage_KEEPALIVE消息给对方,以确保在线。

    相关文档

    https://github.com/yeasy/hyperledger_code_fabric/blob/master/process/chaincode_start.md

    相关文章

      网友评论

        本文标题:fabric源码学习笔记2-chaincode启动过程

        本文链接:https://www.haomeiwen.com/subject/fejmextx.html