Hyperledger Fabric 2.0 官方文档中文版第6章 教程上
总目录
第1章 引言
第2章 Hyperledger Fabric v2.0的新增功能
第3章 关键概念
第4章 入门
第5章 开发应用程序
第6章 教程(上)
第6章 教程(下)
第7章 部署生产网络
第8章 操作指南
第9章 升级到最新版本
6.教程(上)
应用程序开发人员可以使用Fabric教程开始构建自己的解决方案。通过在本地计算机上部署测试网络开始使用Fabric。然后,您可以使用“将智能合约部署到通道”教程提供的步骤来部署和测试智能合约。编写第一个应用程序教程介绍了如何使用Fabric sdk提供的APIs从客户端应用程序调用智能合约。有关Fabric应用程序和智能合约如何协同工作的深入概述,您可以访问“开发应用程序”主题。
网络运营商还可以使用“将智能合约部署到通道”教程来学习如何使用Fabric链码生命周期来管理部署在正在运行的网络上的智能合约。网络运营商和应用程序开发人员都可以使用关于私有数据和CouchDB的教程来探索重要的Fabric特性。准备在生产中部署Hyperledger Fabric时,请参阅《部署生产网络指南》。
更新通道有两个教程:更新通道配置和更新通道的功能级别,而升级组件则说明如何升级节点、排序节点、SDK等组件。
最后,我们介绍了如何编写一个基本的智能合约,开发人员的链码。
注意:如果您有本文档没有解决的问题,或者遇到任何教程的问题,请访问仍然有问题吗?页面获取有关在何处找到其他帮助的提示。
将智能合约部署到通道
最终用户通过调用智能合约与区块链账本交互。在Hyperledger Fabric中,智能合约部署在称为链码的包中。想要验证交易记录或查询账本的组织需要在其节点上安装链码。在连接到通道的节点上安装链码后,通道成员可以将链码部署到通道,并使用链码中的智能合约在通道账本上创建或更新资产。
使用称为Fabric链码生命周期的过程将链码部署到通道。Fabric链码生命周期允许多个组织在链码用于创建交易之前商定如何操作链码。例如,虽然背书策略指定哪些组织需要执行链码以验证交易,但通道成员需要使用Fabric链码生命周期来商定链码背书策略。有关如何在通道上部署和管理链码的更深入概述,请参阅Fabric链码生命周期。
您可以使用本教程学习如何使用节点生命周期链码命令将链码部署到Fabric测试网络的通道。一旦您了解了这些命令,就可以使用本教程中的步骤将自己的链码部署到测试网络,或者将链码部署到生产网络。在本教程中,您将部署编写第一个应用程序教程所使用的Fabcar链码。
注意:这些说明使用了v2.0版本中引入的Fabric链码生命周期。如果要使用以前的生命周期来安装和实例化链码,请访问Fabric文档的v1.4版本。
启动网络
我们将首先部署Fabric测试网络的一个实例。在开始之前,请确保您已经安装了先决条件并安装了示例、二进制文件和Docker镜像。使用以下命令导航到fabric-samples
存储库的本地克隆中的测试网络目录:
cd fabric-samples/test-network
在本教程中,我们希望从已知的初始状态开始操作。下面的命令将杀死任何活动的或过时的docker容器,并删除以前生成的工件。
./network.sh down
然后可以使用以下命令启动测试网络:
./network.sh up createChannel
createChannel
命令使用两个通道成员Org1和Org2创建一个名为mychannel
的通道。该命令还将属于每个组织的节点连接到通道。如果网络和通道创建成功,您可以在日志中看到以下消息:
========= Channel successfully joined ===========
我们现在可以使用节点CLI通过以下步骤将Fabcar链码部署到通道:
Logspout设置
此步骤不是必需的,但对于排除链码故障非常有用。为了监视智能合约的日志,管理员可以使用logspout
工具查看一组Docker容器的聚合输出。该工具将来自不同Docker容器的输出流收集到一个位置,这样就可以很容易地从一个窗口查看正在发生的事情。这可以帮助管理员在安装智能合约时调试问题,也可以帮助开发人员在调用智能合约时调试问题。因为有些容器纯粹是为了启动智能合约而创建的,并且只存在很短的时间,所以从网络收集所有日志是很有帮助的。
安装和配置logspoutt的脚本,monitordocker.sh
,已包含在commercial-paper
样品中的Fabric sample中。我们也将在本教程中使用相同的脚本。logspoutt工具将连续地将日志流式传输到您的终端,因此您需要使用一个新的终端窗口。打开一个新的终端并导航到test-network
目录。
cd fabric-samples/test-network
你可以运行monitordocker.sh
任何目录中的脚本。为了便于使用,我们将复制monitordocker.sh
从commercial-paper
到你的工作目录的脚本
cp ../commercial-paper/organization/digibank/configuration/cli/monitordocker.sh .
# if you're not sure where it is
find . -name monitordocker.sh
然后,可以通过运行以下命令来启动Logspout:
./monitordocker.sh net_test
您将看到类似于以下内容的输出:
Starting monitoring on all containers on the network net_basic
Unable to find image 'gliderlabs/logspout:latest' locally
latest: Pulling from gliderlabs/logspout
4fe2ade4980c: Pull complete
decca452f519: Pull complete
ad60f6b6c009: Pull complete
Digest: sha256:374e06b17b004bddc5445525796b5f7adb8234d64c5c5d663095fccafb6e4c26
Status: Downloaded newer image for gliderlabs/logspout:latest
1f99d130f15cf01706eda3e1f040496ec885036d485cb6bcc0da4a567ad84361
一开始您不会看到任何日志,但当我们部署链码时,这将发生变化。使这个终端窗口变宽而字体变小是很有帮助的。
打包智能合约
我们需要打包链码,然后才能将其安装到我们的节点上。如果您想安装用Go、Java或JavaScript编写的智能合约,步骤是不同的。
Go
在打包链码之前,我们需要安装链码依赖项。导航到包含Fabcar链码Go版本的文件夹。
cd fabric-samples/chaincode/fabcar/go
示例使用Go模块安装链码依赖项。依赖项列在fabcar/go
目录中的go.mod
文件中。你应该花点时间检查这个文件。
$ cat go.mod
module github.com/hyperledger/fabric-samples/chaincode/fabcar/go
go 1.13
require github.com/hyperledger/fabric-contract-api-go v1.1.0
这个go.mod
文件将Fabric合约API导入智能合约包。你可以在文本编辑器中打开fabcar.go
,查看如何在智能合约开始时使用合约API定义SmartContract
类型:
// SmartContract provides functions for managing a car
type SmartContract struct {
contractapi.Contract
}
然后,智能合约类型用于为智能合约中定义的功能创建交易环境,这些功能将数据读写到区块链账本。
// CreateCar adds a new car to the world state with given details
func (s *SmartContract) CreateCar(ctx contractapi.TransactionContextInterface, carNumber string, make string, model string, colour string, owner string) error {
car := Car{
Make: make,
Model: model,
Colour: colour,
Owner: owner,
}
carAsBytes, _ := json.Marshal(car)
return ctx.GetStub().PutState(carNumber, carAsBytes)
}
通过访问API文档和智能合约处理主题,您可以了解更多关于Go合约API的信息。
要安装智能合约依赖项,请从fabcar/go
目录运行以下命令。
GO111MODULE=on go mod vendor
如果命令成功,go包将安装在vendor
文件夹中。
既然我们有了依赖项,我们就可以创建chaincode包了。导航回test-network
文件夹中的工作目录,这样我们就可以将链码与其他网络构件打包在一起。
cd ../../../test-network
您可以使用peer
CLI以所需格式创建链码包。peer
二进制文件位于fabric-samples
存储库的bin
文件夹中。使用以下命令将这些二进制文件添加到CLI路径:
export PATH=${
PWD}/../bin:${
PWD}:$PATH
您还需要将FABRIC_CFG_PATH
设置为指向fabric-samples
存储库中的core.yaml
文件:
export FABRIC_CFG_PATH=$PWD/../config/
要确认您能够使用peer
CLI,请检查二进制文件的版本。二进制文件必须是2.0.0
或更高版本才能运行本教程。
peer version
您还需要将CORE_PEER_MSPCONFIGPATH
设置为管理员或客户端用户的MSP文件夹的位置。运行下面的命令来建立Org1 admin作为我们使用的标识。
export CORE_PEER_MSPCONFIGPATH=${
PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
现在可以使用peer lifecycle chaincode package命令创建链码包:
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/go/ --lang golang --label fabcar_1
此命令将在当前目录中创建一个名为fabcar.tar.gz
的文件。--lang
标志用于指定链码语言,--path
标志提供智能合约代码的位置。--label
标志用于指定一个链码标签,该标签将在安装后标识链码。建议您的标签包含链码名称和版本。
现在我们已经创建了链码包,我们可以在测试网络的节点上安装链码。
JavaScript
在打包链码之前,我们需要安装链码依赖项。导航到包含Fabcar链码JavaScript版本的文件夹。
cd fabric-samples/chaincode/fabcar/javascript
依赖项列在fabcar/javascript
目录的package.json
文件中。你应该花点时间检查这个文件。您可以在下面找到Dependencies部分:
"dependencies": {
"fabric-contract-api": "^2.0.0",
"fabric-shim": "^2.0.0"
package.json
文件将Fabric contract类导入到智能合约包中。您可以在文本编辑器中打开lib/fabcar.js
以查看导入到智能合约中并用于创建FabCar类的contract类。
const {
Contract } = require('fabric-contract-api');
class FabCar extends Contract {
...
}
FabCar
类为智能合约中定义的函数提供交易环境,这些函数将数据读写到区块链账本。
async createCar(ctx, carNumber, make, model, color, owner) {
console.info('============= START : Create Car ===========');
const car = {
color,
docType: 'car',
make,
model,
owner,
};
await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
console.info('============= END : Create Car ===========');
}
通过访问API文档和智能合约处理主题,您可以了解有关JavaScript合约API的更多信息。
要安装智能合约依赖项,请从fabcar/javascript
目录运行以下命令。
npm install
如果命令成功,JavaScript包将安装在npm_modules
文件夹中。
既然我们有了依赖项,我们就可以创建chaincode包了。导航回test-network
文件夹中的工作目录,这样我们就可以将链码与其他网络构件打包在一起。
cd ../../../test-network
您可以使用peer
CLI以所需格式创建链码包。peer
二进制文件位于fabric-samples
存储库的bin
文件夹中。使用以下命令将这些二进制文件添加到CLI路径:
export PATH=${
PWD}/../bin:${
PWD}:$PATH
您还需要将FABRIC_CFG_PATH
设置为指向fabric-samples
存储库中的core.yaml
文件:
export FABRIC_CFG_PATH=$PWD/../config/
要确认您能够使用peer
CLI,请检查二进制文件的版本。二进制文件必须是2.0.0
或更高版本才能运行本教程。
peer version
您还需要将CORE_PEER_MSPCONFIGPATH
设置为管理员或客户端用户的MSP文件夹的位置。运行下面的命令来建立Org1 admin作为我们使用的标识。
export CORE_PEER_MSPCONFIGPATH=${
PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
现在可以使用peer lifecycle chaincode package命令创建链码包:
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/javascript/ --lang node --label fabcar_1
此命令将在当前目录中创建一个名为fabcar.tar.gz
的文件。--lang
标志用于指定链码语言,--path
标志提供智能合约代码的位置。--label
标志用于指定一个链码标签,该标签将在安装后标识链码。建议您的标签包含链码名称和版本。
现在我们已经创建了链码包,我们可以在测试网络的节点上安装链码。
Java
在打包链码之前,我们需要安装链码依赖项。导航到包含Java版Fabcar链码的文件夹。
cd fabric-samples/chaincode/fabcar/java
示例使用Gradle安装链码依赖项。依赖项列在fabcar/java
目录的build.gradle
文件中。你应该花点时间检查这个文件。您可以在下面找到Dependencies部分:
dependencies {
compileOnly 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.0.+'
implementation 'com.owlike:genson:1.5'
testImplementation 'org.hyperledger.fabric-chaincode-java:fabric-chaincode-shim:2.0.+'
testImplementation 'org.junit.jupiter:junit-jupiter:5.4.2'
testImplementation 'org.assertj:assertj-core:3.11.1'
testImplementation 'org.mockito:mockito-core:2.+'
}
build.gradle
文件将Java链码填充程序导入到智能合约包中,其中包括contract类。您可以在src
目录中找到Fabcar智能合约。您可以导航到FabCar.java
文件并在文本编辑器中打开,查看如何使用contract类为定义的函数创建交易环境,这些函数用于将数据读写到区块链账本。
通过访问Java链码文档和智能合约处理主题,您可以了解有关Java链码填充程序和合约类的更多信息。
要安装智能合约依赖项,请从fabcar/java
目录运行以下命令。
./gradlew installDist
如果命令成功,您将能够在build
文件夹中找到build智能合约。
现在我们已经安装了依赖项并构建了智能合约,现在可以创建链码包了。导航回test-network
文件夹中的工作目录,这样我们就可以将链码与其他网络构件打包在一起。
cd ../../../test-network
您可以使用peer
CLI以所需格式创建链码包。peer
二进制文件位于fabric-samples
存储库的bin
文件夹中。使用以下命令将这些二进制文件添加到CLI路径:
export PATH=${
PWD}/../bin:${
PWD}:$PATH
您还需要将FABRIC_CFG_PATH
设置为指向fabric-samples
存储库中的core.yaml
文件:
export FABRIC_CFG_PATH=$PWD/../config/
要确认您能够使用peer
CLI,请检查二进制文件的版本。二进制文件必须是2.0.0
或更高版本才能运行本教程。
peer version
您还需要将CORE_PEER_MSPCONFIGPATH
设置为管理员或客户端用户的MSP文件夹的位置。运行下面的命令来建立Org1 admin作为我们使用的标识。
export CORE_PEER_MSPCONFIGPATH=${
PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
现在可以使用peer lifecycle chaincode package命令创建链码包:
peer lifecycle chaincode package fabcar.tar.gz --path ../chaincode/fabcar/java/build/install/fabcar --lang java --label fabcar_1
此命令将在当前目录中创建一个名为fabcar.tar.gz
的文件。--lang
标志用于指定链码语言,--path
标志提供智能合约代码的位置。--label
标志用于指定一个链码标签,该标签将在安装后标识链码。建议您的标签包含链码名称和版本。
现在我们已经创建了链码包,我们可以在测试网络的节点上安装链码。
安装链码包
在我们打包Fabcar智能合约之后,我们可以在我们的节点上安装链码。链码需要安装在每一个背书交易的节点上。因为我们要将背书策略设置为需要Org1和Org2的背书,所以我们需要在两个组织操作的节点上安装链码:
- peer0.org1.example.com
- peer0.org2.example.com
让我们先在Org1节点上安装链码。设置以下环境变量以作为Org1管理用户操作peer
CLI。CORE_PEER_ADDRESS
将被设置为指向Org1节点peer0.org1.example.com
。
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 lifecycle chaincode install fabcar.tar.gz
如果命令成功,节点将生成并返回包标识符。此包ID将用于在下一步中批准链码。您将看到类似于以下内容的输出:
2020-02-12 11:40:02.923 EST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nIfabcar_1:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3\022\010fabcar_1" >
2020-02-12 11:40:02.925 EST [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: fabcar_1:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3
我们现在可以在Org2节点上安装链码。设置以下环境变量以作为Org2管理员操作,并以Org2节点peer0.org2.example.com
为目标。
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 fabcar.tar.gz
链码是在安装链码时由节点生成的。如果智能合约代码有问题,install命令将从链码返回任何生成错误。
批准链码定义
安装链码包后,需要批准组织的链码定义。定义包括链码管理的重要参数,如名称、版本和链码背书策略。
在可以部署链码之前需要批准它的通道成员集受Application/Channel/lifeycleEndorsement
策略的控制。默认情况下,此策略要求大多数通道成员在链码可用于通道之前需要批准它。因为我们在通道上只有两个组织,而且大多数是2,所以我们需要批准Fabcar的链码定义Org1和Org2。
如果一个组织已在其节点上安装了链码,则需要在其组织批准的链码定义中包含package ID。包ID用于将节点上安装的链码与已批准的链码定义相关联,并允许组织使用链码来背书交易。您可以使用peer lifecycle chaincode queryinstalled命令来查询节点,从而找到链码的包ID。
peer lifecycle chaincode queryinstalled
包ID是链码标签和链码二进制文件的哈希的组合。每个节点都将生成相同的包ID。您应该看到类似于以下内容的输出:
Installed chaincodes on peer:
Package ID: fabcar_1:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3, Label: fabcar_1
我们将在批准链码时使用包ID,所以让我们继续并将其保存为环境变量。将peer lifecycle chaincode queryinstalled
返回的包ID粘贴到下面的命令中。对于所有用户,包ID可能不相同,因此您需要使用从命令窗口返回的包ID来完成此步骤。
CC_PACKAGE_ID=fabcar_1:69de748301770f6ef64b42aa6bb6cb291df20aa39542c3ef94008615704007f3
因为环境变量已经被设置为以Org2管理员的身份操作peer
CLI,所以我们可以批准Fabcar的链码定义为Org2。链码是在组织级别批准的,因此命令只需要针对一个节点。批准通过gossip分发给组织内的其他节点。使用peer lifecycle chaincode approverformyorg命令批准链码定义:
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。当Fabcar链码升级时,序列号将增加到2。该命令还使用--init required
标志请求调用init函数初始化链码,然后再使用其他函数与账本交互。默认情况下,不需要执行Init函数。不需要请求调用Init函数来初始化链码。因为Fabcar链码使用Fabric contract API,所以我们可以通过调用链码中的任何函数来初始化链码,Init函数将在后台被调用。
我们可以向approveformyorg命令提供--signature policy
或--channel config policy
参数来指定链码背书策略。背书策略指定属于不同通道成员的节点需要根据给定的链码验证交易。因为我们没有设置策略,Fabcar的定义将使用默认的背书策略,这要求在提交交易时,交易必须由在场的大多数通道成员背书。这意味着,如果在通道中添加或删除新组织,则会自动更新背书策略,以要求更多或更少的背书。在本教程中,默认策略将需要2取2的多数,交易将需要由来自Org1和Org2的节点认可。如果要指定自定义背书策略,可以使用“背书策略操作指南”了解策略语法。
您需要批准具有管理员角色的标识的链码定义。因此,CORE_PEER_MSPCONFIGPATH
变量需要指向包含管理员标识的MSP文件夹。不能使用客户端用户批准链码定义。需要将批准提交给排序服务,该服务将验证管理员签名,然后将批准分发给您的节点。
我们仍然需要批准链码定义为Org1。将以下环境变量设置为以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。
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链码到通道。虽然只有大多数组织需要批准链码定义(使用默认策略),但所有组织都需要批准链码定义才能在其节点上启动链码。如果在通道成员批准链码之前提交定义,组织将无法背书交易。因此,建议所有通道成员在提交链码定义之前批准链码。
将链码定义提交到通道
在足够多的组织批准了链码定义后,一个组织可以将链码定义提交到通道。如果大多数通道成员已批准该定义,则提交交易将成功,并且在通道上实现链码定义中约定的参数。
您可以使用peer lifecycle chaincode checkcommitreadency命令检查通道成员是否批准了相同的链码定义。用于checkcommitreadency
命令的标志与用于批准组织的链码的标志相同。但是,不需要包含--package id
标志。
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映射,该映射显示通道成员是否已批准checkcommitreadence
命令中指定的参数:
{
"Approvals": {
"Org1MSP": true,
"Org2MSP": true
}
}
由于作为通道成员的两个组织都批准了相同的参数,因此链码定义已准备好提交给通道。可以使用peer lifecycle chaincode commit命令将链码定义提交到通道。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
上面的事务使用--peerAddresses
标志从Org1将peer0.org1.example.com
作为目标,从Org2将peer0.org2.example.com
作为目标。commit
交易被提交给加入通道的节点,以查询由操作节点的组织批准的链码定义。命令需要针对足够多组织的节点,以满足部署链码的策略。因为审批是在每个组织内分发的,所以您可以针对属于通道成员的任何节点。
通道成员的链码定义背书被提交到排序服务,以添加到块中并分发到通道。然后,通道上的节点验证是否有足够数量的组织批准了链码定义。peer lifecycle chaincode commit
命令将在返回响应之前等待节点的验证。
可以使用peer lifecycle chaincode querycommitted命令来确认chaincode定义已提交到通道。
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
命令将返回链码定义的序列和版本:
Committed chaincode definition for chaincode 'fabcar' on channel 'mychannel':
Version: 1, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
调用链码
在将链码定义提交给通道后,链码将从连接到安装链码的通道的节点开始。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":[]}'
如果以下命令响应成功,则应该能够:
2020-02-12 18:22:20.576 EST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
因为我们在链码定义中包含了--init requ