在智能合约开发过程中,开发人员需要一种快速、迭代地测试链码包的方法,而无需为每次修改运行链码生命周期命令。
使用 Fabric 二进制文件并启动peer处于开发模式("DevMode"),然后将链码连接到peer。它允许您启动链代码,而无需在peer在链码最初提交到通道后,您可以绕过peer生命周期链码命令。这允许快速部署、调试和更新,而无需重新发布peer每次进行更新时生命周期链码命令。
注意:为了在peer,必须在网络中的所有节点上禁用 TLS 通信。由于强烈建议在生产网络中使用 TLS 通信,因此您永远不应该运行生产网络peer在开发模式中。
所有命令都是从fabric/文件夹中执行的。它使用所有默认设置peer和orderer并根据需要使用命令行中的环境变量覆盖配置。默认情况下不需要修改peercore.yaml或ordererorderer.yaml文件。
准备环境
1.克隆fabric代码
从GitHub克隆 Fabric 存储库。根据需要选择发布分支。
bash
$ git clone https://github.com/hyperledger/fabric
$ cd fabric
2.构建order、peer和configtxgen
运行以下命令来构建二进制文件orderer,peer和 configtxgen:
bash
$ make orderer peer configtxgen
Building build/bin/orderer
GOBIN=/home/along/go/src/github.com/Hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=2.5.9 -X github.com/hyperledger/fabric/common/metadata.CommitSHA=2e4078eb7 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger" -buildvcs=false github.com/hyperledger/fabric/cmd/orderer
Building build/bin/peer
GOBIN=/home/along/go/src/github.com/Hyperledger/fabric/build/bin go install -tags "" -ldflags "-X github.com/hyperledger/fabric/common/metadata.Version=2.5.9 -X github.com/hyperledger/fabric/common/metadata.CommitSHA=2e4078eb7 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger" -buildvcs=false github.com/hyperledger/fabric/cmd/peer
make: Nothing to be done for 'configtxgen'.
成功后,您应该看到类似以下内容的结果:
bash
$ ls build/bin/
configtxgen configtxlator cryptogen orderer peer
3.设置环境变量
设置PATH环境变量以包含orderer和peer二进制文件:
bash
export PATH=$(pwd)/build/bin:$PATH
将FABRIC_CFG_PATH环境变量设置为指向sampleconfig文件夹:
bash
export FABRIC_CFG_PATH=$(pwd)/sampleconfig
4.创建数据目录
在/var目录中创建hyperledger子目录。
这是 Fabric 用于存储块的默认位置,如order的orderer.yaml和peer 的core.yaml文件。要创建hyperledger子目录,请执行以下命令,并将问号替换为您的用户名:
bash
sudo mkdir /var/hyperledger
sudo chown ????? /var/hyperledger
5.configtxgen生成创世块
生成创世块ordering服务。
运行以下命令生成创世块并将其存储在$(pwd)/sampleconfig/genesisblock
中,以便可供使用orderer在下一步中,当orderer已开始。
bash
$ configtxgen -profile SampleDevModeSolo -channelID syschannel -outputBlock genesisblock -configPath $FABRIC_CFG_PATH -outputBlock "$(pwd)/sampleconfig/genesisblock"
2024-08-09 14:50:07.619 CST 0001 INFO [common.tools.configtxgen] main -> Loading configuration
2024-08-09 14:50:07.653 CST 0002 INFO [common.tools.configtxgen.localconfig] completeInitialization -> orderer type: solo
2024-08-09 14:50:07.653 CST 0003 INFO [common.tools.configtxgen.localconfig] Load -> Loaded configuration: /home/along/go/src/github.com/Hyperledger/fabric/sampleconfig/configtx.yaml
2024-08-09 14:50:07.658 CST 0004 INFO [common.tools.configtxgen] doOutputBlock -> Generating genesis block
2024-08-09 14:50:07.658 CST 0005 INFO [common.tools.configtxgen] doOutputBlock -> Creating system channel genesis block
2024-08-09 14:50:07.659 CST 0006 INFO [common.tools.configtxgen] doOutputBlock -> Writing genesis block
成功后,您应该看`到类似以下内容的结果:
bash
$ ls sampleconfig/
configtx.yaml core.yaml core.yaml.bak genesisblock msp orderer.yaml
sampleconfig目录新增了genesisblock文件。
启动orderer节点
运行以下命令来启动orderer使用SampleDevModeSolo配置文件并启动ordering服务:
bash
ORDERER_GENERAL_GENESISPROFILE=SampleDevModeSolo orderer
在这条命令中,我们看到了几个关键部分,它们是Hyperledger Fabric中与配置和操作相关的:
-
ORDERER_GENERAL_GENESISPROFILE
:- 这是一个环境变量,用于设置Hyperledger Fabric中的创世区块配置文件(Genesis profile)。在Fabric网络中,创世区块是链的第一个区块,它定义了链的初始状态和配置。
-
SampleDevModeSolo
:- 这是创世区块配置文件的名称。在Fabric中,可以通过不同的配置文件来定义不同数量和类型的节点,以及它们如何相互通信。
SampleDevModeSolo
通常是一个单节点的配置文件,用于开发模式,它配置了一个单一的排序服务节点(orderer)。
- 这是创世区块配置文件的名称。在Fabric中,可以通过不同的配置文件来定义不同数量和类型的节点,以及它们如何相互通信。
-
orderer
:- 这是执行命令的主体,即Fabric中的排序服务节点。排序服务节点负责接收来自应用的交易请求,并将它们排序形成区块,然后发送给网络中的其他节点。
-
命令结构:
- 命令的结构表明它可能是在shell环境中设置环境变量,然后启动或配置排序服务节点。这种命令通常在启动Fabric网络或排序服务节点的脚本中看到。
-
命令的目的:
- 这条命令的目的是指定排序服务节点在启动时使用
SampleDevModeSolo
配置文件。这通常用于开发或测试环境,因为它简化了网络的配置,只使用一个排序服务节点。
- 这条命令的目的是指定排序服务节点在启动时使用
判断启动是否成功
启动成功能看到下面的信息:
bash
2024-08-09 14:53:39.515 CST 000d INFO [orderer.common.server] Main -> Starting orderer:
Version: 2.5.9
Commit SHA: 2e4078eb7
Go version: go1.22.5
OS/Arch: linux/amd64
2024-08-09 14:53:39.516 CST 000e INFO [orderer.common.server] Main -> Beginning to serve requests
启动peer节点
打开另一个终端窗口并设置所需的环境变量以覆盖peer配置并启动peer节点。
注意:如果您打算保留orderer和peer在同一环境中(不在单独的容器中),然后才设置CORE_OPERATIONS_LISTENADDRESS
环境变量(端口可以是除 9443 之外的任何端口)。
bash
export CORE_OPERATIONS_LISTENADDRESS=127.0.0.1:9444
带着--peer-chaincodedev=true
参数启动peer,peer将进入开发模式。
bash
export PATH=$(pwd)/build/bin:$PATH
export FABRIC_CFG_PATH=$(pwd)/sampleconfig
FABRIC_LOGGING_SPEC=chaincode=debug CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052 peer node start --peer-chaincodedev=true
提醒:在DevMode下运行时,无法启用 TLS。
判断启动是否成功
成功后,您应该看到类似以下内容的结果:
bash
2024-08-09 16:56:05.391 CST 003c INFO [nodeCmd] serve -> Discovery service activated
2024-08-09 16:56:05.391 CST 003d INFO [nodeCmd] serve -> Starting peer with Gateway enabled
2024-08-09 16:56:05.391 CST 003e INFO [nodeCmd] serve -> Starting peer with ID=[jdoe], network ID=[dev], address=[192.168.0.2:7051]
2024-08-09 16:56:05.391 CST 003f INFO [nodeCmd] serve -> Started peer with ID=[jdoe], network ID=[dev], address=[192.168.0.2:7051]
创建channel并加入peer
创建channel
打开另一个终端窗口并运行以下命令以使用configtxgen工具生成通道创建交易。此命令使用SampleSingleMSPChannel配置文件创建通道ch1 :
bash
export PATH=$(pwd)/build/bin:$PATH
export FABRIC_CFG_PATH=$(pwd)/sampleconfig
configtxgen -channelID ch1 -outputCreateChannelTx ch1.tx -profile SampleSingleMSPChannel -configPath $FABRIC_CFG_PATH
peer channel create -o 127.0.0.1:7050 -c ch1 -f ch1.tx
2024-08-09 15:22:39.209 CST 0001 INFO [common.tools.configtxgen] main -> Loading configuration
2024-08-09 15:22:39.242 CST 0002 INFO [common.tools.configtxgen.localconfig] Load -> Loaded configuration: /home/along/go/src/github.com/Hyperledger/fabric/sampleconfig/configtx.yaml
2024-08-09 15:22:39.243 CST 0003 INFO [common.tools.configtxgen] doOutputChannelCreateTx -> Generating new channel configtx
2024-08-09 15:22:39.244 CST 0004 INFO [common.tools.configtxgen] doOutputChannelCreateTx -> Writing new channel tx
2024-08-09 15:22:39.324 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
2024-08-09 15:22:39.344 CST 0002 INFO [cli.common] readBlock -> Received block: 0
peer加入channel
现在加入peer通过运行以下命令进入频道:
bash
$ peer channel join -b ch1.block
2024-08-09 15:23:06.505 CST 0001 INFO [channelCmd] InitCmdFactory -> Endorser and orderer connections initialized
2024-08-09 15:23:06.529 CST 0002 INFO [channelCmd] executeJoin -> Successfully submitted proposal to join channel
这peer现已加入channel ch1。
链码
1.构建链码
我们使用fabric/integration/chaincode
目录中的简单链代码来演示如何在 DevMode 中运行链代码包。在与上一步相同的终端窗口中,运行以下命令来构建链代码:
bash
$ go build -o simpleChaincode ./integration/chaincode/simple/cmd
2.启动链码
当DevMode启用时peer, CORE_CHAINCODE_ID_NAME
环境变量必须设置为<CHAINCODE_NAME> : <CHAINCODE_VERSION>
否则,peer无法找到链码。对于本示例,我们将其设置为mycc:1.0 。运行以下命令启动链代码并将其连接到peer:
bash
$ CORE_CHAINCODE_LOGLEVEL=debug CORE_PEER_TLS_ENABLED=false CORE_CHAINCODE_ID_NAME=mycc:1.0 ./simpleChaincode -peer.address 127.0.0.1:7052
因为我们设置了调试日志记录peer当我们启动它时,可以确认链码注册成功。在你的peer日志,您应该看到类似以下内容的结果:
bash
2024-08-09 16:12:18.458 CST 0046 DEBU [chaincode] Register -> registered handler complete for chaincode mycc:1.0
2024-08-09 16:12:18.458 CST 0047 DEBU [chaincode] HandleRegister -> Got REGISTER for chaincodeID = mycc:1.0, sending back REGISTERED
2024-08-09 16:12:18.458 CST 0048 DEBU [chaincode] HandleRegister -> Changed state to established for mycc:1.0
2024-08-09 16:12:18.458 CST 0049 DEBU [chaincode] sendReady -> sending READY for chaincode mycc:1.0
2024-08-09 16:12:18.458 CST 004a DEBU [chaincode] sendReady -> Changed to state ready for chaincode mycc:1.0
3.批准并提交链码
现在,您需要运行以下 Fabric 链码生命周期命令来批准链码定义并将其提交到通道:
bash
# 批准链码
$ peer lifecycle chaincode approveformyorg -o 127.0.0.1:7050 --channelID ch1 --name mycc --version 1.0 --sequence 1 --init-required --signature-policy "OR ('SampleOrg.member')" --package-id mycc:1.0
2024-08-09 16:14:40.884 CST 0001 INFO [chaincodeCmd] ClientWait -> txid [3903a7765184f2b5de054898e0435fd2e52a06dafce2a3d56ddf92ea52d469c3] committed with status (VALID) at 0.0.0.0:7051
#检查链码批准状态
$ peer lifecycle chaincode checkcommitreadiness -o 127.0.0.1:7050 --channelID ch1 --name mycc --version 1.0 --sequence 1 --init-required --signature-policy "OR ('SampleOrg.member')"
Chaincode definition for chaincode 'mycc', version '1.0', sequence '1' on channel 'ch1' approval status by org:
SampleOrg: true
# 提交链码
$ peer lifecycle chaincode commit -o 127.0.0.1:7050 --channelID ch1 --name mycc --version 1.0 --sequence 1 --init-required --signature-policy "OR ('SampleOrg.member')" --peerAddresses 127.0.0.1:7051
2024-08-09 16:15:01.363 CST 0001 INFO [chaincodeCmd] ClientWait -> txid [91d4e807d0294a006554fce4e4f94e6aede47a4ae26be25a4d0658daeaf52970] committed with status (VALID) at 127.0.0.1:7051
4.调用链码
4.1初始化链码
bash
$ CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["init","a","100","b","200"]}' --isInit
2024-08-09 16:15:10.146 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200
along@iv-ydasjmjawwwh2yowmoe5:~/go/src/github.com/Hyperledger/fabric$ CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["invoke","a","b","10"]}'
2024-08-09 16:15:18.767 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200
along@iv-ydasjmjawwwh2yowmoe5:~/go/src/github.com/Hyperledger/fabric$ CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["query","a"]}'
2024-08-09 16:15:25.775 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200 payload:"90"
4.2调用
bash
$ CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["query","a"]}'
2024-08-09 16:19:32.293 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200 payload:"90"
$ CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["invoke","a","b","10"]}'
2024-08-09 17:11:09.597 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200
along@iv-ydasjmjawwwh2yowmoe5:~/go/src/github.com/Hyperledger/fabric$ CORE_PEER_ADDRESS=127.0.0.1:7051 peer chaincode invoke -o 127.0.0.1:7050 -C ch1 -n mycc -c '{"Args":["query","a"]}'
2024-08-09 17:16:42.540 CST 0001 INFO [chaincodeCmd] chaincodeInvokeOrQuery -> Chaincode invoke successful. result: status:200 payload:"80"
总结
现在可以迭代地更新智能合约、保存更改、构建链代码,然后使用上述步骤再次启动链码。您不需要运行peer每次进行更改时都会更新链代码的生命周期命令(批准、提交)。