Fabric 2.0 智能合约部署及升级

  • 张小雨
  • 更新于 2020-02-17 21:49
  • 阅读 5014

Fabric2.0 智能合约(链码)实践 - 智能合约安装、定义 及 如何升级

本系列文章如下: HyperLedger Fabric 2.0 测试网络部署 Fabric2.0 样例 first-network 生成配置说明 Fabric2.0启动网络脚本配置剖析 Fabric 2.0 创建通道与加入通道 Fabric 2.0 智能合约部署及升级 Fabric 2.0 实战 - 设置背书策略

1. Fabric 2.0 合约新特性

从Fabric 2.0开始,对链码的管理是完全分散(去中心化)的:多个组织可以使用Fabric链码生命周期来就链码的参数(例如链码认可策略)达成协议,然后再使用链码与分类帐进行交互。

新的智能合约在生命周期中提供了一些改进:

  • 多个组织必须同意链码的参数:

在Fabric的1.x版本中,一个组织可以为所有其他渠道成员设置链码的参数(例如,认可策略)。新的Fabric链码生命周期更加灵活,因为它既支持集中式信任模型(例如先前生命周期模型的模型),也支持分散模型,这些模型需要足够数量的组织才能在背书策略上生效。

  • 更安全的链码升级过程:

在先前的链码生命周期中,升级事务可能由单个组织发出,这给尚未安装新链码的渠道成员带来了风险。新模型仅在足够数量的组织批准升级后才允许升级链码。

  • 更容易的认可策略更新:

Fabric 生命周期允许您更改认可策略,而无需重新打包或重新安装链码。用户还可以利用新的默认策略,该策略需要频道中大多数成员的认可。在从渠道中添加或删除组织时,该策略会自动更新。

  • 可检查的链代码包:

Fabric 生命周期将链码打包在易于阅读的tar文件中。这使得检查链码包和协调跨多个组织的安装变得更加容易。

  • 使用一个程序包在通道上启动多个链码:

上一个生命周期使用安装链码包时指定的名称和版本定义了通道上的每个链码。现在,您可以使用单个 chaincode 程序包,并在相同或不同的通道上以不同的名称多次部署它。

2. 智能合约实践

智能合约的 lifecycle 实践主要分成以下4个部分

Fabric 2.0 合约

2.1 安装以及定义智能合约

2.1.1 打包合约

Fabric 2.0 的智能合约需要打包成一个.tar.gz压缩包。 打开控制台,执行 docker exec -it cli 进入cli容器

由于没接触过新的智能合约命令,我们先输入help,获取下帮助文档,控制台输入:

> peer lifecycle chaincode --help

peer lifecycle chaincode 命令定义说明:

#智能合约所有操作命令:
Perform chaincode operations: package|install|queryinstalled|getinstalledpackage|approveformyorg|checkcommitreadiness|commit|querycommitted

Usage:
  peer lifecycle chaincode [command]

Available Commands:
  approveformyorg      同意智能合约定义
  checkcommitreadiness  检查合约是否在通道上已经定义
  commit               提交合约定义到指定通道
  getinstalledpackage  从节点中获取已经安装的链码包
  install              部署链码
  package           打包链码
  querycommitted       查询节点上已提交的链码定义
  queryinstalled       查询节点已经安装的链码

由于要打包合约此处我们使用 peer lifecycle chaincode package, 在容器内部执行命令:

> peer lifecycle chaincode package mycc2.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label mycc_2

参数解释: mycc2.tar.gz :打包合约包文件名 --path :智能合约路径 --lang :智能合约语言 支持golang、node、java --label :智能合约标签,描述作用

执行完成后,查看当前目录,出现mycc2.tar.gz Fabric 2.0 合约 tar.gz

查看打包后的文件内容,主要包含:

(1).chaincode-Package-Metadata.json 文件,主要是定义合约的代码路径、合约语言以及合约标签

{ "path" : "github.com/hyperledger/fabric-samples/chaincode/abstore/go/",
"type":"golang",
"label":"mycc_2"}

(2)压缩的合约代码文件code.tar.gz,包含合约代码以及依赖包

2.1.2 部署合约到节点

继续在cli执行以下命令:

> peer lifecycle chaincode install mycc2.tar.gz

mycc2.tar.gz: 智能合约压缩包路径

控制台输出: Fabric 2.0 合约

验证合约安装是否安装到节点

> peer lifecycle chaincode queryinstalled

控制台输出:

Fabric 2.0 合约 验证安装到节点

在宿主机执行docker ps 发现目前合约容器还未启动。

2.1.3 当前组织同意合约定义

Fabric 2.0 智能合约由合约定义控制。当通道成员批准合约定义时,该批准作为组织对其接受的合约参数的投票。这些经过批准的组织定义允许通道成员在链码在通道上使用之前对链码达成一致。链码定义包括以下参数,这些参数需要在组织之间保持一致:

名称: 智能合约名称 版本: 与给定的合约包相关联的版本号或值。如果您升级了合约二进制文件,那么您也需要更改合约版本。 序列: 定义链码的次数。此值为整数,用于跟踪合约升级。例如,当您第一次安装并批准一个chaincode定义时,序列号将是1。下次升级合约时,序列号将增加到2。 背书策略: 哪些组织需要执行和验证事务输出。背书策略可以表示为传递给CLI或SDK的字符串,也可以在通道配置中引用策略。默认情况下,背书策略被设置为通道/应用程序/背书,这默认要求通道中的大多数组织对交易进行背书。 集合配置: 指向与您的chaincode关联的私有数据集合定义文件的路径。有关私有数据收集的更多信息,请参见私有数据体系结构参考。 初始化: 所有的链码需要包含一个初始化函数来初始化链码。默认情况下,这个函数永远不会执行。但是,您可以使用chaincode定义来请求Init函数是可调用的。如果请求执行Init,则fabric将确保在调用任何其他函数之前调用Init,并且只调用一次。 ESCC/VSCC插件: 自定义认证或验证插件的名称。

cli容器输入以下命令:

> peer lifecycle chaincode approveformyorg --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID channel2 --name mycc2 --version 1 --init-required --package-id mycc_2:33c137ade1dcc3dd383174a451549a1eda509336cf957dfb472854686d565b9e --sequence 1 --waitForEvent

命令选项说明如下:

--tls :是否启动tls --ca :ca证书路径 --channelID :智能合约安装通道 --name :合约名 --version :合约版本 --package-id queryinstalled :查询的合约ID --sequence :序列号 --waitForEvent :等待peer提交交易返回 --init-required :合约是否必须执行init

控制台日志: Fabric 2.0 合约 能看到通过orderer.example.com产生了一个交易

2.1.4 检查合约定义是否满足策略

Fabric 2.0 的智能合约的部署必须满足一定合约定义策略,策略的定义在通道配置中具体定义 控制台输入以下命令:

> peer lifecycle chaincode checkcommitreadiness --channelID channel2 --name mycc2–version 1 --sequence 1 --output json --init-required

输出以下结果,可以得知当前合约获取了Org1MSP的同意,参考2.1.3,而还没得到Org2MSP的定义 Fabric 2.0 合约

查看原本的lifecycle策略定义是满足过半数即可 Fabric 2.0 合约

现在明显不满足,我们还是执行commit合约看一下会怎么样 Fabric 2.0 合约 Error: transaction invalidated with status (ENDORSEMENT_POLICY_FAILURE) :不满足背书策略

这时候我们需要把Org2MSP也同意这个合约定义,切换环境变量为peer0.org2.example.com的配置

重复执行2.1.2 跟2.1.3操作后,再执行策略查询,可以看到两个都true了,满足策略。 Fabric 2.0 合约

2.1.5 提交合约

在满足合约定义的策略后,可以提交合约 控制台执行以下命令提交合约

> peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 1 --init-required

命令选项说明如下:

--tls :是否启动tls --ca :ca证书路径 --channelID :智能合约安装通道 --name :合约名 --version :合约版本 --package-id queryinstalled :查询的合约ID --sequence :序列号 --waitForEvent :等待peer提交交易返回 --init-required :合约是否必须执行init --peerAddresses :节点路径 --tlsRootCertFiles :节点ca根证书路径(--peerAddresses --tlsRootCertFiles 连用,可多个节点,多个节点即将合约部署到对应节点集合上)

控制台输出日志:

Fabric 2.0 合约 查看智能合约容器,此时合约容器已经启动 Fabric 2.0 合约

2.1.6 查看节点已提交合约

cli容器内输入以下命令

> peer lifecycle chaincode querycommitted --channelID mychannel --name mycc

控制台输出合约具体信息如下: Fabric 2.0 合约

2.1.7 操作合约

Fabric 2.0 智能合约操作主要有invokequery, 此处与1.x完全一致

初始化合约,执行init方法,设置a:100, b:100

> peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --isInit -c '{"Args":["Init","a","100","b","100"]}'

控制台输出: Fabric 2.0 合约

查询a的余额:

> peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

输出值为100。

3. 智能合约升级

3.1 查看需要升级的智能合约信息

还是先在控制台输入 docker exec -it cli bash 进入cli的控制台,默认cli的环境变量节点为peer0.org1.example.com.

目前已部署一个智能合约到peer0.org1.example.com,cli控制台输入命令:

> peer lifecycle chaincode queryinstalled

查看mycc合约的package_id如下: Fabric 2.0 合约

查看mycc合约在mychannel通道的合约定义,cli控制台输入命令:

> peer lifecycle chaincode querycommitted -C mychannel

可以看到mycc合约具体信息: Fabric 2.0 合约

参数 中文描述
Name 合约名称 mycc
Version 合约版本 1
Sequence 合约序列号(升级1次,加1) 1
Endorsement Plugin 背书插件 escc
Validation Plugin 校验插件 vscc

执行一次query操作方便后面对比:

> peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'

此时控制台输出a的值为90: Fabric 2.0 合约

3.2 修改合约代码

假如本地不存在该合约代码,2.0提供从节点上获取代码包的操作 控制台输入以下命令:

> peer lifecycle chaincode getinstalledpackage --package-id  mycc_1:00ef9e95ea103b2c27eacd5a62efd9b34863c672d236a1ce99a7d539b2f9ef7a

packge-id:使用1步骤中查询获取的合约 packge_id

当前目录出现mycc.tar.gz包为合约包,解压合约包里面的code.tar,编辑合约代码 添加一个方法默认加10: Fabric 2.0 合约

Fabric 2.0 合约

3.3 重新打包合约

控制台输入以下命令打包合约:

> peer lifecycle chaincode package mycc.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label mycc_1

将根据新的合约代码打包成新的智能合约包mycc.tar.gz

3.4 重新安装合约

更新合约代码需要重新将合约安装到节点上:

> peer lifecycle chaincode install mycc.tar.gz

控制台输出合约安装信息:

Fabric 2.0 合约

此时我们再查询一下节点安装合约信息,控制台输入:

> peer lifecycle chaincode queryinstalled

控制台输出: Fabric 2.0 合约

可以看到新增了一个package_id不一样的mycc合约,原来的还在。

3.5 修改合约定义

真正升级的操作其实是在合约定义这一步骤,控制台输入以下命令,与原来相比将package_id修改为新安装的合约package_id,sequence要改成2,因为install了2次

> peer lifecycle chaincode approveformyorg --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name mycc --version 1 --init-required --package-id  mycc_1:2f358faa3475e5c37a90be9a7c0db2f608ecb09b13f64b001f83799be9fccc77 --sequence 2 --waitForEvent

Fabric 2.0 合约

检查approve状态,控制台输入:

> peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name mycc --version 1 --sequence 2 --output json --init-required 

sequence要改成2,因为install了2次,否则报错Error: query failed with status: 500 - failed to invoke backing implementation of 'CheckCommitReadiness': requested sequence is 1, but new definition must be sequence 2

3.6 切换节点

环境变量切换peer0.org2.example.com重复3.3,3.4,3.5步,知道出现以下结果: Fabric 2.0 合约切换节点

3.7 重新提交合约定义

完成智能合约lifecycle策略后,重新提交合约定义:

> peer lifecycle chaincode commit -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --channelID mychannel --name mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt --version 1 --sequence 2 --init-required

注意序列号sequence

控制台输出以下结果:

Fabric 2.0 合约

此时通过新的智能合约查询a的值,还是为90

Fabric 2.0 合约

3.8 检验新合约代码

刚刚添加了addTen这个方法,理论上a应该加10等于100 控制台输入以下命令调用addTen

> peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt  -c  '{"Args":["addTen","a"]}'  

查看结果a果然为100 升级成功

Fabric 2.0 合约升级

4. 总结

Fabric 2.0 的智能合约合约安装部署过程做了很多的修改,首先是合约打包,合约打包更方便了,打包一次,部署多次,从安全性上,合约定义的同意策略控制极大提高了合约的合规性。并且提供了更安全的链码共识升级方案。 虽然步骤麻烦,但是总体来说 Fabric 2.0 智能合约的改动还是比较认可。

转载自: https://me.csdn.net/qq_28540443

点赞 2
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

1 条评论

请先 登录 后评论
张小雨
张小雨
攻坚联盟链