Hyperledger Fabric链码之三
在《Hyperledger Fabric链码之一》和《Hyperledger Fabric链码之二》中我们介绍了链码的定义,并通过dev网络测试了测试了自己编写的链码程序。
本文中我们站在区块链网络管理员的角度来阐述链码,我们集中在链码的声明周期管理,如链码的打包,安装,初始话以及升级。
链码声明周期
超级帐本Fabric提供的接口使得多种类型的节点能够进行交互 — 节点,排序节点以及成员管理服务 — 同时使得在背书节点上可以进行打包、安装、初始化和升级链码。
Hyperledger Fabric的SDKs对API接口进行了抽象以便于应用开发,用来管理链码的生命周期。此外Hyperledger Fabric的API可以通过CLI的方式直接访问,本文中我们使用了这种方式。
我们为链码的生命周期管理提供了4个命令 package
, install
, instantiate
, 以及 upgrade
。 以后版本中,我们计划添加stop
和start
交易来关闭和启动链码而不需要真正的卸载它。链码被成功安装和初始化后,链码会处于激活状态(running)并通过invoke
来处理交易。之后链码也可以被升级。
打包
链码的打包包含3个部分:
- 链码,被定义为
ChaincodeDeploymentSpec
或者CDS。 CDS根据代码以及名字和版本来定义链码包。 - 一个可选的初始化策略,语法构成上与背书
endorsement-policies
相同 - 一组签名,来自拥有该链码的实体
签名具有下面的目的: - 建立链码归属权
- 验证链码包的内容
- 防止链码包篡改
在一个channel中链码初始化交易的创建者会经过链码的初始化策略的验证。
创建链码包
有两种方式来打包链码。一种方式是:当一个链码有多个拥有者,因此需要链码包被多个身份进行签名。首先需要创建一个签名的链码包SignedCDS
,然后顺序传送给其他拥有者进行签名。
更简单的方式是: 当部署一个仅仅由一个节点签名的SignedCDS
时执行install
交易
我们首先解决最复杂的情况。但是,如果你不需要担心多个拥有者的情况,你可以直接跳到:ref:安装
章节。
使用下面的命令创建链码包
peer chaincode package -n mycc -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -v 0 -s -S -i "AND('OrgA.admin')" ccpack.out
其中, -s
选项创建了一个可以被多个拥有者签名的链码包,而不是简单的一个CDS。 当指定了-s
, 如果需要其他拥有者签名的话也必须指定-S
选项。否则,除了CDS以外,上述命令会创建一个仅包含初始化策略的SignedCDS
。
-S
选项用来指导链码包的签名过程,使用core.yaml
文件中localMspid
指定的MSP的值。 该选项是可选的。然而如果链码包创建没有使用签名,也就不能被别的拥有者使用signpackage
命令来进行签名。
选项-i
允许指定链码的初始化策略。初始化策略与背书策略具有相同的格式,用来指定什么身份可以来初始化链码。 在上面的例子中,仅仅OrgA的管理员能够初始化该链码。如果未提供初始化策略,会使用默认值,仅允许节点MSP的管理员身份来初始化链码。
链码包签名
被签名的链码包被创建后可以交给其他拥有者进行检查和签名。 工作流支持线下的链码包签名。
ChaincodeDeploymentSpec 被一组拥有者进行签名得到 SignedChaincodeDeploymentSpec或者SignedCDS
. SignedCDS
包含3个元素:
- CDS包含源码,名字以及链码的版本。
- 链码的初始化策略,描述为背书策略
- 链码拥有者列表,通过Endorsement来定义。
注意::背书策略是线下确定的,用来提供合适的MSP规则当链码在一些通道初始话的时候。如果未指定初始化策略,那么缺省策略是通道的任何MSP管理员。
每个拥有者背书ChaincodeDeploymentSpec
, 然后结合自己的身份(比如证书)后进行签名。
链码拥有者可以使用如下的命令对之前签名的链码包进行签名
peer chaincode signpackage ccpack.out signedccpack.out
其中, ccpack.out
和`signedccpack.out``分别是命令的输入和输出。 后者包含一个额外的本地MSP签名。
安装
install
交易将链码源码打包为一个指定的格式ChaincodeDeploymentSpec
(或者CDS),并安装到运行链码的节点上。
注意:链码必须安装在同一个通道的所有背书节点上。
当install
API输入参数仅是ChaincodeDeploymentSpec
时,会使用默认的初始化策略并包含一个空的拥有者列表。
注意: 链码应该仅安装在拥有者的背书节点上以保护链码逻辑的机密性,防止网络中其他成员的访问。那些没有链码的成员,不能作为链码交易的背书人;也就是说,他们不能执行链码。然而,他们仍然可以验证和提交交易。
为了安装链码,需要向lifecycle system chaincode
(LSCC), 在System Chaincode
章节描述,发送一个SignedProposal。例如,安装sacc
链码。
使用CLI的方式,安装命令如下:
peer chaincode install -n asset_mgmt -v 1.0 -p sacc
CLI内部会为sacc
创建SignedChaincodeDeploymentSpec
并且发送给本地的peer,节点调用LSCC的install
方法。-p
参数指定了链码的路径,必须在用户GOPATH
下,例如$GOPATH/src/sacc
。 CLI命令的完整描述参考CLI
章节。
值得注意的是为了在节点上安装链码,SignedProposal的签名必须来自peer本地MSP管理员。
初始化
instantiate
交易调用lifecycle System Chaincode
(LSCC)`创建并初始化通道中的链码。这是一个链码-通道绑定的过程:链码可以绑定到多个通道中,并独立运行在每一个通道中。也就是说,不管链码被安装并初始化到多少个通道中,通道状态都是隔离的。
instantiate
交易的创建者必须在SignedCDS中指定初始化策略,同时必须在通道中具有可写权限,在通道创建时配置。这些对于防止恶意实体部署链码并欺骗成员执行链码具有重要作用。
例如, 默认的初始化策略是通道MSP的任意管理员,因此链码初始化交易的创建者必须是一个通道管理员。当交易提议发送到背书节点,会使用背书策略验证创建者的签名。在交易提交到账本前的验证阶段会再一次进行验证。
初始化交易也会为通道中链码设置背书策略。背书策略描述的是需要多少个对交易结果的背书,交易才能被通道成员承认。
比如,使用CLI的方式来初始化sacc
链码,并用状态john
和0
来进行初始化,命令描述如下:
peer chaincode instantiate -n sacc -v 1.0 -c '{"Args":["john","0"]}' -P "OR ('Org1.member','Org2.member')"
注意:上面命令中背书策略(使用波兰表示法)表示需要Org1或者Org2中的任意成员对所有sacc
的所有交易进行背书。即,Org1或Org2必须对执行Invoke
的结果进行签名,交易才是有效交易。
交易成功初始化后,链码进入了激活状态,准备处理接收到的类型为ENDORSER_TRANSACTION的交易提议。 交易在背书节点上进行并行处理。
升级
链码可以通过改变版本号的方式来进行升级,版本号是SignedCDS的一部分。其他组成有拥有者、背书策略是可选的。然而,链码名必须是相同的,否则会被认为是完全不同的链码。
升级前,新版本的链码必须首先安装到背书节点上。升级交易与初始化交易类似,会将新版本的交易绑定到通道中。其他绑定旧版本的通道仍然运行旧版本。也就是说upgrade
交易一次只影响一个通道,即交易提交到的通道。
注意:既然链码多个版本可以同时运行,那么升级过程不会自动移除旧版本,因此用户需要自己进行处理。
与instantiate
细微的不同是:upgrade
交易会用当前链码的初始化策略进行检查,而不是新的策略。这样用来保证只有当前初始化策略指定的成员能够来升级链码。
注意:在升级阶段,链码Init
函数会被调用来升级数据或者重新初始化,因此当升级链码的时候需要格外小心防止重新设置状态。
停止和启动
stop
和start
交易现在还没有实现。然而,你可以通过手动删除每个背书节点上的链码容器和SignedCDS包来停止一个链码。注:你需要登入peer节点容器来删除CDS。我们提供一个工具脚本来执行这个操作。
docker rm -f <container id>
rm /var/hyperledger/production/chaincodes/<ccname>:<ccversion>
链码的停止将有助于在可控方式下进行升级,在链码升级前,将通道中所有节点上的链码进行停止。
CLI
注:我们需要平台相关的二进制可执行程序peer
. 现在,你可以简单的在运行的docker容器中使用此命令。
在fabric-peer
Docker容器中执行命令,如下
docker run -it hyperledger/fabric-peer bash
# peer chaincode --help
执行上面的命令会显示:
Usage:
peer chaincode [command]
Available Commands:
install Package the specified chaincode into a deployment spec and save it on the peer's path.
instantiate Deploy the specified chaincode to the network.
invoke Invoke the specified chaincode.
package Package the specified chaincode into a deployment spec.
query Query using the specified chaincode.
signpackage Sign the specified chaincode package
upgrade Upgrade chaincode.
Flags:
--cafile string Path to file containing PEM-encoded trusted certificate(s) for the ordering endpoint
-C, --chainID string The chain on which this command should be executed (default "testchainid")
-c, --ctor string Constructor message for the chaincode in JSON format (default "{}")
-E, --escc string The name of the endorsement system chaincode to be used for this chaincode
-l, --lang string Language the chaincode is written in (default "golang")
-n, --name string Name of the chaincode
-o, --orderer string Ordering service endpoint
-p, --path string Path to chaincode
-P, --policy string The endorsement policy associated to this chaincode
-t, --tid string Name of a custom ID generation algorithm (hashing and decoding) e.g. sha256base64
--tls Use TLS when communicating with the orderer endpoint
-u, --username string Username for chaincode operations when security is enabled
-v, --version string Version of the chaincode specified in install/instantiate/upgrade commands
-V, --vscc string The name of the verification system chaincode to be used for this chaincode
Global Flags:
--logging-level string Default logging level and overrides, see core.yaml for full syntax
--test.coverprofile string Done (default "coverage.cov")
Use "peer chaincode [command] --help" for more information about a command.
在脚本中运行,peer
命令在执行失败的时候会返回一个非零的错误码。
链码命令使用示例:
peer chaincode install -n mycc -v 0 -p path/to/my/chaincode/v0
peer chaincode instantiate -n mycc -v 0 -c '{"Args":["a", "b", "c"]} -C mychannel
peer chaincode install -n mycc -v 1 -p path/to/my/chaincode/v1
peer chaincode upgrade -n mycc -v 1 -c '{"Args":["d", "e", "f"]} -C mychannel
peer chaincode query -C mychannel -n mycc -c '{"Args":["query","e"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile $ORDERER_CA -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
系统链码
系统链码与链码具有相同的编程模型,不同的是,系统链码运行在peer进程中,而不是隔离的docker容器中。因此,系统链码被编译进了peer可执行程序中,生命周期与前面的不同。比如,系统链码没有install
,instantiate
和upgrade
。
系统链码的作用是降低节点和链码之间的gRPC通信开销,折中了管理的灵活性。例如,系统链码只能使用peer二进制程序来升级。也必须使用固定的参数来注册,不具有背书策略或者背书策略函数。
系统链码在Fabric中用来实现一些系统行为,可以进行合理的替换和修改。
当前提供的系统链码列表:
- LSCC生命周期系统链码用来处理声明周期请求
- CSCC配置系统链码在节点端用来处理通道配置
- QSCC请求系统链码 提供了账本请求的APIs,例如获取区块和交易。
- ESCC背书系统链码通过对交易提议响应进行签名来处理背书
- VSCC验证系统链码处理交易验证,包括检查背书策略和多版本并发控制。
在对系统链码进行修改和替换时需要格外的小心,尤其是LSCC,ESCC和VSCC,因为他们管理了整个交易的执行。值得注意的是在将交易提交到账本前VSCC来验证一个区块的有效性,通道中所有节点执行相同的验证以防止账本分叉(不确定)是至关重要的。因此需要格外关注VSCC的修改和替换。
------------------------------------------------------------------------------------完美的终结线--------------------------------------------------------------------------------------
Hyperledger Fabric链码之三的更多相关文章
- Hyperledger Fabric链码之一
什么是链码(Chaincode)? 我们知道区块链有3个发展阶段:区块链1.0,区块链2.0,区块链3.0.其中区块链2.0就是各种区块链平台百花齐放的阶段,区块链2.0最大的特点就是智能合约,我们接 ...
- Hyperledger fabric 链码篇GO(四)
Hyperledger fabric 链码篇GO(四) fabric中的链码也就是我们区块链所认知的智能合约,fabric中可由nodejs,java,go编写,本篇只针对GO语言编写链码.将详细介绍 ...
- Hyperledger Fabric链码之二
上篇文章中我们介绍了链码的概念,本文中我们将介绍Fabric下链码的编写和测试.我们会通过一个简单例子的方式来阐述链码API的使用. 链码API 每一个链码程序都必须实现一个接口Chainco ...
- HyperLedger Fabric部署与链码解读
1.Fabric简介 Fabric是超级账本中的一个项目,用以推进区块链技术.和其他区块链类似,它也有一个账本,使用智能合约,且是一个参与者可以分别管理自身交易的系统.它是一个联盟链.Fabric与其 ...
- Hyperledger Fabric:最简单的方式测试你的链码
一直以来,写完链码进行测试都要先搭建一个Fabric环境,然后安装链码进行测试,实际上Fabric提供了最为简单的方式可以允许我们对编写的应用链码进行功能测试,不需要搭建一个完整的Fabeic环境.而 ...
- Hyperledger Fabric(4)链码ChainCode
智能合约,是一个抽象的概念,智能合约的历史可以追溯到 1990s 年代.它是由尼克萨博(Nick Szabo)提出的理念,几乎与互联网同龄. 我们这里所说的智能合约只狭义的指区块链中.它能够部署和运行 ...
- Hyperledger Fabric 1.0 从零开始(十二)——fabric-sdk-java应用
Hyperledger Fabric 1.0 从零开始(十)--智能合约 Hyperledger Fabric 1.0 从零开始(十一)--CouchDB 上述两章,最近网上各路大神文章云集,方案多多 ...
- Hyperledger Fabric Model——超级账本组成模型
超级账本组成模型 本文主要讲述Hyperledger Fabric的关键设计特性,并细述如何实现了一个全面的.可定制的企业级区块链解决方案: 资产定义--资产这里理解为任何具有货币价值的东西,它们都可 ...
- 基于ubuntu16.04快速构建Hyperledger Fabric网络
前言 最近在参加一个比赛,使用到了区块链的开源软件hyperledger,由于之前从未接触过区块链,以及和区块链开发相关的内容,所有在网上查阅了大量的资料,并且通过学习yeasy(杨宝华)开源的入门书 ...
随机推荐
- SSH通过密钥登陆
A服务器上操作 ssh-keygen -t rsa/dsa 后面所带参数rsa/dsa为加密方式,默认为dsa [root@localhost ~]# ssh-keygen Generating pu ...
- MySQL数据库(五)使用pymysql对数据库进行增删改查
折腾好半天的数据库连接,由于之前未安装 pip ,而且自己用的python 版本为3.6. 只能用 pymysql 来连接数据库,(如果有和我一样未安装 pip 的朋友请 点这里http://blog ...
- java实现四则运算
http://blog.csdn.net/lip009/article/details/7768258 我之前找到的一个大神写的?还没看懂
- 2018年2月19日我的java学习(——)
在学完了类和对象的时候,开始对面向对象的思想有了一点认识,不过也不是完全的理解了. 就现在的学习状态来说,是非常的不错的,但是在学习的内容来说,我学的好像只是跟随这 站长的思路而已,也许是经验不足吧. ...
- noip第27课资料
- GC算法基础
寻找垃圾对象的算法:1. 引用计数(无法处理循环引用) 2. 根寻法(被广泛引用在gc算法中) 清理垃圾的算法: 1. 标记复制 2. 标记清理 3. 标记整理 分代算法的好处: 1. 分代处理, ...
- java实现wc.exe
Github地址:https://github.com/ztz1998/wc/tree/master 项目相关要求 实现一个统计程序,它能正确统计程序文件中的字符数.单词数.行数,以及还具备其他扩展功 ...
- C++面试基础之回调
回调函数技术广泛运用在动态库开发(或者类库)中,是使软件模块化的重要手段.回调函数可以看作是一种通知和实现机制,用于控制反转,即模块A调用模块B时,模块B完成一定任务后反过头来调用模块A.在被调用方代 ...
- 吴恩达机器学习笔记34-模型选择和交叉验证集(Model Selection and Train_Validation_Test Sets)
假设我们要在10 个不同次数的二项式模型之间进行选择: 显然越高次数的多项式模型越能够适应我们的训练数据集,但是适应训练数据集并不代表着能推广至一般情况,我们应该选择一个更能适应一般情况的模型.我们需 ...
- 第59节:Java中的html和css语言
欢迎到我的简书查看我的文集 前言: HTML 英文: HyperText Markup Language内容 html是超文本标记语言,是网页语言的基础知识,html是通过标签来定义的语言,所有代码都 ...