Hyperledger-Fabric 区块链

Hyperledger-Fabric安装开发部署(六)智能合约的安装与更新

简介

  • 之前虽然介绍了智能合约,但是并没有说明如何更新部署;在实际运用中我们的合约代码必然涉及到升级更新,甚至完全废弃更换新的合约代码;很有必要在这里讲述一下在NodeSDK下如何实现这些。
  • 如果接触过以太坊会知道在以太坊中这是一件非常烦的事情,但是在Fabric中变的非常简单,且容易理解。不过Fabric的更新合约的功能也是在1.0.0加入的。
  • 此篇所需要的开发环境与Hyperledger-Fabric安装开发部署(四)NodeJs-SDKHyperledger-Fabric安装开发部署(五)NodeJs-SDK详解相同。

官方英文版教程:
http://hyperledger-fabric.readthedocs.io/en/latest/index.html


1.撰写新的合约

按照e2e的模型我们写一个简单的合约如下:

将以上内容保存至D:\....\balance-transfer\artifacts\src\github.com\newmycc\e2eTestcc_01.go

在之前e2e的智能合约中只能再初始化的时候加入a,b并不能加入更多的key;上述合约加入了一个Create(),保留了Move()与Query();我们可以加入更多的c,d,e….

至于Go版的智能合约如何脱离Fabric进行调试、编译、测试等,后续会在新的文章中介绍。

2.安装智能合约

2.1 现有的智能合约

使用vscode运行balance-transfer,使用post工具(本文使用Restlet Client)调用查询已安装的智能合约

可以看到目前在peer1上已安装的合约只有一个“name: mycc, version: 1.0”
将上图中的type参数改为instantiated再次查询;
得到的结果是一样的,这个表示已经初始化的智能合约
以上查询在后续我们还要用到,需要保留对应post脚本。

注:本次操作使用org1上的用户,如无特别说明,均默认org1用户。

2.2 安装智能合约

调用如下接口:

给peer1、与peer2上同时安装新的合约,并提示操作成功。

先分析一下nodejs的代码:
对照/app/install-chaincode.js

这里只是收集一些信息交给SDK中client.installChaincode()做处理,installChaincode()介绍: 官方SDK说明

操作完成后,我们再次调用刚才使用的查询已安装的智能合约接口,会得到如下的结果:

可以看到我们的newmycc1已经成功安装,但是在Fabric中智能合约的安装成功并不代表这份合约可以被使用,必须要初始化之后才可以使用;可以使用刚才介绍的已经初始化的智能合约接口,newmycc1并不会出现在列表中。
安装仅仅是上传代码文件、创建链码的名称与版本信息,甚至不会再这一步编译Go文件。

2.3 初始化智能合约

使用如下接口初始化刚才安装的智能合约:

能看到我这里使用了52.21s,这个操作相对比较耗时,就会有超时的情况出现,需要在”/app/instantiate-chaincode.js”中修改默认超时时间:

详细说明可以参阅sendInstantiateProposal()的官方SDK文档官方SDK文档

在初始化成功后,在服务器上会出现两个新的docker容器,对应了我们的两个节点,每个节点上的链码独立运行:

初始化的时候主要是将指定的智能合约进行如下操作:
1. 检测编译
2. 建立docker容器
3. docker内实例化链码
4. 执行初始化方法(可以理解为构造函数)


接下来进行验证;再次调用已初始化的智能合约接口来查询,结果如下:

初始化的时候有一个参数是“args”:[“c”,”10″]
那么调用上一篇所使用的查询接口查询c的值试试:

然而没有查询到c对应的值,这是因为:
这次查询使用的智能合约是mycc,并不是我们新建的newmycc1;不同的链码之间数据也是隔离的。

了解这一点后,将mycc修改为newmycc1,再试一次:

至此,说明新的合约已经完全生效,再试试新合约中Create():

也是可以正常调通的,在使用上边的查询验证d的值,出现如下的结果说明新的合约以及新的方法均没有问题。
d now has 100 after the move

3.更新智能合约

有了代码的安装那么必然会有代码的升级,在我们安装和初始化的过程中都有一个版本号“chaincodeVersion”:”v1″,但是在使用的时候没有提交版本号的参数,就是说:更新链码的版本不会涉及到外部调用的修改,每次调用智能合约均会使用最新的版本。

首先对新的合约做少许修改,在e2eTestcc_01.go中做如下修改

3.1 更新智能合约-安装

这一步需要使用2.2 安装智能合约中的安装方法,区别只是将”v1″修改为”v2″,合约文件已经修改完毕,目录也没有变化无需修改。

提示安装成功后,可以继续使用刚才提到的查询方法,验证是否已经安装成功。如下图可以看到多出来一个v2的版本。

3.2 更新智能合约-更新

在balance-transfer项目中目前并没有关于更新的接口,但是在SDK中是存在的,只不过没有实现而已。

新建/app/upgrade-chaincode.js文件,将以下内容复制:

在app.js中加入如下代码:

调用新写的这个接口:

在这里只更新了peer1的链码,并没有更新peer2,只样做会导致peer2的对应链码无法使用,目前经过实测发现:
在peer1上安装合约A.V2,并且在peer1执行更新,这样操作对于peer1没有任何影响,正常调用新版本V2;但是当调用同一个org下的peer2的链码,会提示找不到A.V2,类似如下错误:
cannot retrieve package for chaincode newmycc1/v4, error open /var/hyperledger/production/chaincodes/newmycc1.v4: no such file or directory after the move
可是我们并没有在peer2上进行任何关于链码A.V2的操作;而且查询peer2上已经初始化的智能合约会发现,它的版本被A.V2覆盖了,不过在peer2上已安装的智能合约却不包含A.V2,这也就导致合约A在peer2下无法调用了。
尚不清楚这是Fabric就如此设计(同org下不同peer必须使用同版本的链码?)还是在node-SDK或者Fabric本身的BUG。


可以继续使用前文提到的各种查询验证此次更新合约是否成功;需要提醒的是再合约的更新中,也会执行Go中的构造函数,例如图中就将c值修改为88,可以利用查询验证c的值确实被修改为88。

4.总结

  1. 智能合约的安装:安装->初始化;
  2. 智能合约的更新:安装->更新;
  3. 链码不同的版本、安装不同的peer都会独立创建各自的docker images与docker container,均独立运行;
  4. 当服务器重启后,docker中智能合约的容器无需手动启动,会在调用的时候自行开启;
  5. 不同的智能合约数据独立存储

.
.
.
.
.
.
.
【本文章出自NM1024.com,转载请注明作者出处。】

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据