区块链 | Hyperledger Fabric 04 超详细图解——智能合约的部署、调用与升级

2022年6月22日 271点热度 0人点赞 0条评论

导读



超级账本,作为最火热的联盟链技术,得到了广泛地使用,也得到了很多科研人员的青睐。

今天这篇文章,我们一起来部署智能合约,从一个案例中,学习部署过程、调用过程,更新过程。我们也针对安装过程中出现的一些问题做了详细的说明,并提供解决方案。

让我们一起走进文章,来感受Fabric并深入理解联盟链吧!

图片


1

说在前面的话


1、说点题外话


距离上次更新,已经很久过去一个学期多的时间了。因为,突然临时换了研究方向,将大量的经历放在了新方向的奠基上。

好像自己陷入了学习数学的方法的困境——总想把一切都搞懂,总想想明白一切原委!

最近也有在看《毛泽东选集》,在看教员的故事。其实很早就在看了,只不过,这个学期养成了每天必看的习惯。在教员的身上,看到了奋斗的力量,看到了思想的力量!也在尝试将这些思想和精神,一点点融入到自己的科研中。理论联系实际,不是空话,不是说说而已,但是真正用马克思主义,用毛泽东思想去改进自己,去完善自己,确实不是那么太容易的事情。是心志不坚,是压力不大。是自己身上的小毛病在作祟!是因为自己身上还是缺乏一个真正的无产阶级该有的一些正确的精神,是因为自己身上还是充斥着一个无产者不该有的错误的缺点。

学期末,杂事基本结束,基础技术总结继续。一点一点改进自己的缺点,一点一点完善自己。

只愿你,能和我一起!

2、环境测试

1、区块链环境测试

在今天的内容之前,我们还是要先测试一下我们的环境,方便后续的学习。我们检查测试网络是否存在:

./network.sh up createChannel

图片

上面这个命令是开启网络并同时创建通道。

创建完成后,我们部署链码:

./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

图片

如果没有问题,那就说明我们的环境基本正常,大家也可以看上一篇文章做更加深入的测试:

图片

区块链 | Hyperledger Fabric 03 超详细图解——通过Fabric测试网络深入理解联盟链

确认没问题后,就可以关闭网络了:

./network.sh down

图片

2、网络环境测试

我们要确保系统是联网的,成功连接的前提是有连接的标志,比如:

图片

最简单的方法是打开系统自带的火狐浏览器,然后打开网页测试:

图片

也可以使用命令行(显得更专业吧)!

图片

如果网络连接有问题,就要解决,我们需要考虑我们的Ubuntu系统是独立系统,还是安装在虚拟机中的。更多的问题,可能是出现在虚拟机中,可能的原因有如下:

1、首先确保网络没有问题。网络出现问题,(1)有可能是网本身连不上;(2)有可能是电脑的网卡驱动出现问题;(3)某些网络不支持虚拟机,如锐捷,上网有解决方案;2、网络没问题,要配置好虚拟机的网络,一般选择NAT3、Ubuntu的配置问题(1)检查NetworkManager.state(2)检查NetworkManager.conf

关于后两点,具体如下:

首先关闭网络管理:

sudo service network-manager stop

然后使用如下命令打开NetworkManager.state:

sudo gedit /var/lib/NetworkManager/NetworkManager.state

将所有的都改为true:

图片

同理,打开NetworkManager.conf:

sudo gedit /etc/NetworkManager/NetworkManager.conf

将其中的managed=false改为managed=true:

图片

然后我们启动:

sudo service network-manager start

或者重启:

sudo service network-manager restart

网络问题可能的原因有很多,我们只能对症下药,但是大多数都是上面的几种情况,有出现其他问题解决不了,我们可以一起交流。

测试完成后,确保都没问题后,我们就可以学习今天的内容啦!

2

启动与配置


1、简述

终端用户和区块链进行交互,本质上是终端用户调用智能合约。智能合约是在区块链2.0——以太坊中得到了发扬。但智能合约早在1995年就由Nick Szabo提出。

Hyperledger Fabric 中,智能合约被部署在链码(Chaincode)中,想要验证交易或者查询账本的组织需要在其对等节点中下载链码。对等节点要加入到通道中,安装完成后,通道中的成就就可以将链码部署到通道中,并使用链码中的智能合约来创建或更新通道账本中的资产。

有关于更详细的链码和智能合约的知识,可以看下面这篇文章:

图片

区块链 | 智能合约

使用Fabric链码生命周期进程将链码部署到通道中。Fabric链码生命周期允许多个组织在链码用于创建交易之前就如何操作达成共识。例如,背书策略指定哪些组织需要执行链码来验证交易,而通道成员需要使用Fabric链码生命周期来就链码背书策略达成一致。
接下来,让我们开始学习如何部署吧。

2、启动网络

经过前面的测试,没有问题,我们就可以启动网络了:
./network.sh up createChannel

创建完成如下:

图片


这个时候,我们要留意我们创建的网络名称:

图片

3、设置Logspout

首先要说明的是,这个操作不是必须的,如果大家仅仅是学习简单的开发与应用,可以跳过。

为了监控智能合约的日志,管理员可以使用logspout工具查看来自一组Docker容器的聚合输出。该工具将输出流从不同的Docker容器收集到一个地方,从而轻松查看单个窗口发生了什么。这可以帮助管理员在调用智能合约时安装智能合约或开发人员时调试问题。由于某些容器的创建纯粹是为了启动智能合约,并且仅在短时间内存在,因此从网络中收集所有日志是有帮助的。

我们打开test-network文件夹(不确定路径看下图),会发现有这个文件的存在:

图片

如果这个文件夹下没有,我们可以打开如下路径:

~/HyperledgerFabric2.3/fabric/scripts/fabric-samples/commercial-paper/organization/digibank/configuration/cli

具体的大家跟我会有一定的差别,去fabric-samples文件夹下面按照路径寻找即可。

如果还是没有,可以直接使用如下的命令去查找:

find . -name monitordocker.sh

在根目录打开终端,然后输入上面的命令,就可以找到啦

图片

monitordocker.sh这个文件是用于安装和配置logSpout的脚本,我们可以直接使用。LogSpout工具会将连续将日志输出到终端,方便起见,我们在该文件夹下创建一个新的终端窗口。

图片

然后再第二个终端(新创建的终端)启动:

./monitordocker.sh fabric_test

这里的网络是我们前面创建的网络:

图片

执行结果如下:

图片

刚开始,不会看到任何日志,后续部署的过程中,会有显示。

3

链码部署


做完了上面的,我们就可以正式开始了。我们的部署包括如下四个阶段:


打包智能合约安装链码包批准链码定义提交链码定义到通道

1、打包智能合约


我们使用go语言作为示例讲解,首先使用如下命令定位到go文件夹:

cd ../chaincode/fabcar/go

图片

然后我们需要检查一下依赖项文件:
cat go.mod

图片

然后我们打开go文件夹下的fabcar.go文件:

图片

首先我们能够看到使用contract API定义SmartContract类型:

图片

然后,使用SmartContract类型为智能合约中定义的函数创建交易环境,这些函数将数据读写到区块链账本。
我们需要在go文件夹下执行如下命令,安装智能合约依赖项:
GO111MODULE=on go mod vendor
执行成功界面如下:

图片

在go文件夹中会发现一个新的vendor文件夹:

图片

接下来,我们回到test-network文件夹下:
cd ../../../test-network
我们可以使用对等节点CLI以所需的格式创建链码包。对等节点的二进制文件位于fabric-samples库的bin文件夹中。使用如下的命令,将这些二进制文件添加到我们的CLI路径中:
export PATH=${PWD}/../bin:$PATH
我们也需要设置FABRIC_CFG_PATH指向中fabric-samples的core.yaml。
export FABRIC_CFG_PATH=$PWD/../config/
上面几步操作如下:

图片

为了确保我们能够使用对等节点CLI,我们需要检查二进制的版本,需要2.0.0或者更新的版本:
peer version

图片

确认没问题之后,就可以使用如下命令创建链码包:
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1
我们先来做一下解释:
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1
我们使用peer lifecycle chaincode package命令创建了一个包,命名为:fabcar.tar.gz。使用 --path 标记设置智能合约代码的来源位置是我们前面讲到的go文件夹(../chaincode/fabcar/go/)。使用--lang 标记指定我们的链码的编程语言是golang。使用--label 标签指定链码标签是fabcar_1,用于识别安装后的链码的身份。
执行完成后,我们就能在test-network文件夹下,看到我们打包好的链码:

图片

2、安装链码包

在我们打包了Fabcar智能合约之后,我们可以在我们的对等节点上安装链码。链码需要安装在每一个将支持交易的对等节点。因为我们要设定背书策略,要求Org1和Org2都背书,所以我们需要在两个组织操作的对等节点上安装链码
peer0.org1.example.compeer0.org2.example.com

我们依次在Org1和Org2安装链码,首先在Org1中安装,设置如下环境变量:

export CORE_PEER_TLS_ENABLED=trueexport CORE_PEER_LOCALMSPID="Org1MSP"export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crtexport CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/mspexport CORE_PEER_ADDRESS=localhost:7051

其中,第三条命令和和第四条命令表明指向了Org1。

图片

然后我们执行安装过程:

peer lifecycle chaincode install fabcar.tar.gz

图片

同理,使用如下命令将链码安装到Org2:

export CORE_PEER_LOCALMSPID="Org2MSP"export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crtexport CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/mspexport CORE_PEER_ADDRESS=localhost:9051peer lifecycle chaincode install fabcar.tar.gz

图片

特别说明一下,我们前面有安装工具logSpout来监控智能合约日志,我们可以在我们创建的另一个终端查看安装过程:

图片


3、批准链码定义


安装完成后,我们就可以批准链码定义了。链码定义包括一些链码管理的重要参数,如名称,版本,背书策略等。

在部署链码钱,通道成员集合需要批准链码,通道成员由

Application/Channel/lifeycleEndorsement

策略进行管理。这个策略默认需要链码在加入通道前得到大多数通道成员的批准,而在本案例中,两个组织,大多数就是2,因此,Org1和Org2都需要批准Fabcar的链码定义。

如果一个组织已经在他们的对等节点上安装了链码,他们需要在他们的组织批准的链码定义中包括packageID。packageID用于将安装在对等节点上的链码与经过批准的链码定义相关联,并允许组织使用链码来支持交易

可以通过如下命令查询对等体信息来查找链码对应的packageID

peer lifecycle chaincode queryinstalled

packageID是链码标签和链码二进制的哈希值的组合。每个对等节点都会生成相同的packageID。输出如下:

图片


我们将在批准链码时使用包ID,为方便后续使用,我们将其保存为一个环境变量。
export CC_PACKAGE_ID=fabcar_1:1146b4b491871bf18b23dd67dd8cc058655b36cc0e2274f165ed06b796a8f27

因为环境变量已经被设置为作为Org2管理员来操作对等的CLI,所以我们可以批准将Fabcar定义为Org2的链码。链码在组织层面得到批准,因此该命令只需要针对一个对等节点。这种批准会通过闲谈传播给组织内的其他成员。使用如下命令批准链码定义:

peer lifecycle chaincode approveformyorg

具体的命令为:

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

同样,我们用更方便的格式来讲解:

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

前六行不必说,比较简单,第七行--package-id用于在链码定义中包含包的标识符。--sequence参数是一个整数,用于跟踪链码被定义或更新的次数,最初为1,升级后会变为2。

执行结果如下:

图片


同时我们也能看到logSpout的监控画面。

图片


我们可以为approveformyorg命令提供--signature-policy或--channel-config-policy参数来指定链码背书策略。背书策略指定了需要多少个属于不同通道成员的对等节点对给定的链码验证交易。如果不设置,即采用默认的背书策略:提交交易时,由大多数通道成员认可。如果新增或者删除组织,背书策略也会自动更新,以满足“大多数”的需要。

我们也需要批准具有管理员角色的标识的链码的定义。因此,CORE_PEER_MSPCONFIGPATH变量需要指向包含管理标识的MSP文件夹。要注意的是,我们不能使用客户端用户来批准链码定义,批准需要提交给排序服务,排序服务验证管理签名并将批准发送给对等节点。

我们仍然需要批准链码定义为Org1。设置以下环境变量,以Org1管理员身份操作:

export CORE_PEER_LOCALMSPID="Org1MSP"export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/mspexport CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crtexport CORE_PEER_ADDRESS=localhost:7051

然后就是批准链码定义为Org1:

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

我们现在有了大多数需要部署的Fabcar链码到通道。虽然只有大多数组织需要批准链码定义(使用默认策略),但所有组织都需要批准链码定义,以便在他们的对等节点上启动链码。如果在通道成员批准链码之前提交定义,组织将无法认可事务。因此,建议所有通道成员在提交链码定义之前批准链码。

4、提交链码定义到通道


在有足够多的组织批准链码定义后,一个组织可以将链码定义提交给该通道。如果大多数通道成员都同意该定义,提交事务将成功,并且链码定义中同意的参数将在通道上实现。
可以使用如下命令检查各通道成员是否批准了相同的链码定义:
peer lifecycle chaincode checkcommitreadiness
完整的命令为:
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json
执行结果如下:

图片

由于作为通道成员的两个组织都批准了相同的参数,因此链码定义可以提交给通道。可以使用如下命令将链码定义提交给该通道。commit命令也需要由组织管理员提交。
peer lifecycle chaincode commit
完整命令为:
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
执行结果如下:

图片

可以使用如下命令确认链码定义已经提交给该通道:
peer lifecycle chaincode querycommitted
完整命令为:
peer lifecycle chaincode querycommitted --channelID mychannel --name fabcar --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
执行结果如下:

图片

我们将结果复制出来方便大家看:
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]

4

后续操作



部署完成后,我们还有一些后续的操作需要执行,包括调用升级清理

1、调用链码


在链码定义被提交到一个通道后,链码将从连接到安装链码的通道的对等节点开始。现在,客户端应用程序可以调用Fabcar链代码了。使用以下命令在账本上创建一组初始汽车。请注意,invoke命令需要以足够数量的对等节点为目标,以满足链码认可策略。
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"initLedger","Args":[]}'
红框中就是我们得到的输出:

图片

具体为:
2022-06-22 22:45:55.177 CST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
我们可以使用查询功能读取由链码创建的汽车集:

图片

具体为:
[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]

2、升级链码


我们可以使用相同的Fabric链码生命周期过程来升级已经部署到通道的链码。通道成员可以通过安装一个新的链码包来升级链码,然后批准一个带有新的包ID的链码定义,一个新的链码版本,并将序列号增加1。在将链代码定义定义为通道之后,可以使用新的链码。这个过程允许通道成员在链码升级时进行协调,并确保在新链码部署到通道之前有足够数量的通道成员准备使用它。
通道成员也可以使用升级流程更改链码背书策略。通过批准具有新的背书策略的链码定义并将链码定义提交给通道,通道成员可以更改管理链码的背书策略,而无需安装新的链码包。
为了提供一个升级我们刚刚部署的Fabcar链代码的场景,我们假设Org1和Org2想要安装用另一种语言编写的链代码版本。他们将使用Fabric链码的生命周期来更新链码版本,并确保两个组织在新链码在渠道上激活之前已经安装了新链码。我们假设Org1和Org2最初安装的是GO版本的Fabcar链代码,但是使用JavaScript编写的链代码会更舒服。第一步是打包Fabcar链代码的JavaScript版本。
要注意的是,很多情况下,我们的Ubuntu虚拟机中是没有安装npm的,所以我们要先安装npm:

sudo apt install npm
然后我们从test-network目录发出以下命令来安装chaincode依赖项:
cd ../chaincode/fabcar/javascriptnpm installcd ../../../test-network
安装过程部分截图如下:

图片

然后我们设置环境变量,用于后续的打包:
export PATH=${PWD}/../bin:$PATHexport FABRIC_CFG_PATH=$PWD/../config/export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/msppeer lifecycle chaincode package fabcar_2.tar.gz --path ../chaincode/fabcar/javascript/ --lang node --label fabcar_2

图片

然后我们执行如下命令使对等节点CLI作为Org1管理:
export CORE_PEER_TLS_ENABLED=trueexport CORE_PEER_LOCALMSPID="Org1MSP"export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crtexport CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/[email protected]/mspexport CORE_PEER_ADDRESS=localhost:7051
执行如下命令将新的链码包安装到Org1对等节点中:
peer lifecycle chaincode install fabcar_2.tar.gz
结果如下:

图片

然后我们进行查询,就会发现新创建的包ID:
peer lifecycle chaincode queryinstalled
结果如下:

图片

我们将包ID保存为一个新的变量:
export NEW_CC_PACKAGE_ID=fabcar_2:510df31a69a460b6f45717a1f5674bbc46ffb8241b8bb269266011491d0c0067
然后Org1就可以批准新的链码定义了:
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 2.0 --package-id $NEW_CC_PACKAGE_ID --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
这两步执行结果如下:

图片

接下来安装链码包,并批准链码定义为Org2,以便升级链码。执行如下命令使对等节点CLI作为Org2管理并进行安装:
export CORE_PEER_LOCALMSPID="Org2MSP"export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crtexport CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/[email protected]/mspexport CORE_PEER_ADDRESS=localhost:9051peer lifecycle chaincode install fabcar_2.tar.gz
结果如下:

图片

然后就是批准Org2的新链码定义:
peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 2.0 --package-id $NEW_CC_PACKAGE_ID --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

图片

使用如下命令检查序列为2的链码定义是否可以提交到通道中:
peer lifecycle chaincode checkcommitreadiness
完整命令如下:
peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name fabcar --version 2.0 --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json
执行结果如下:

图片

在提交新的链码定义后,链码将在通道上进行升级。在此之前,之前的链码将继续在两个组织的对等节点上运行。Org2可以使用以下命令升级链码:
peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name fabcar --version 2.0 --sequence 2 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

图片

成功的提交交易将立即启动新的链码。如果链码的定义更改了背书策略,新策略将生效。使用如下命令验证新的链码是否在对等节点开始:
docker ps
执行结果如下:

图片

我们将输出展示在下面:
CONTAINER ID   IMAGE                                                                                                                                                                   COMMAND                  CREATED         STATUS         PORTS                                                                                                                                 NAMES69774e4b697c   dev-peer0.org2.example.com-fabcar_2-510df31a69a460b6f45717a1f5674bbc46ffb8241b8bb269266011491d0c0067-54e12ab8ea79f61443ac1f1eaf57157b208d217c9b8d01b2a73322f26446789d   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes                                                                                                                                         dev-peer0.org2.example.com-fabcar_2-510df31a69a460b6f45717a1f5674bbc46ffb8241b8bb269266011491d0c00672ebbaf3e3c7e   dev-peer0.org1.example.com-fabcar_2-510df31a69a460b6f45717a1f5674bbc46ffb8241b8bb269266011491d0c0067-48506a0daaa9cd12e0c03b343531a27c82cb0d957d6f0c60256fdcfafb4a81bc   "docker-entrypoint.s…"   2 minutes ago   Up 2 minutes                                                                                                                                         dev-peer0.org1.example.com-fabcar_2-510df31a69a460b6f45717a1f5674bbc46ffb8241b8bb269266011491d0c0067e34803048be0   gliderlabs/logspout                                                                                                                                                     "/bin/logspout"          5 hours ago     Up 5 hours     127.0.0.1:8000->80/tcp                                                                                                                logspoutd521514c2f0e   hyperledger/fabric-tools:latest                                                                                                                                         "/bin/bash"              5 hours ago     Up 5 hours                                                                                                                                           cli9a9f2b5b95ed   hyperledger/fabric-orderer:latest                                                                                                                                       "orderer"                5 hours ago     Up 5 hours     0.0.0.0:7050->7050/tcp, :::7050->7050/tcp, 0.0.0.0:7053->7053/tcp, :::7053->7053/tcp, 0.0.0.0:17050->17050/tcp, :::17050->17050/tcp   orderer.example.comf4f5874c1e75   hyperledger/fabric-peer:latest                                                                                                                                          "peer node start"        5 hours ago     Up 5 hours     0.0.0.0:9051->9051/tcp, :::9051->9051/tcp, 7051/tcp, 0.0.0.0:19051->19051/tcp, :::19051->19051/tcp                                    peer0.org2.example.comd89f2f0db832   hyperledger/fabric-peer:latest                                                                                                                                          "peer node start"        5 hours ago     Up 5 hours     0.0.0.0:7051->7051/tcp, :::7051->7051/tcp, 0.0.0.0:17051->17051/tcp, :::17051->17051/
我们也可以通过创建一辆新车来测试我们的新链码:
peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n fabcar --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"createCar","Args":["CAR11","Honda","Accord","Black","Tom"]}'
执行结果如下:

图片

我们也可以查询所有的车辆:
peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
执行结果如下:

图片

[{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}},{"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}},{"Key":"CAR11","Record":{"color":"Black","docType":"car","make":"Honda","model":"Accord","owner":"Tom"}},{"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}},{"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}},{"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}},{"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}},{"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}},{"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}},{"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}},{"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}]

2、清理链码


我们使用完链码,就可以关闭监控工具和网络了。

关闭监控工具命令为:

docker stop logspoutdocker rm logspout

这个命令不是在我们打开这个监控工具的终端执行,就在我们前面执行命令的终端即可,上面是执行命令的终端,下面是监控的终端:

图片


图片


出现红框说明成功关闭。然后接着执行下一条命令:

图片


最后关闭网络:

./network.sh down

图片

5

说在后面的话


到这里,我们就了解了如何部署智能合约到通道,虽然只是一件事,但是内容很多,将近两万字,包括了很多重要的操作,需要大家一步一步认认真真去做。遇到困难不可怕,教员的诗词说的好,世上无难事,只要肯登攀。只要我们用科学的方法,认真去做,一定能够达到我们的目的!

一起加油啦!

图片

图片

长按二维码关注


图片

在看数你最好看

47600区块链 | Hyperledger Fabric 04 超详细图解——智能合约的部署、调用与升级

这个人很懒,什么都没留下

文章评论