Hyperledger Fabric 2.5.4开发之通道篇[2]
  iwbGD3gmtxyT 2023年11月02日 41 0

Hyperledger Fabric 2.5.4开发之通道篇[2]_配置文件

简介

本篇中,我们将对使用Fabric官方提供的测试网络创建通道的过程作详细分析。

将本教程与测试网络一起使用,首先介绍如何创建一个通道生成块;然后创建一个应用程序通道(用于测试网络中的peer节点加入其中)。

注意:本文不需要设置排序节点,而是利用Fabric示例测试网络中的现成的排序节点。由于测试网络已经为我们部署了一个排序服务和peer节点;所以,本篇仅关注创建通道的过程。

另外,测试网络提供了一个createChannel子命令,可用于测试环境下创建通道;但是,本文将详细解释如何以手动方式创建一个通道,这也是不借助测试网络时必需的过程。

Fabric v2.3引入了在不需要系统通道的情况下创建通道的功能,从而使得创建通道的过程中消除了额外的管理层。

在本文中,我们将使用configtxgen工具创建通道的创世区块,然后使用osnadmin channel命令创建通道。


前提准备

  • 已经成功下载并安装Fabric的fabric-samples示例仓库。
  • 已经成功下载并安装Fabric的二进制文件以及Docker映像。

注意:在本实验过程中,在成功创建一个通道并将Peer节点加入该通道后,还需要将锚Peer节点添加到该通道中,以便服务发现和私有数据正常工作。关于如何在通道上设置锚Peer节点的说明也包含在本教程中,但要求在本地机器上安装jq工具


jq是一个轻量级且灵活的命令行JSON处理器,类似于用于JSON数据的tosed、awk、grep和friends等工具。它是用可移植的C语言编写的,没有运行时依赖性,允许您轻松地对结构化数据进行切片、过滤、映射和转换。

有关jq工具的使用,详见参考材料3中有关.sh脚本文件分析。

(一)启动Fabric测试网络

./network.sh up

此命令将创建一个包含两个Peer节点的Peer组织和拥有一个排序节点的排序组织的Fabric网络。其中,这两个Peer组织将分别操作一个Peer节点,而排序服务管理员将操作仅有的一个排序节点。

上述脚本输出内容在此省略……

但是请注意,两个Peer节点分别在端口7051和9051上运行,而排序节点在端口7050上运行。我们将在后续命令中使用到这些端口。

默认情况下,当启动测试网络时,并不包含任何通道。

(二)准备命令行工具configtxgen

通道是通过两个步骤实现的:

  1. 创建通道的创世区块
  2. 创建通道

在安装Fabric时,configtxgen工具已安装在Fabric samples\bin目录中。

join请求中将创世区块传递给排序服务节点来创建通道。通道创建事务指定通道的初始配置,可以由configtxgen工具创建通道。该工具读取定义通道配置的configtx.yaml文件,然后将相关信息写入通道创建事务,并输出一个包括通道创建事务的创世区块。

(三)准备配置文件configtx.yaml

对于测试网络来说,configtxgen工具使用configtxt\configtx.yaml文件中定义的通道配置文件来创建通道配置,并将其写入Fabric可以读取的protobuf格式。

注意,configtx.yaml文件包含以下信息,我们将使用这些信息来创建一个新通道:

  • 组织(Organizations):Peer节点和排序组织都可以成为通道中的成员。每一个组织都保留一个用于构建通道MSP的加密信息的引用。
  • 排序服务(Ordering service):决定了哪些排序节点将构成网络的排序服务,以及它们将使用一致的共识方法来达成共同的交易订单。本节中还用于定义作为排序服务共识集部分的排序节点。虽然在官方提供的测试网络中,只存在一个排序节点,但在生产网络中,我们建议使用五个排序节点,这样可以允许两个排序节点出现宕机时仍然确保达成共识机制
EtcdRaft:
    Consenters:
    - Host: orderer.example.com
      Port: 7050
      ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
      ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
  • Channel policies:此文件的不同部分共同定义策略,这些策略将决定组织如何与通道交互,以及哪些组织需要批准通道更新。本文中,我们仅使用Fabric使用的默认策略。
  • Channel profiles:每个通道配置文件都引用configtx.yaml文件其他部分的信息来构建通道配置。这些配置文件用于创建应用程序通道的创世区块。请注意,测试网络中的configtx.yaml文件包括一个名为TwoOrgsApplicationGenesis的配置文件,我们将使用它来生成创建通道事务。
TwoOrgsApplicationGenesis:
    <<: *ChannelDefaults
    Orderer:
        <<: *OrdererDefaults
        Organizations:
            - *OrdererOrg
        Capabilities: *OrdererCapabilities
    Application:
        <<: *ApplicationDefaults
        Organizations:
            - *Org1
            - *Org2
        Capabilities: *ApplicationCapabilities

此配置节中包括了两个Peer组织Org1和Org2,还有一个排序组织OrdererOrg。以后可以使用通道更新事务从共识者集中添加或删除其他的排序节点和排序组织。

有关创建configtx.yaml文件的更多细节,请参考本小系列博客的后面文章。

创建通道第一步:创建通道的创世区块

因为我们已经启动了Fabric测试网络,所以我们准备创建一个新的通道。我们已经设置了使用configtxgen工具所需的环境变量。

通道是Fabric网络中交易的隔离机制。通道可以提供一种隔离Peer节点信息的重要机制,只有加入通道的合法组织成员才能接收到通道上的数据,从而隔离未经授权的数据访问,保护数据隐私性。

创世区块是Fabric网络中通道的初始状态。每个通道都有一个创世区块,它包含了一些初始化参数和交易数据。创世区块是通道的起点,同时也是通道账本的第一个区块,它定义了通道的初始状态和规则。

因此,通道和创世区块在Fabric网络中是密切相关的,它们共同定义了Fabric网络中的交易和隔离机制。

运行以下命令为channel1创建通道创世区块:

configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/channel1.block -channelID channel1

在这个命令中,有几项重要参数说明如下:

  • -profile:该命令使用-profile标志(-profile TwoOrgsApplicationGenesis
    )引用configtx.yaml文件中的TwoOrgsApplicationGenesis这个profile节中定义的内容。
  • -outputBlock:该命令的输出是写入文件channel1.block。
  • -channelID:此参数指定即将创建的通道的名称。您可以为通道指定任何想要的名称,但为了便于说明,在本文中我们使用channel1。通道名称必须全部小写,长度少于250个字符,并且与正则表达式[a-z][a-z0-9.-]*匹配。

上述命令运行成功后,可以看到configtxgen加载configtx.yaml文件并打印通道创建事务的日志:

[common.tools.configtxgen] main -> INFO 001 Loading configuration
[common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
[common.tools.configtxgen.localconfig] completeInitialization -> INFO 003 Orderer.EtcdRaft.Options unset, setting to tick_interval:"500ms" election_tick:10 heartbeat_tick:1 max_inflight_blocks:5 snapshot_interval_size:16777216
[common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /Users/fabric-samples/test-network/configtx/configtx.yaml
[common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
[common.tools.configtxgen] doOutputBlock -> INFO 006 Creating application channel genesis block
[common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block

创建通道第二步:创建应用程序通道¶

现在,我们有了通道创世区块,然后就可以很容易地使用:

osnadmin channel join

命令来创建通道了。为了简化后续命令,我们还需要设置一些环境变量,以确定测试网络中节点的证书位置:

export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key

此少部分内容涉及到shell编程有关内容及Fabric测试网络随同的几个.sh文件,详细细节请参考李晓黎老师的《Go语言Hyperledger区块链开发实战》141页有关介绍。

运行以下命令将在排序服务上创建名为channel1的频道。

osnadmin channel join --channelID channel1 --config-block ./channel-artifacts/channel1.block -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
  • --channelID:指定创建通道创世区块时提供的应用程序通道的名称。
  • --config-block:指定使用configtxgen命令创建的通道创世区
    块或最新配置块的位置。
  • -o:指定排序管理端点的主机名和端口。对于测试网络中的排序节点来说,此设置为localhost:7053

此外,由于osnadmin通道命令使用双向TLS通信协议与排序节点通信,因此需要提供以下三个证书:

  • --ca-file:指定排序组织TLS CA根证书的位置和文件名。
  • --client-cert:指定来自TLS CA的管理客户端签名证书的位置和文件名。
  • --client-key:指定TLS CA中管理客户端私钥的位置和文件名。

成功时,命令的输出包含以下内容:

Status: 201
{
	"name": "channel1",
	"url": "/participation/v1/channels/channel1",
	"consensusRelation": "consenter",
	"status": "active",
	"height": 1
}

至此,通道已经处于活动状态,可供Peer节点加入了。

(一)Consenter vs. Follower¶

请注意,排序节点已加入通道(consensusRelation: "consenter")。

如果针对未包含在configtx.yaml文件(或通道配置共识者集合)中在Consenters:列表中的排序节点运行命令,那么,该项将作为follower添加到通道中。要了解有关加入其他排序节点时注意事项的更多信息,请参阅本系列的第一篇(Hyperledger Fabric 2.5.4开发之通道篇[1])中的第三步部分。

(二)Active vs. onboarding¶

一个排序节点可以通过提供通道创世区块或最新的配置块的方式加入到通道中。如果从最新的配置块加入,则排序节点状态将设置为“onboarding”,直到通道分类账赶上指定的配置块,此时该配置块变为“Active”状态。此时,您可以通过提交通道更新事务将排序节点添加到通道共识者集合中,这将导致consensusRelation从follower更改为consenter

创建通道后,接下来的步骤是将Peer节点加入通道并部署智能合约。

列出排序节点上的通道¶

在将Peer节点加入通道之前,您可能需要尝试创建其他的通道。创建更多通道时,osnadmin通道list命令可用于查看排序节点所属的通道。此处使用的参数与上一步骤中的osnadmin通道join命令中使用的参数相同:

osnadmin channel list -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"

此命令的输出类似于:

Status: 200
{
	"systemChannel": null,
	"channels": [
		{
			"name": "channel1",
			"url": "/participation/v1/channels/channel1"
		}
	]
}

将Peer节点加入通道(即:向通道中添加组织)¶

测试网络包括两个Peer组织,每个组织有一个Peer节点。但是,在使用peer CLI命令之前,我们需要设置一些环境变量,以指定我们作为哪个用户(客户端MSP)以及我们的目标Peer节点。设置以下环境变量以指示我们充当Org1管理员并针对Org1 Peer节点。

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 CLI命令行,我们还需要修改FABRIC_CONFIG_PATH:

export FABRIC_CFG_PATH=$PWD/../config/

要把测试网络中的peer节点从Org1加入到通道channel1,只需在加入请求中传递创世区块:

peer channel join -b ./channel-artifacts/channel1.block

成功时,此命令的输出包含以下内容:

[channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
[channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

我们为Org2中的peer节点重复这些步骤。设置以下环境变量以方便作为Org2管理员操作peer CLI。环境变量还将Org2 peer,peer0.Org2.example.com,设置为目标peer。

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

现在重复该命令,将peer节点从Org2加入channel1:

peer channel join -b ./channel-artifacts/channel1.block

成功时,此命令的输出包含以下内容:

[channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
[channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

设置锚点Peer节点¶

最后,在一个组织将其Peer节点加入到目标通道后,应该至少选择一个Peer节点作为锚节点。为了利用诸如私有数据和服务发现之类的功能,需要锚节点。

每个组织都应该在一个通道上设置多个Peer锚点,以便实现冗余。

有关gossip协议和锚节点的更多信息,请参阅官方文档“Gossip数据传播协议”。

每个组织的锚Peer节点的端点信息都包括在通道配置文件中。每个通道成员都可以通过更新通道来指定其锚Peer节点。接下来,我们将使用configtxlator这个CLI工具来更新通道配置,并为Org1和Org2选择一个锚Peer节点。

注意:

如果您的本地机器上还没有安装jq,您需要立即安装它来完成后面这些步骤。

首先,我们从Org1中选择一个peer作为锚点peer。第一步是使用peer channel fetch命令获取最新的通道配置块信息。为此,需要设置以下环境变量,以便作为Org1管理员来使用peer CLI工具进行操作:

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 channel fetch config channel-artifacts/config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "$ORDERER_CA"

因为最新近的通道配置块是通道创世区块,所以命令将从通道返回块0

[channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
[cli.common] readBlock -> INFO 002 Received block: 0
[channelCmd] fetch -> INFO 003 Retrieving last config block: 0
[cli.common] readBlock -> INFO 004 Received block: 0

通道配置块config_block.pb存储在channel-artifacts文件夹中,以便使更新过程与其他内容分离开来。

接下来,切换到channel-artifacts文件夹以完成下一步操作:

cd channel-artifacts

现在,我们可以开始使用来处理通道配置。

第一步是将protobuf中的块解码为可以读取和编辑的JSON对象。使用下面命令会过滤掉琐碎的块数据,只留下重点的通道配置信息。

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq '.data.data[0].payload.data.config' config_block.json > config.json

这些命令将通道配置块转换为一个精简的JSON config.JSON,此文件将作为我们接下来更新操作的基础内容。因为我们不想直接编辑这个文件,所以我们会制作一个可以编辑的副本。我们将在未来的步骤中使用原始的通道配置。

cp config.json config_copy.json

您可以使用jq工具将Org1的锚Peer节点添加到通道配置中。

jq '.channel_group.groups.Application.groups.Org1MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org1.example.com","port": 7051}]},"version": "0"}}' config_copy.json > modified_config.json

在这一步之后,我们在modified_config.JSON文件中获得了JSON格式的通道配置的更新版本。

现在,我们可以使用configtxlator工具将原始和修改后的通道配置转换回protobuf格式,并计算它们之间的差异。

configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb

新的protobuf文件名为config_update.pb,它包含我们需要应用于通道配置的锚节点更新信息。我们可以将配置更新封装在一个交易信封中,以创建通道配置更新交易。

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

现在,我们可以使用最后一个文件config_update_in_envelope.pb,实现更新通道。切换回test-network目录:

cd ..

我们可以通过向peer channel update命令提供新的通道配置来添加锚节点。因为我们正在更新只影响Org1的通道配置的部分内容,所以其他通道成员不需要批准通道更新。

peer channel update -f channel-artifacts/config_update_in_envelope.pb -c channel1 -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"

当通道更新成功时,您应该看到以下响应:

[channelCmd] update -> INFO 002 Successfully submitted channel update

我们还可以将Org2中的Peer节点设置为锚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_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
export CORE_PEER_ADDRESS=localhost:9051

接下来,拉出最新的通道配置块,它现在是通道上的第二个块:

peer channel fetch config channel-artifacts/config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"

切换回channel-artifacts目录:

cd channel-artifacts

然后,解码并复制配置块。

configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
jq '.data.data[0].payload.data.config' config_block.json > config.json
cp config.json config_copy.json

将加入通道的Org2 Peer节点添加为通道配置中的锚节点:

jq '.channel_group.groups.Application.groups.Org2MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org2.example.com","port": 9051}]},"version": "0"}}' config_copy.json > modified_config.json

现在,我们将原始和更新后的通道配置信息转换回protobuf文件格式,并计算它们之间的差异。

configtxlator proto_encode --input config.json --type common.Config --output config.pb
configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb

将配置更新封装在交易信封中,以便创建新的通道配置更新交易:

configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb

切换到test-network目录下:

cd ..

执行以下命令,更新通道并设置Org2锚节点:

peer channel update -f channel-artifacts/config_update_in_envelope.pb -c channel1 -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"

如果您想了解有关如何提交通道更新请求的更多信息,请参阅官方文档更新通道配置

您可以通过运行peer channel info命令来确认通道是否已成功更新:

peer channel getinfo -c channel1

现在,通过在通道创世区块中添加两个通道配置块来更新通道。注意,此时通道的高度将增加到三个,散列值也得到更新:

Blockchain info: {"height":3,"currentBlockHash":"GKqqk/HNi9x/6YPnaIUpMBlb0Ew6ovUnSB5MEF7Y5Pc=","previousBlockHash":"cl4TOQpZ30+d17OF5YOk/mtMjJpUXiJmtw8+sON8a8="}

将链码部署到新通道¶

我们可以通过向通道部署链代码来检验一下通道是否已成功创建。我们可以使用network.sh脚本将官方示例项目中的基本资产转移链代码部署到任何一个测试网络中的通道上。使用以下命令就可以将链代码部署到我们的新通道:

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

运行该命令后,应该会在日志中看到部署到通道的链代码。

Committed chaincode definition for chaincode 'basic' on channel 'channel1':
Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
Query chaincode definition successful on peer0.org2 on channel 'channel1'
Chaincode initialization is not required

然后,运行以下命令可以初始化分类帐上的一些资产:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "$ORDERER_CA" -C channel1 -n basic --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":[]}'

成功后,您将看到:

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

通过发出以下查询命令,可以确认资产是否已成功地添加到分类账中:

peer chaincode query -C channel1 -n basic -c '{"Args":["getAllAssets"]}'

成功运行的话,应该看到类似于以下内容的输出:

[{"ID":"asset1","color":"blue","size":5,"owner":"Tomoko","appraisedValue":300},
{"ID":"asset2","color":"red","size":5,"owner":"Brad","appraisedValue":400},
{"ID":"asset3","color":"green","size":10,"owner":"Jin Soo","appraisedValue":500},
{"ID":"asset4","color":"yellow","size":10,"owner":"Max","appraisedValue":600},
{"ID":"asset5","color":"black","size":15,"owner":"Adriana","appraisedValue":700},
{"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}]

在自己搭建的Fabric网络上创建通道¶

归纳一下的话,本篇介绍了使用osnadmin channel join命令在官方测试网络上创建一个通道的基本步骤。如果您准备好构建自己的Fabric网络的话,建议按照本系列第一篇(Hyperledger Fabric 2.5.4开发之通道篇[1])中的步骤了解有关使用osnadmin channel命令的更多信息。

重要参考




【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
iwbGD3gmtxyT