超级账本Fabric2.x 如何将智能合约部署到通道

如何将智能合约部署到通道——部署Fabric测试网络的实例

使用系统版本:Ubuntu 18.04
提示:任何命令错误都可以试试加sudo提升权限!!!
参考文章:官方文档

一、启动网络

1.1 进入测试网络目录

我们将从部署Fabric测试网络的实例开始。在开始之前,请确保已经完成了准备阶段并安装了示例,二进制文件和Docker映像,如未完成,可以参考超级账本Fabric 2.x 详细安装步骤及可能问题解决方式

进入fabric-samples/test-network目录

cd ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network

1.2 恢复到已知的初始状态

使用以下命令结束所有活动或陈旧的Docker容器并删除以前生成的部件

sudo ./network.sh down

1.3 启动测试网络

sudo ./network.sh up createChannel

该createChannel命令创建一个以mychannel两个通道成员Org1和Org2命名的通道。该命令还将属于每个组织的peer节点加入通道。如果成功创建了网络和通道,则可以在日志中看到以下消息:

============Channel successfully joined================

二、设置Logspout(可选)

此步骤不是必需的,但是对于故障排除链码非常有用。
Fabric示例monitordocker.sh中的commercial-paper示例已包含用于安装和配置Logspout的脚本。

2.1 打开一个新的终端

2.2 进入fabric-samples/test-network目录

cd ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/test-network

2.3 将monitordocker.sh脚本从commercial-paper示例复制到fabric-samples/test-network工作目录中

sudo cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh .

2.4 启动Logspout

sudo ./monitordocker.sh net_test

成功后可以看到类似于以下内容的输出:

Starting monitoring on all containers on the network net_test
Unable to find image 'gliderlabs/logspout:latest' locally
latest: Pulling from gliderlabs/logspout
188c0c94c7c5: Already exists 
f76076d59b2f: Pull complete 
d09edbff691c: Pull complete 
Digest: sha256:2b70c1989a00a2775311e66aec8be6e2479deb0e0c0c0be603de1863f49027e8
Status: Downloaded newer image for gliderlabs/logspout:latest
1c6c61c50c02e45282d565c8177d81358945a1ab59065a822491ee88fcac1ad6

三、打包智能合约

注意:以下为由Go语言编写的智能合约打包步骤,JavaScript打包见第八节。

3.1 打开一个新的终端

3.2 安装chaincode依赖项

依赖项go.mod在fabric-samples/chaincode/fabcar/go目录中的文件中列出,该go.mod文件将Fabric合约API导入到智能合约包中。

cd ~/go/src/github.com/hyperledger/fabric/scripts/fabric-samples/chaincode/fabcar/go
sudo GO111MODULE=on go mod vendor

3.3 返回到test-network所在目录

返回到test-network所在目录,以便可以将链码与其他网络部件打包在一起。

cd ../../../test-network

3.4 将bin目录中二进制文件添加到CLI路径

所需格式的链码包可以使用peer CLI创建,使用以下命令将这些二进制文件添加到你的CLI路径。

export PATH=${PWD}/../bin:$PATH

3.5 设置FABRIC_CFG_PATH为指向fabric-samples中的core.yaml文件

export FABRIC_CFG_PATH=$PWD/../config/

3.6 创建链码包

使用peer lifecycle chaincode package命令创建链码包。

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

命令解释:此命令将在当前目录中创建一个名为basic.tar.gz的软件包。–lang标签用于指定链码语言,–path标签提供智能合约代码的位置,该路径必须是标准路径或相对于当前工作目录的路径,–label标签用于指定一个链码标签,该标签将在安装链码后对其进行标识。建议您的标签包含链码名称和版本。

现在,我们已经创建了链码包,我们可以在测试网络的对等节点上安装链码。

四、安装链码包

打包Fabcar智能合约后,我们可以在peer节点上安装链码。需要在将认可交易的每个peer节点上安装链码。因为我们将设置背书策略以要求来自Org1和Org2的背书,所以我们需要在两个组织的peer节点上安装链码:peer0.org1.example.com和peer0.org2.example.com。

4.1 Org1 peer节点安装链码

先在Org1 peer节点上安装链码。

  • 设置以下环境变量,以Org1管理员的身份操作peer CLI。
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    
  • 使用 peer lifecycle chaincode install 命令在peer节点上安装链码。
    sudo peer lifecycle chaincode install fabcar.tar.gz
    
  • 如果命令成功,则peer节点将生成并返回包标识符。下一步,此包ID将用于通过链码。你应该看到类似于以下内容的输出:
    2020-11-24 20:59:00.766 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506\022\010fabcar_1" > 
    2020-11-24 20:59:00.775 CST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506
    

4.2 Org2 peer节点安装链码

  • 设置以下环境变量,以Org2管理员的身份操作peer CLI。
    export CORE_PEER_LOCALMSPID="Org2MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    export CORE_PEER_ADDRESS=localhost:9051
    
  • 使用 peer lifecycle chaincode install 命令在peer节点上安装链码。
    sudo peer lifecycle chaincode install fabcar.tar.gz
    
  • 注意:安装链码时,链码由peer节点构建。如果智能合约代码有问题,install命令将从链码中返回所有构建错误。

五、通过链码定义

安装链码包后,需要通过组织的链码定义。该定义包括链码管理的重要参数,例如名称,版本和链码认可策略。

如果组织已在其peer节点上安装了链码,则他们需要在其组织通过的链码定义中包括包ID。包ID用于将peer节点上安装的链码与通过的链码定义相关联,并允许组织使用链码来认可交易。

5.1 查询包ID

可以使用peer lifecycle chaincode queryinstalled命令来查询peer节点,从而找到链码的包ID。

sudo peer lifecycle chaincode queryinstalled

包ID是链码标签和链码二进制文件的哈希值的组合。每个peer节点将生成相同的包ID。你应该看到类似于以下内容的输出:

Installed chaincodes on peer:
Package ID: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506, Label: fabcar_1

通过链码时,我们将使用包ID,因此,将包ID保存为环境变量。将返回的包ID粘贴到下面的命令中。
注意:包ID对于所有用户而言都不相同,因此需要使用上一步中从命令窗口返回的包ID来完成此步骤。而不是直接复制命令!!!

export CC_PACKAGE_ID=fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506

5.2 Org2通过链码定义

因为已经设置了环境变量为peer CLI作为Orig2管理员进行操作,所以我们可以以Org2组织级别将Fabcar的链码定义通过。使用 peer lifecycle chaincode approveformyorg命令通过链码定义:

sudo 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

5.3Org1通过链码定义

设置以下环境变量以Org1管理员身份运行:

export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051

Org1通过链码定义:

sudo 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 checkcommitreadiness命令来检查通道成员是否已批准相同的链码定义:

sudo 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

该命令将生成一个JSON映射,该映射显示通道成员是否批准了checkcommitreadiness命令中指定的参数:

{
	"approvals": {
		"Org1MSP": true,
		"Org2MSP": true
	}
}

由于作为通道成员的两个组织都同意了相同的参数,因此链码定义已准备好提交给通道。你可以使用peer lifecycle chaincode commit命令将链码定义提交到通道。commit命令还需要由组织管理员提交。

sudo 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命令来确认链码定义已提交给通道。

sudo 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

如果将链码成功提交给通道,该querycommitted命令将返回链码定义的顺序和版本:

Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]

七、调用链码

sudo 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":[]}'

如果命令成功执行,应该能够得到类似于以下的响应:

chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200

还可以使用查询功能来读取由链码创建的汽车的集合:

sudo 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":"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"}}]

八、升级智能合约

在第三节中安装的链码包是由Go语言写的,接下来我们升级为由JavaScript编写的链码。

  • 从test-network目录发出以下命令以安装chaincode依赖项:

    cd ../chaincode/fabcar/javascript
    # 没有安装npm记得自行安装,另外记得换国内源!!!
    # 另外国内更适合使用 cnpm
    # sudo npm install
    # 这里我使用了cnmp。使用nmp也可。
    sudo cnmp install
    cd ../../../test-network
    
  • 执行以下命令来打包test-network目录中的JavaScript链码:

    # 如果你未关闭终端,以下环境变量可以不用设置
    # 设置再次使用peer CLI所需的环境变量
    export FABRIC_CFG_PATH=$PWD/../config/
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    
    # 打包链码
    sudo peer lifecycle chaincode package fabcar_2.tar.gz --path ../chaincode/fabcar/javascript/ --lang node --label fabcar_2
    
    # 如果你未关闭终端,以下环境变量可以不用设置
    # 运行以下命令,以Org1管理员的身份操作peer CLI
    export CORE_PEER_TLS_ENABLED=true
    export CORE_PEER_LOCALMSPID="Org1MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
    export CORE_PEER_ADDRESS=localhost:7051
    
    # 使用以下命令在Org1peer节点上安装新的链码包
    sudo peer lifecycle chaincode install fabcar_2.tar.gz
    
  • 新的链码包将创建一个新的包ID。可以通过查询peer节点来找到新的包ID:

    sudo peer lifecycle chaincode queryinstalled
    

    该queryinstalled命令将返回已在peer节点上安装的链码的列表:

    Installed chaincodes on peer:
    Package ID: fabcar_1:762e0fe3dbeee0f7b08fb6200adeb4a3a20f649a00f168c0b3c2257e53b6e506, Label: fabcar_1
    Package ID: fabcar_2:760e754e45a8ecf4bcc654945ac4554bbdb793d63255b047b5b9a6199a004ae4, Label: fabcar_2
    
  • 使用包标签找到新链码的包ID,并将其另存为新的环境变量:

    export NEW_CC_PACKAGE_ID=fabcar_2:760e754e45a8ecf4bcc654945ac4554bbdb793d63255b047b5b9a6199a004ae4
    
  • 现在,Org1可以通过新的链码定义:

    sudo 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来通过新的链码定义:

    export CORE_PEER_LOCALMSPID="Org2MSP"
    export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
    export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
    export CORE_PEER_ADDRESS=localhost:9051
    
    # 在Org2peer节点上安装新的链码包
    sudo peer lifecycle chaincode install fabcar_2.tar.gz
    
    # 同意Org2的新链码定义
    sudo 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
    
  • 使用peer lifecycle chaincode checkcommitreadiness命令检查序列2的链码定义是否准备好提交给通道:

    sudo 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
    

    如果命令返回以下JSON,则表示链代码已准备好升级:

    {
                "Approvals": {
                        "Org1MSP": true,
                        "Org2MSP": true
                }
    }
    
  • 提交新的链码定义后,链码将在通道上升级。在此之前,先前的链码将继续在两个组织的peer节点上运行。Org2可以使用以下命令来升级链码:

    sudo 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
    

    成功的提交事务将立即启动新的链码。如果链码定义更改了背书政策,则新政策将生效。
    你可以使用以下命令来验证新链码已在你的peer节点上启动:docker p

    docker ps
    
  • 创建新车来测试新的JavaScript链代码

      ```bash
      sudo 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"]}'
      ```
    
    • 你可以再次查询分类帐上的所有汽车以查看新汽车:

      sudo peer chaincode query -C mychannel -n fabcar -c '{"Args":["queryAllCars"]}'
      
    • 你应该从JavaScript链代码中看到以下结果:

    [{"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"}}]
    

九、清理

使用完链码后,你可以使用以下命令删除Logspout工具:

docker stop logspout
docker rm logspout

然后,你可以通过从test-network目录发出以下命令来关闭测试网络:

sudo ./network.sh down
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值