Hyperledger Chaincode启动过程
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启动过程的更多相关文章
- fabric网络环境启动过程详解
这篇文章对fabric的网络环境启动过程进行讲解,也就是我们上节讲到的启动测试fabric网络环境时运行network_setup.sh这个文件的执行流程 fabric网络环境启动过程详解 上一节我们 ...
- Fabric1.4源码解析: 链码容器启动过程
想写点东西记录一下最近看的一些Fabric源码,本文使用的是fabric1.4的版本,所以对于其他版本的fabric,内容可能会有所不同. 本文想针对Fabric中链码容器的启动过程进行源码的解析.这 ...
- Fabric1.4源码解析:Peer节点启动过程
看一下Peer节点的启动过程,通常在Fabric网络中,Peer节点的启动方式有两种,通过Docker容器启动,或者是通过执行命令直接启动. 一般情况下,我们都是执行docker-compose -f ...
- zookeeper源码分析之一服务端启动过程
zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...
- [原] KVM 虚拟化原理探究(2)— QEMU启动过程
KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...
- Openfire的启动过程与session管理
说明 本文源码基于Openfire4.0.2. Openfire的启动 Openfire的启动过程非常的简单,通过一个入口初始化lib目录下的openfire.jar包,并启动一个 ...
- 探索 Linux 系统的启动过程
引言 之所以想到写这些东西,那是因为我确实想让大家也和我一样,把 Linux 桌面系统打造成真真正正日常使用的工具,而不是安装之后试用几把再删掉.我是真的在日常生活和工作中都使用 Linux,比如在 ...
- Linux内核启动过程概述
版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...
- SpringMVC启动过程详解(li)
通过对SpringMVC启动过程的深入研究,期望掌握Java Web容器启动过程:掌握SpringMVC启动过程:了解SpringMVC的配置文件如何配置,为什么要这样配置:掌握SpringMVC是如 ...
随机推荐
- HihoCoder 1053 居民迁移
居民迁移 时间限制:3000ms 单点时限:1000ms 内存限制:256MB 描述 公元2411年,人类开始在地球以外的行星建立居住点.在第1326号殖民星上,N个居住点分布在一条直线上.为了方便描 ...
- 关于JS浅拷贝和深拷贝
在 JS 中有一些基本类型像是Number.String.Boolean,而对象就是像这样的东西{ name: 'Larry', skill: 'Node.js' },对象跟基本类型最大的不同就在于他 ...
- 提示“load System.Core failed”
Could not load file or assembly 'System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec8 ...
- Java开发前期准备工作
配置Java开发环境变量 在"系统变量"中设置3项属性,JAVA_HOME, PATH, CLASSPATH. 变量设置参数如下: 变量名:JAVA_HOME 变量值:C:\Pro ...
- ClassLoader热加载的简单实现
当我们在eclipse中修改了一个.java文件时,并通过[ctrl + s ]保存了此java文件,相应的bin目录中,会发现.class文件也发生了修改.通常情况下,java文件是在我们的web项 ...
- AppCan使用注意问题
1.文件上传的时候尽量使用uexUploadMsg,然后注意文件名,文件名一定要正确才能传上去.
- android httpclient 设置超时
3.X是这样的 HttpClient httpClient=new DefaultHttpClient();4.3是这样的CloseableHttpClient httpClient = HttpCl ...
- 杂项-公司-百科:华特·迪士尼-un
ylbtech-杂项-公司-百科:华特·迪士尼 华特·迪士尼(Walt Disney,全名Walter Elias Disney,又译沃尔特·迪士尼,1901年12月5日—1966年12月15日),出 ...
- python学习(七) 更加抽象
python是面向对象的语言. 7.1 对象的魔力 7.1.1 多态 不管是字符串还是列表,count()函数都可以正常工作. >>> ['ab','b','c'].count('c ...
- 从零开始搭建包含多个子系统的Vue工程项目
本文以windows为例,介绍支持多个子系统的Vue工程项目的搭建过程,相对于单一系统的工程,多个子系统引入了如下一些问题: 项目目录结构设计 打包结果设计:每个子系统可以独立发布上线 多布局实现:多 ...