Hyperledger Fabric学习(三)链码

一、链码开发模板

        链码开发实现Chaincode接口,Chaincode接口里面只有两个方法,一个是Init()方法(链码初始化),另一个是Invoke()方法(链码调用主要逻辑),Chaincode接口如下:

/*
   所有链码必须实现Chaincode接口的Init()和Invoke()方法,
   并且fabric需要调用这两个方法来执行交易逻辑
 */
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()方法在首次建立链码容器后负责实例化,并初始化数据
    */
   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()方法执行,包括查询或者更新账本
      交易成功提交后,更新的状态变量才会提交到账本中
    */
   Invoke(stub ChaincodeStubInterface) pb.Response
}

        在链码开发的过程中,主要涉及到ChaincodeStubInterface的以下方法,可以直接使用,方法列表如下:

type ChaincodeStubInterface interface {
  //获取参数,返回Invoke()方法名称,以及参数列表
  GetFunctionAndParameters() (string, []string)
  //获取TxID,也就是每次调用的提案ID
  GetTxID() string
  //获取KV键值Value
  GetState(key string) ([]byte, error)
  //更新KV键值
  PutState(key string, value []byte) error
  //删除KV键值
  DelState(key string) error
  //根据字典序获取KV键值集合
  GetStateByRange(startKey, endKey string) (StateQueryIteratorInterface, error)
  //获取联合索引KV键值
  GetStateByPartialCompositeKey(objectType string, keys []string) (StateQueryIteratorInterface, error)
  //创建联合索引
  CreateCompositeKey(objectType string, attributes []string) (string, error)
  //分割联合索引
  SplitCompositeKey(compositeKey string) (string, []string, error)
  //获取KV键值结合
  GetQueryResult(query string) (StateQueryIteratorInterface, error)
  //获取对应Key下的历史更新记录
  GetHistoryForKey(key string) (HistoryQueryIteratorInterface, error)
}

二、链码启动流程

  • 初始化:读取默认配置,创建到Peer节点的gRPC的连接;
  • 创建有限状态机结构(FSM):FSM会根据收到的消息和当前的状态来触发状态转移,并执行提前设置的操作;同时Peer节点也有类似的FSM结构来管理消息响应;
  • 发送注册gRPC消息:利用创建好的gPRC连接向Peer发送自身的注册消息;
  • 消息处理循环:注册成功之后,等待接收来自Peer的消息以及自身的状态迁移(nextState)消息;

三、链码容器与Peer节点通信过程

  • 链码容器与Peer节点建立通信

    • 链码容器向Peer节点发送自己的注册信息ChaincodeMessage_REGISTER
    • Peer节点接收到之后注册到本地的一个Handle结构,返回ChaincodeMessage_REGISTERED消息给链码容器,状态更新为established
    • 链码容器收到之后,什么也不做,只把状态更新为established
    • Peer节点继续发送ChaincodeMessage_READY消息给链码容器,状态更新为READY
    • 链码容器收到之后,还是什么也不做,状态继续更新为READY
  • 链码容器初始化

    • Peer节点继续发送ChaincodeMessage_INIT消息给链码容器;
    • 链码容器收到之后,调用Handler.handleInit()方法进行初始化。主要是初始化所需的ChaincodeStub结构,调用链码代码中的Init()方法;
    • 链码容器初始化成功之后,返回ChaincodeMessage_COMPLETED消息给Peer节点。此时,链码容器进入可被调用(Invoke)状态;
  • 链码容器的Invoke()方法被Peer节点调用

    • Peer节点如果要调用链码,发送ChaincodeMessage_TRANSACTION消息给链码容器;
    • 链码容器收到,调用**Invoke()**方法,根据用户在Invoke()方法的具体实现逻辑,可以返回如下几类的响应消息给Peer节点:
      • 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节点收到消息,进行处理,并返回ChaincodeMessage_RESPONSR消息给链码容器;
    • 链码容器收到消息,返回ChaincodeMessage_COMPLETE消息给Peer节点,代表链码的一次Invoke()方法调用成功结束;
发布了622 篇原创文章 · 获赞 150 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/feizaoSYUACM/article/details/104974496