Hyperledger Fabric Transaction Proposal过程
客户端将交易预提案(Transaction Proposal)通过 gRPC 发送给支持 Endorser 角色的 Peer 进行背书。
这些交易提案可能包括链码的安装、实例化、升级、调用、查询;以及 Peer 节点加入和列出通道操作。
Peer 接收到请求后,会调用 core/endorser/endorser.go 中 Endorser 结构体 的ProcessProposal(ctx context.Context, signedProp *pb.SignedProposal) (*pb.ProposalResponse, error) 方法,进行具体的背书处理。
背书过程主要完成如下操作:
- 检查提案消息的合法性,以及相关的权限;
- 模拟执行提案:启动链码容器,对世界状态的最新版本进行临时快照,基于它执行链码,将结果记录在读写集中;
- 对提案内容和读写集合进行签名,并返回提案响应消息。
整体过程
主要过程如下图所示。

- 检查提案合法性;
- 调用 ValidateProposalMessage() 方法对签名的提案进行格式检查,主要包括:
- Channel 头部格式:是否合法头部类型,由 validateChannelHeader() 完成;
- 签名头格式:是否包括了 nonce 和creators 数据,由 validateSignatureHeader() 完成;
- 签名域:creator 证书 MSP 检查是否合法,签名是否正确,由 checkSignatureFromCreator() 完成。
- 如果是系统链码调用(SCC),检查是否是允许从外部调用的三种 SCC 之一:cscc、lscc、qscc 或 rscc;
- 如果 chainID 不为空,获取对应 chain 的账本结构,并检查 TxID 唯一性,确保同一交易未曾提交到账本结构中;
- 对于用户链码调用,需要检查 ACL:资源为
PROPOSE,默认策略是签名提案者在通道上拥有写权限(CHANNELWRITERS)。
- 调用 ValidateProposalMessage() 方法对签名的提案进行格式检查,主要包括:
- 模拟执行提案
- 如果 chainID 不为空,获取对应账本的交易模拟器(TxSimulator)和历史查询器(HistoryQueryExecutor),这两个结构将在后续执行链码时被使用。
- 如果 chainID 不为空,调用
simulateProposal()方法获取模拟执行的结果,检查返回的响应 response 的状态,若不小于错误 500 则创建并返回一个失败的 ProposalResponse。
- 对提案内容和读写集合进行签名
- chainID 非空情况下,调用 endorseProposal() 方法利用 ESCC,对之前得到的模拟执行的结果进行背书。返回 ProposalResponse,检查 simulateProposal 返回的response 的状态,若不小于错误阈值 400(被背书节点反对),返回 ProposalResponse 及链码错误 chaincodeError(endorseProposal 里有检查链码执行结果的状态,而 simulateProposal 没有检查)。
- 将 response.Payload 赋给 ProposalResponse.Response.Payload(因为 simulateProposal 返回的 response 里面包含链码调用的结果)。
- 返回响应消息 ProposalResponse。
simulateProposal 方法
simulateProposal 方法会通过执行链码逻辑来获取对状态的修改结果,并存放到读写集合中,主要过程如下:
- 从提案结构的载荷中提取 ChaincodeInvocationSpec 结构,其中包含了所调用链码(包括系统链码和用户链码)的路径、名称和版本,以及调用时传入的参数列表;
- 检查 ESCC 和 VSCC(尚未实现);
- 对用户链码,检查提案中的实例化策略跟账本上记录的该链码的实例化策略(安装链码时指定)是否一致。防止有人修改权限在其它通道非法实例化。
- 调用 callChaincode() 方法执行 Proposal,返回 Response 和 ChaincodeEvent。
- 调用
core.endorser包中SupportImpl.Execute()方法,该方法主要调用core.chaincode包中的ExecuteChaincode()方法,进一步调用包内的Execute()方法。调用过程中会把交易模拟器和历史查询器通过上下文结构体传入后续子方法。 Execute()方法会调用ChaincodeSupport.Launch()方法创建并启动链码容器。启动成功后创建链码 gRPC 消息,通过ChaincodeSupport.Execute()方法发送消息给 CC 容器,执行相关的合约,并返回执行响应(ChaincodeMessage 结构)。此过程中会将读写集记录到交易模拟器结构体中。
- 调用
- 对于非空 chainID(大部分跟账本相关的操作),执行 GetTxSimulationResults() 拿到执行结果
TxSimulationResults结构,从中可以解析出读写集数据。 - 最终返回链码标准数据结构 ChaincodeDefinition、响应消息 ChaincodeMessage、交易读写集 PubSimulationResults、链码事件 ChaincodeEvent。
endorseProposal 方法
主要过程如下:
- 获取被调用的链码指定的背书链码的名字。
- 通过 callChaincode() 实现对背书链码的调用,返回响应 response(对 ESCC 的调用同样也会产生 simulation results,但 ESCC 不能背书自己产生的simulation results,需要背书最初被调用的链码产生的 simulation results)。
- 检查 response.Status,是否大于等于 400(错误阈值),若是则把 response 赋给 proposalResponse.Response 并返回 proposalResponse。
- 将 response.Payload解码后(ProposalResponse类型)返回。
callChaincode 方法
主要过程如下:
- 判断交易模拟器,不为空则把它加入到Context的K-V存储中。
- 判断被call的cc是不是系统链码,创建CCContext(包含通道名、链码名、版本号、交易ID、是否 SCC、签名 Prop、Prop)
- 调用 core/chaincode/chaincodeexec.go 下的 ExecuteChaincode(),返回响应 response 和 事件ccevent。
- 返回 response和ccevent。
来源:https://github.com/yeasy/hyperledger_code_fabric/blob/master/process/chaincode_start.md
Hyperledger Fabric Transaction Proposal过程的更多相关文章
- Hyperledger Fabric Transaction Flow——事务处理流程
Transaction Flow 本文概述了在标准资产交换过程中发生的事务机制.这个场景包括两个客户,A和B,他们在购买和销售萝卜(产品).他们每个人在网络上都有一个peer,通过这个网络,他们发送自 ...
- Hyperledger Fabric Ordering Service过程
排序服务在超级账本 Fabric 网络中起到十分核心的作用.所有交易在发送给 Committer 进行验证接受之前,需要先经过排序服务进行全局排序. 在目前架构中,排序服务的功能被抽取出来,作为单独的 ...
- HyperLedger Fabric基于zookeeper和kafka集群配置解析
简述 在搭建HyperLedger Fabric环境的过程中,我们会用到一个configtx.yaml文件(可参考Hyperledger Fabric 1.0 从零开始(八)--Fabric多节点集群 ...
- Hyperledger Fabric 1.0 从零开始(十三)——orderer分布式方案
简述 在搭建HyperLedger Fabric环境的过程中,我们会用到一个configtx.yaml文件(可参考Hyperledger Fabric 1.0 从零开始(八)——Fabric多节点集群 ...
- Hyperledger Fabric Ledger——账本总账
Ledger Ledger(账本)即所有的state transitions(状态切换),是有序且不可篡改的.state transitions(状态切换)是由参与方提交的chaincode(智能合约 ...
- 深入解析Hyperledger Fabric启动的全过程
在这篇文章中,使用fabric-samples/first-network中的文件进行fabric网络(solo类型的网络)启动全过程的解析.如有错误欢迎批评指正. 至于Fabric网络的搭建这里不再 ...
- HyperLedger Fabric 1.0的Transaction处理流程
如果把区块链比作一个只能读写,不能删改的分布式数据库的话,那么事务和查询就是对这个数据库进行的最重要的操作.以比特币来说,我们通过钱包或者Blockchain.info进行区块链的查询操作,而转账行为 ...
- Fedora 25-64位操作系统中安装配置Hyperledger Fabric过程
安装过程参照Hyperledger Fabric的官方文档,文档地址:http://hyperledger-fabric.readthedocs.io/en/latest/prereqs.html 0 ...
- Hyperledger Fabric的test-network启动过程Bash源码详解
前言 在基于Debian搭建Hyperledger Fabric 2.4开发环境及运行简单案例中,我们已经完成了Fabric 2.4的环境搭建及fabric-samples/test-network官 ...
随机推荐
- 高级C/C++编译技术之读书笔记(五)之动态库版本控制
最近有幸阅读了<高级C/C++编译技术>深受启发,该书深入浅出地讲解了构建过程(编译.链接)中的各种细节,从多个角度展示了程序与库文件或代码的集成方法,提出了面向代码复用和系统集成的软件架 ...
- 拦截器springmvc防止表单重复提交【1】
[参考博客:http://www.cnblogs.com/hdwpdx/archive/2016/03/29/5333943.html] springmvc 用拦截器+token防止重复提交 首先,防 ...
- 转载FPGA学习之内嵌乘法器调用
补充一点,除法的时候如果直接a/b那么就会调用lpm模块,不管输入是否是常数,乘法的时候输入都是reg型变量会调用硬件乘法器,有一个是常数就会调用lpm模块. 上课的时候一直听老师说真正实践的时候你别 ...
- vba传递参数类型错误
先来看看微软官方的说明: 目录内容 概要 解决方案 详细信息 重现问题的步骤 &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; ...
- ArcGIS_Server的安装
1.双击ArcGIS_for_Server_Windows_103_142101.exe 2.下一步 3.关闭 4.Win10系统弹出询问框是否更改程序,点击“”是“” 5.开始安装程序,点击next ...
- RelativeLayout里的gravity不能居中的解决方法
最近在遇到RelativeLayout里的gravity属性给它复制center_horizontal或者center都不能居中它的子组件,后来找到了替代方法,只要在它的每个子组件里加上android ...
- XMemcached使用经历
XMemcached就是Memcached的java客户端之一,目前项目里用到了.据说它比起其他的java客户端从性能上要好一点,实现方式是NIO的.先看怎么实例化出来一个Memcached客户端吧: ...
- Java Integer和String内存存储
标签: java内存string 2016-01-10 12:51 1545人阅读 评论(2) 收藏 举报 分类: Java(7) 版权声明:本文为博主原创文章,未经博主允许不得转载. 先看代码: ...
- swift 学习-- 元组
//元组 //定义:元组是有多个值组合而成的复合值,其中的值可以是任意类型,而且每一个元素的类型可以是不同的 let http404Error = (404, "Not Found" ...
- linux文件系统命令和分区 挂载
文件系统命令df [选项][挂载点]选项:-a 显示所有的文件系统信息,包括特殊文件,如/proc,/sysfs-h 使用习惯单位显示容量,如KB,MB或GB等-T 显示文件系统类型-m 以MB为单位 ...