链码部署

现阶段,我们通过peer cli向通道中部署链码。当然,教育联盟链的BAAS(Blockchain as a service)服务平台也正在开发中,未来可以通过BAAS管理平台来管理链码。

通过peer cli部署链码需要四步操作:

  • 第一步,链码打包

  • 第二步,链码安装

  • 第三步,链码审议

  • 第四步,链码提交

链码打包

在安装链码之前我们需要对链码打包,在打包链码之前,我们需要安装链码的依赖包,切换到包含链码的目录中,使用go module来安装链码的依赖包,在go目录下运行命令:

GO111MODULE=on go mod vendor

使用peer CLI打包链码:

peer lifecycle chaincode package Vote.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label Vote

此命令会在当前目录下创建Vote.tar.gz文件,–lang标识链码的编程语言,–path链码路径,–label链码安装后的标签,建议包含链码名称和版本。

链码安装

打包完链码后,就可以在peer上安装。链码需要再所有参与背书的peer上安装。此处以一个组织内进行安装为例eg:org1。

首先通过配置环境变量在指定peer操作的为组织Org1

export CORE_PEER_MSPCONFIGPATH=${PWD}/${edu}/admin/msp
export CORE_PEER_LOCALMSPID=”Org1MSP”
export CORE_PEER_ADDRESS=localhost:7051
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/${edu}/tls-ca/xxxxxx.pem
export PROJ_NAME='Vote'
export VERSION='1.0'

运行下面代码在peer上安装链码:

peer lifecycle chaincode install Vote.tar.gz

如果执行成功,会返回链码的标识符package ID,此ID会再下一步审议链码的环节用到。类似于下方的输出:

2021-09-26 11:40:02.923 EST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"Ivote_1:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3\022\010fabcar_1" >
2021-09-26 11:40:02.925 EST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: vote_1:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3

链码审议

安装链码包后,需要组织审议链码的定义,定义包含管理链码的参数如名称、版本,背书策略.channel内的成员需要在部署链码之前对链码的定义达成一致。

审议链码时会用到packageID 我们先把它保存到一个环境变量中:

export ID=Vote_1:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3

执行下面命令:

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

–package-id来标识链码,–sequence是一个整数用来追踪链码定义和升级次数。因为此处是第一次部署链码到channel中,所以sequence是1,当此链码升级的时候,sequence要递增到2。如果你使用的是低版本的链码API,可以使用–init-required来执行链码的初始化init。第一次invoke调用链码时需要使用–isInit来初始化链码,执行init函数。需要用admin的身份来审议链码定义,因此CORE_PEER_MSPCONFIGPATH 要执行admin的账户。客户端用户不能审议链码,审议结果会提交给排序服务器,排序服务器验证管理员签名后会将审议结果分发给组织内的peers

提交链码

在足够数量的组织为链码定义达成一致后,一个组织可以提交链码定义到Channel中。如果大多数组织同意了链码定义,提交事务会成功执行,且链码定义的参数会在channel中生效。

可以使用 peer lifecycle chaincode checkcommitreadiness 命令来查看哪些成员已经同意了链码定义:

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name vote --version 1.0 --sequence 1 --tls true --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

通道内所有组织都同意了链码定义之后,链码定义就可以提交到channel中,执行以下命令提交channel中:

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name vote --version 1.0 --sequence 1 --tls true --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

通道内成员背书的链码定义会提交到排序服务节点上,然后在通道中会创建一个区块。通道上的peers会验证是否有足够的组织同意了链码定义,peer lifecycle chaincode commit会一直等待peers的验证结果。 使用使用peer lifecycle chaincode querycommitted来确认链码定义是否已经被提交到通道上。如果链码成功的提交到通道上,会返回链码的sequence和链码版本号。

调用链码

如果链码定义提交成功,链码会在安装的peer上开始运行。链码已经可以被客户端调用,此处要注意链码调用需要有满足策略的足够的背书节点。

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls true --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

如果调用成功,会看到如下返回:

2021-09-28 03:45:41.956 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

升级链码

可以使用lifecycle 来升级已经部署的链码。通道中成员可以升级链码:安装新链码包,审议链码定义,新的链码版本,新的sequence(递增一位)。新的链码在提交到channel后可以调用。