Chaincode 启动过程

简介

这里讲的 Chaincode 是用户链码(User Chaincode,UCC),对应用开发者来说十分重要,它提供了基于区块链分布式账本的状态处理逻辑,基于它可以开发出多种复杂的应用。

Hyperledger Fabric 中,Chaincode 默认运行在 Docker 容器中。Peer 通过调用 Docker API 来创建和启动 Chaincode 容器。Chaincode 容器启动后跟 Peer 之间创建 gRPC 连接,双方通过发送 ChaincodeMessage 来进行交互通信。Chaincode 容器利用 core.chaincode.shim 包提供的接口来向 Peer 发起请求。

典型结构

下面给出了链码的典型结构,用户只需要关注到 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(cc *grpc.ClientConn) 和 chaincodeSupportClient.Register(ctx context.Context, opts ...grpc.CallOption) 两个方法。

初始化完成后,创建有限状态机结构(FSM,github.com/looplab/fsm)。FSM 会根据收到的消息和当前状态来触发状态转移,并执行提前设置的操作。

Peer 侧也利用了类似的 FSM 结构来管理消息响应。

之后,利用创建好的 gRPC 连接开始向 Peer 发送第一个 gRPC 消息:ChaincodeMessage_REGISTER,将自身注册到 Peer 上。注册成功后开始消息处理循环,等待接收来自 Peer 的消息以及自身的状态迁移(nextState)消息。

后续过程中,Chaincode 和 Peer 利用 FSM 完成一系列对消息的响应运作,如下所示。

  • Peer 收到来自链码容器的 ChaincodeMessage_REGISTER 消息,将其注册到本地的一个 Handler 结构,返回 ChaincodeMessage_REGISTERED 消息发给链码容器。之后更新状态为 established ,并发送 ChaincodeMessage_READY 消息给链码侧,更新状态为 ready。
  • 链码侧收到 ChaincodeMessage_REGISTERED 消息后,不进行任何操作,注册成功。更新状态为 established。收到 ChaincodeMessage_READY 消息后更新状态为 ready。
  • Peer 侧发出 ChaincodeMessage_INIT 消息给链码容器,准备触发链码侧初始化操作。
  • 链码容器收到 ChaincodeMessage_INIT 消息,通过 Handler.handleInit() 方法进行进行初始化。主要包括初始化所需的 ChaincodeStub 结构,以及调用链码代码中的 Init() 方法。初始化成功后,返回 ChaincodeMessage_COMPLETED 消息给 Peer。此时,链码容器进入可被调用(Invoke)状态。
  • 链码被调用时,Peer 发出 ChaincodeMessage_TRANSACTION 消息给链码。
  • 链码收到 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 消息给对方,以确保彼此在线。

Hyperledger Chaincode启动过程的更多相关文章

  1. fabric网络环境启动过程详解

    这篇文章对fabric的网络环境启动过程进行讲解,也就是我们上节讲到的启动测试fabric网络环境时运行network_setup.sh这个文件的执行流程 fabric网络环境启动过程详解 上一节我们 ...

  2. Fabric1.4源码解析: 链码容器启动过程

    想写点东西记录一下最近看的一些Fabric源码,本文使用的是fabric1.4的版本,所以对于其他版本的fabric,内容可能会有所不同. 本文想针对Fabric中链码容器的启动过程进行源码的解析.这 ...

  3. Fabric1.4源码解析:Peer节点启动过程

    看一下Peer节点的启动过程,通常在Fabric网络中,Peer节点的启动方式有两种,通过Docker容器启动,或者是通过执行命令直接启动. 一般情况下,我们都是执行docker-compose -f ...

  4. zookeeper源码分析之一服务端启动过程

    zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...

  5. [原] KVM 虚拟化原理探究(2)— QEMU启动过程

    KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...

  6. Openfire的启动过程与session管理

    说明   本文源码基于Openfire4.0.2.   Openfire的启动       Openfire的启动过程非常的简单,通过一个入口初始化lib目录下的openfire.jar包,并启动一个 ...

  7. 探索 Linux 系统的启动过程

    引言 之所以想到写这些东西,那是因为我确实想让大家也和我一样,把 Linux 桌面系统打造成真真正正日常使用的工具,而不是安装之后试用几把再删掉.我是真的在日常生活和工作中都使用 Linux,比如在 ...

  8. Linux内核启动过程概述

    版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...

  9. SpringMVC启动过程详解(li)

    通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...

随机推荐

  1. iTunes文件共享

    在Info.plist文件中添加UIFileSharingEnabled键,并将键值设置为YES.将您希望共享的文件放在应用程序的Documents目录.

  2. call、apply、bind用法区别

    call call() 方法调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表). <p class="danger"> 注意:该方法的作用和 ...

  3. JavaScript 与 Java、PHP 的比较

    网站开发的实践从设计方面开始,包括客户端编程语言.大体上说,在网页设计中使用了三种语言:HTML,CSS和Java.自从网站发明以来,HTML和CSS已经成为网页设计的基础,但是Java被用于添加网站 ...

  4. springboot 自定义属性

    前言 spring boot使用application.properties默认了很多配置.但需要自己添加一些配置的时候,我们如何添加呢 1.添加自定义属性 在src/main/resources/a ...

  5. redis key设计技巧

    把表名转换为key前缀, 第二端放置表用于区分区key的字段–对应mysql中的主键的列名如userid. 3.放置主键值,如1,2,3,…..,a,b,c. 4.放要存储的列名 user表 user ...

  6. ORA-12154,TNS错误解决办法

  7. [Client] looks like we got no XML document in....

    无wsdl方式应用webservice时,服务端包含了 include_once'inc/utility_all.php '一直报[Client] looks like we got no XML d ...

  8. linux 下安装php扩展

    linux下安装php扩展 步骤: 1.在扩展解压包目录执行 phpize 2.执行 ./configure --with-php-config=/usr/local/php/bin/php-conf ...

  9. 高速PCB设计注意事项

    和SERDES应用相关的高速系统PCB设计注意事项如下: (1)微带(Microstrip)和带状线(Stripline)布线. 微带线是用电介质分隔的参考平面(GND或Vcc)的外层信号层上的布线, ...

  10. 关于.NET中的Session

    Asp.net 默认配置下,Session莫名丢失的原因及解决办法正常操作情况下Session会无故丢失.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成6 ...