创建一个新的channel

创建一个新的channel

官方文档

You can use this tutorial to learn how to create new channels using the configtxgen CLI tool and then use the peer channel commands to join a channel with your peers. While this tutorial will leverage the Fabric test network to create the new channel, the steps in this tutorial can also be used by network operators in a production environment.

你可以通过这个教程来学习通过 configtxgenCLI工具来创建新的通道,然后通过 peer channel 命令将peer节点加入通道。尽管本教程将利用Fabric测试网络来创建新渠道,网络操作人员也可以在生产环境中使用本教程中的步骤。

In the process of creating the channel, this tutorial will take you through the following steps and concepts:

在创建频道的过程中,本教程将带您完成以下步骤和概念:

Setting up the configtxgen tool(设置configtxgen工具)

Channels are created by building a channel creation transaction and submitting the transaction to the ordering service. The channel creation transaction specifies the initial configuration of the channel and is used by the ordering service to write the channel genesis block. While it is possible to build the channel creation transaction file manually, it is easier to use the configtxgen tool. The tool works by reading a configtx.yaml file that defines the configuration of your channel, and then writing the relevant information into the channel creation transaction. Before we discuss the configtx.yaml file in the next section, we can get started by downloading and setting up the configtxgen tool.

通道的创建是通过构建一个创建通道的交易然后将此交易提交给排序服务来完成的。“创建通道的交易”指明了此通道的初始化配置并且由排序服务写入通道的创世纪区块中。尽管可以手动构建“创建通道的交易”,但使用configtxgen工具更容易。configtxgen工具读取定义了channle配置的configtx.yaml文件,然后将相关信息写入“创建通道的交易”中。在我们讨论 configtx.yaml 文件之前,我们先开始下载并设置configtxgen 工具。

You can download the configtxgen binaries by following the steps to install the samples, binaries and Docker images. configtxgen will be downloaded to the bin folder of your local clone of the fabric-samples repository along with other Fabric tools.

你可以跟着 install the samples, binaries and Docker images的步骤来下载 configtxgenconfigtxgen 会下载到fabric-samples仓库的bin目录下。

For the purposes of this tutorial, we will want to operate from the test-network directory inside fabric-samples. Navigate to that directory using the following command:

为了本教程的目的,我们会想要在fabric-samples下面的 test-network 目录下进行操作,使用下面的命令切换到此目录:

1
cd fabric-samples/test-network

We will operate from the test-network directory for the remainder of the tutorial. Use the following command to add the configtxgen tool to your CLI path:

在本教程的其余部分中,我们将从test-network目录进行操作。使用以下命令将configtxgen工具添加到您的CLI路径:

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

In order to use configtxgen, you need to the set the FABRIC_CFG_PATH environment variable to the path of the directory that contains your local copy of the configtx.yaml file. For this tutorial, we will reference the configtx.yaml used to setup the Fabric test network in the configtx folder:

为了使用configtxgen,您需要将FABRIC_CFG_PATH环境变量设置为包含configtx.yaml的本地目录。对于本教程,我们将在此环境变量设置为在Fabric test network目录下的包含configtx.yamlconfigtx 目录:

1
export FABRIC_CFG_PATH=${PWD}/configtx

You can check that you can are able to use the tool by printing the configtxgen help text:

你可以通过打印 configtxgen工具的help来检查是否已经设置好:

1
configtxgen --help

The configtx.yaml file(configtx.yaml文件)

The configtx.yaml file specifies the channel configuration of new channels. The information that is required to build the channel configuration is specified in a readable and editable form in the configtx.yaml file. The configtxgen tool uses the channel profiles defined in the configtx.yaml file to create the channel configuration and write it to the protobuf format that can be read by Fabric.

configtx.yaml 文件指明了一个新的通道的通道配置。在configtx.yaml文件中可以读取和编辑构建通道配置所需的信息。 configtxgen 工具通过使用 configtx.yaml文件中的通道属性的定义来创建通道配置,并将其写入可由Fabric读取的 protobuf格式

You can find the configtx.yaml file that is used to deploy the test network in the configtx folder in the test-network directory. The file contains the following information that we will use to create our new channel:

你可以在test-network目录的configtx 文件夹下面看到 configtx.yaml 文件,这个文件包含在创建新通道时会用到的下面的信息:

  • Organizations: The organizations that can become members of your channel. Each organization has a reference to the cryptographic material that is used to build the channel MSP.

    • 可以成为你的通道成员的组织信息,每一个组织都有对用于构建通道MSP的加密材料的引用。
  • Ordering service: Which ordering nodes will form the ordering service of the network, and consensus method they will use to agree to a common order of transactions. The file also contains the organizations that will become the ordering service administrators.

    • 哪些排序节点将形成网络中的排序服务,以及它们用于同意交易顺序的共识方法。此文件还包含了会成为排序服务管理员的组织的信息。
  • Channel policies: Different sections of the file work together to define the policies that will govern how organizations interact with the channel and which organizations need to approve channel updates. For the purposes of this tutorial, we will use the default policies used by Fabric.

    • 文件的不同部分一起定义通道策略,这些策略将控制组织与通道的交互方式以及哪些组织需要批准渠道更新。就本教程而言,我们将使用Fabric使用的默认策略。
  • Channel profiles Each channel profile references information from other sections of the configtx.yaml file to build a channel configuration. The profiles are used the create the genesis block of the orderer system channel and the channels that will be used by peer organizations. To distinguish them from the system channel, the channels used by peer organizations are often referred to as application channels.

    • 每个通道的配置信息都引用configtx.yaml文件的其他部分来构建通道配置。这些配置信息是用来创建orderer system channel 的创世纪区块的,然后通道会被同等的其他组织所使用。为了将它们(orderer system channel)与系统通道区分开来,组织使用的通道通常称为应用程序通道。

    The configtxgen tool uses configtx.yaml file to create a complete genesis block for the system channel. As a result, the system channel profile needs to specify the full system channel configuration. The channel profile used to create the channel creation transaction only needs to contain the additional configuration information required to create an application channel.

configtxgen工具使用configtx.yaml文件为系统通道创建完整的创世块。结果,系统通道配置文件需要指定完整的系统通道配置。用于创建“创建通道的交易”使用的通道配置仅需要包含创建应用程序通道所需的其他配置信息。

You can visit the Using configtx.yaml to create a channel genesis block tutorial to learn more about this file. For now, we will return to the operational aspects of creating the channel, though we will reference parts of this file in future steps.

你可以访问 Using configtx.yaml to create a channel genesis block 教程来学习此文件的更多信息。现在我们回到创建通道的操作方面。

Start the network(启动网络)

参考Fabric测试网络使用

Our instance of the test network was deployed without creating an application channel. However, the test network script creates the system channel when you issue the ./network.sh up command. Under the covers, the script uses the configtxgen tool and the configtx.yaml file to build the genesis block of the system channel. Because the system channel is used to create other channels, we need to take some time to understand the orderer system channel before we can create an application channel.

我们部署的测试网络实例未创建应用程序通道。但是测试网络脚本在你运行./network.sh up 命令时创建了系统通道。在幕后,脚本使用configtxgen工具和configtx.yaml文件来构建系统通道的创世纪块。因为系统通道是用来创建其他通道的,所以我们在创建一个应用通道之前需要花一些时间去了解排序系统通道( orderer system channel

The orderer system channel(排序系统通道)

Creating an application channel(创建一个应用通道)

Now that we have deployed the nodes of the network and created the orderer system channel using the network.sh script, we can start the process of creating a new channel for our peer organizations. We have already set the environment variables that are required to use the configtxgen tool. Run the following command to create a channel creation transaction for channel1:

现在我们已经使用network.sh脚本在测试网络中部署了节点,并且创建了排序系统通道。我们现在可以开始为我们的组织创建一个新通道的程序了。我们已经设置了使用configtxgen工具所需的环境变量。运行下面的程序来为channel1通道创建一个“创建通道的交易”:

1
configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel1.tx -channelID channel1

The -channelID will be the name of the future channel. Channel names must be all lower case, less than 250 characters long and match the regular expression [a-z][a-z0-9.-]*. The command uses the uses the -profile flag to reference the TwoOrgsChannel: profile from configtx.yaml that is used by the test network to create application channels:

-channelID标志制定了创建的通道的名称,通道的名称必须全是小写,不超过250个字符并且符合正则表达式[a-z][a-z0-9.-]*。该命令使用-profile标志来引用configtx.yaml文件中的TwoOrgsChannel:配置,测试网络使用它来创建应用程序通道:

1
2
3
4
5
6
7
8
9
10
TwoOrgsChannel:
Consortium: SampleConsortium
<<: *ChannelDefaults
Application:
<<: *ApplicationDefaults
Organizations:
- *Org1
- *Org2
Capabilities:
<<: *ApplicationCapabilities

The profile references the name of the SampleConsortium from the system channel, and includes both peer organizations from the consortium as channel members. Because the system channel is used as a template to create the application channel, the ordering nodes defined in the system channel become the default consenter set of the new channel, while the administrators of the ordering service become the orderer administrators of the channel. Ordering nodes and ordering organizations can be added or removed from the consenter set using channel updates.

该配置文件从系统通道引用SampleConsortium的名称,并且包含来自该联盟的两个组织作为通道成员。因为系统通道被用作模版来创建应用通道,系统通道中定义的排序节点成为新渠道的默认consenter set,而排序服务的管理员将成为新渠道的排序管理员。可以使用通道更新在consenter set中添加或删除排序节点和排序组织。

If the command successful, you will see logs of configtxgen loading the configtx.yaml file and printing a channel creation transaction:

如果上面的命令执行成功,你会看到configtxgen 工具加载 configtx.yaml 文件并且打印了一个创建通道的交易:

1
2
3
4
2020-12-23 14:25:49.175 CST [common.tools.configtxgen] main -> INFO 001 Loading configuration
2020-12-23 14:25:49.185 CST [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /Users/apple/code/open-source/blockchain/hyperledger/fabric-samples/test-network/configtx/configtx.yaml
2020-12-23 14:25:49.185 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx
2020-12-23 14:25:49.188 CST [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx

We can use the peer CLI to submit the channel creation transaction to the ordering service. To use the peer CLI, we need to set the FABRIC_CFG_PATH to the core.yaml file located in the fabric-samples/config directory. Set the FABRIC_CFG_PATH environment variable by running the following command:

你可以使用 peerCLI来把这个“创建通道的交易”提交到排序服务。为了使用peer CLI,我们需要设置环境变量FABRIC_CFG_PATHfabric-samples/config 目录下的core.yaml文件,运行下面的命令来设置FABRIC_CFG_PATH环境变量:

1
export FABRIC_CFG_PATH=$PWD/../config/

Before the ordering service creates the channel, the ordering service will check the permission of the identity that submitted the request. By default, only admin identities of organizations that belong to the system channel consortium can create a new channel. Issue the commands below to operate the peer CLI as the admin user from Org1:

在排序服务创建通道时,排序服务会检查提交请求的身份的权限。默认情况下,只有属于系统通道联盟的组织的管理员身份才能创建新的通道。运行下面的命令来以Org1的管理员身份操作 peer CLI:

1
2
3
4
5
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

You can now create the channel by using the following command:

你现在可以使用下面的命令来创建通道了:

1
peer channel create -o localhost:7050  --ordererTLSHostnameOverride orderer.example.com -c channel1 -f ./channel-artifacts/channel1.tx --outputBlock ./channel-artifacts/channel1.block --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

The command above provides the path to the channel creation transaction file using the -f flag and uses the -c flag to specify the channel name. The -o flag is used to select the ordering node that will be used to create the channel. The --cafile is the path to the TLS certificate of the ordering node. When you run the peer channel create command, the peer CLI will generate the following response:

上面的命令使用 -f标志来指定“创建通道的交易”的文件,并且使用 -c 标志来指定通道名称。-o标志是用来选择用来创建通道的排序节点的。--cafile 标志是排序节点的TLS证书路径。当你运行 peer channel create命令时, peer CLI会生成下面的响应:

1
2
2020-12-23 14:36:09.386 CST [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized
2020-12-23 14:36:09.595 CST [cli.common] readBlock -> INFO 00c Received block: 0

Because we are using a Raft ordering service, you may get some status unavailable messages that you can safely ignore. The command will return the genesis block of the new channel to the location specified by the --outputBlock flag.

因为我们使用一个Raft策略的排序服务,你可能会收到一些状态不可用的信息你可以放心的忽略他们。该命令会将新通道的创世纪区块输出到--outputBlock标志指定的位置。

Join peers to the channel(把节点加入通道中)

After the channel has been created, we can join the channel with our peers. Organizations that are members of the channel can fetch the channel genesis block from the ordering service using the peer channel fetch command. The organization can then use the genesis block to join the peer to the channel using the peer channel join command. Once the peer is joined to the channel, the peer will build the blockchain ledger by retrieving the other blocks on the channel from the ordering service.

在通道创建之后,我们可以把我们的peer节点加入到通道。属于通道成员的组织可以使用 peer channel fetch命令从排序服务那里获取通道的创世纪区块。然后这个组织就可以使用这个创世纪区块来通过 peer channel join 命令将peer节点加入到通道了。一旦peer节点加入了通道,peer节点将通过从排序服务中检索其他区块来构建区块链账本了。

Since we are already operating the peer CLI as the Org1 admin, let’s join the Org1 peer to the channel. Since Org1 submitted the channel creation transaction, we already have the channel genesis block on our file system. Join the Org1 peer to the channel using the command below.

因为我们已经通过Org1的管理员操作了 peer CLI ,让我们把Org1的peer节点加入到通道。因为是Org1组织提交的“创建通道的交易”,我们已经在我们本地的文件系统中拥有了通道的创世纪区块。使用下面的命令将组织Org1的peer节点加入到通道中:

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

The CORE_PEER_ADDRESS environment variable has been set to target peer0.org1.example.com. A successful command will generate a response from peer0.org1.example.com joining the channel:

环境变量CORE_PEER_ADDRESS已经设置为指向了peer0.org1.example.com,如果命令成功的话会获取 peer0.org1.example.com 加入通道的响应:

1
2
2020-03-06 17:49:09.903 EST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-03-06 17:49:10.060 EST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel

我本地的运行报错如下,记录TODO,最终使用最新2.3.0的版本就没有这个问题。2.2.0版本没有成功启动org1的peer。

1
2
3
4
5
(base) apple@WHOAMIdeMacBook-Pro:~/code/open-source/blockchain/hyperledger/fabric-samples/test-network$     peer channel join -b ./channel-artifacts/channel1.block
2020-12-23 14:59:02.760 CST [comm.tls] ClientHandshake -> ERRO 001 Client TLS handshake failed after 2.782623ms with error: EOF remoteaddress=[::1]:7051
2020-12-23 14:59:03.768 CST [comm.tls] ClientHandshake -> ERRO 002 Client TLS handshake failed after 2.438885ms with error: EOF remoteaddress=[::1]:7051
2020-12-23 14:59:05.075 CST [comm.tls] ClientHandshake -> ERRO 003 Client TLS handshake failed after 1.857716ms with error: EOF remoteaddress=[::1]:7051
Error: error getting endorser client for channel: endorser client failed to connect to localhost:7051: failed to create new connection: context deadline exceeded

You can verify that the peer has joined the channel using the peer channel getinfo command:

你可以使用 peer channel getinfo 命令来验证peer节点已经加入了通道:

1
peer channel getinfo -c channel1

The command will list the block height of the channel and the hash of the most recent block. Because the genesis block is the only block on the channel, the height of the channel will be 1:

这个命令会列出通道区块的高度和最新的区块的hash值,因为这个通道上只有一个创世纪区块,所以这个通道上的区块高度是1:

1
2
2020-03-13 10:50:06.978 EDT [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Blockchain info: {"height":1,"currentBlockHash":"kvtQYYEL2tz0kDCNttPFNC4e6HVUFOGMTIDxZ+DeNQM="}

We can now join the Org2 peer to the channel. Set the following environment variables to operate the peer CLI as the Org2 admin. The environment variables will also set the Org2 peer, peer0.org1.example.com, as the target peer.

我们现在可以把组织Org2的peer节点加入通道了。设置下面的环境变量来使用Org2的管理员操作peer CLI。

1
2
3
4
5
export CORE_PEER_TLS_ENABLED=true
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

While we still have the channel genesis block on our file system, in a more realistic scenario, Org2 would have the fetch the block from the ordering service. As an example, we will use the peer channel fetch command to get the genesis block for Org2:

然而在我们本地系统中仍然存在通道的创世纪区块,在一个更真实的情形中,组织Org2应该从排序服务获取这个区块。例如,我们将使用 peer channel fetch命令来为组织Org2获取创世纪区块:

1
peer channel fetch 0 ./channel-artifacts/channel_org2.block -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

The command uses 0 to specify that it needs to fetch the genesis block that is required to join the channel. If the command is successful, you should see the following output:

该命令使用0来指明它需要获取创世纪块,该创世纪区块用于加入通道。如果命令执行成功,你会看到下面的输出:

1
2
2020-03-13 11:32:06.309 EDT [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-03-13 11:32:06.336 EDT [cli.common] readBlock -> INFO 002 Received block: 0

The command returns the channel genesis block and names it channel_org2.block to distinguish it from the block pulled by org1. You can now use the block to join the Org2 peer to the channel:

这个命令会获取到名为 channel_org2.block 的通道创世纪区块,以与Org1的区块作区分。你现在可以使用这个区块把Org2的peer节点加入到通道:

1
peer channel join -b ./channel-artifacts/channel_org2.block

Set anchor peers(设置锚节点)

After an organizations has joined their peers to the channel, they should select at least one of their peers to become an anchor peer. Anchor peers are required in order to take advantage of features such as private data and service discovery. Each organization should set multiple anchor peers on a channel for redundancy. For more information about gossip and anchor peers, see the Gossip data dissemination protocol.

在一个组织将他们的peer节点加入到通道之后,他们还需要在他们的组织内部选择至少一个peer节点作为锚节点。Anchor peers 需要锚节点的好处是他能够利用私有数据以及做服务发现。每个组织都应在一个通道上设置多个锚节点以实现冗余。

The endpoint information of the anchor peers of each organization is included in the channel configuration. Each channel member can specify their anchor peers by updating the channel. We will use the configtxlator tool to update the channel configuration and select an anchor peer for Org1 and Org2. The process for setting an anchor peer is similar to the steps that are required to make other channel updates and provides an introduction to how to use configtxlator to update a channel configuration. You will also need to install the jq tool on your local machine.

通道配置中包含每个组织的锚节点的终点信息。每个组织都可以通过更新通道配置来知名他们的锚节点。我们会使用 configtxlator工具来更新通道配置并且为组织Org1和Org2各选择一个锚节点。设置锚节点的流程与教程update a channel configuration的步骤很类似。你还需要在你的本地安装jq 工具。

We will start by selecting an anchor peer as Org1. The first step is to pull the most recent channel configuration block using the peer channel fetch command. Set the following environment variables to operate the peer CLI as the Org1 admin:

我们先以Org1的身份来选择一个锚节点。第一步是使用peer channel fetch 命令拉去最新的通道配置区块。设置环境变量以Org1管理员的身份操作 peer CLI :

1
2
3
4
5
6
export FABRIC_CFG_PATH=$PWD/../config/
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

You can use the following command to fetch the channel configuration:

你可以通过下面的命令来获取通道配置:

1
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

Because the most recent channel configuration block is the channel genesis block, you will see the command return block 0 from the channel.

因为最新的通道配置区块是通道的创世纪区块,你会看到该命令会返回通道上的0区块。

1
2
3
4
2020-12-23 16:37:33.686 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-12-23 16:37:33.689 CST [cli.common] readBlock -> INFO 002 Received block: 0
2020-12-23 16:37:33.689 CST [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
2020-12-23 16:37:33.693 CST [cli.common] readBlock -> INFO 004 Received block: 0

The channel configuration block was stored in the channel-artifacts folder to keep the update process separate from other artifacts. Change into the channel-artifacts folder to complete the next steps:

通道配置区块被存储在channel-artifacts目录下,以使更新流程与其他的组件区分开。进入 channel-artifacts 目录下来完成接下来的步骤:

1
cd channel-artifacts

We can now start using the configtxlator tool to start working with the channel configuration. The first step is to decode the block from protobuf into a JSON object that can be read and edited. We also strip away the unnecessary block data, leaving only the channel configuration.

我们现在开始使用 configtxlator 工具和通道配置一起工作。第一步是将来自区块的protobuf格式解码为可以读取和编辑的JSON格式。我们还将去除不必要的块数据,仅保留通道配置。

1
2
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

These commands convert the channel configuration block into a streamlined JSON, config.json, that will serve as the baseline for our update. Because we don’t want to edit this file directly, we will make a copy that we can edit. We will use the original channel config in a future step.

这些命令将通道配置区块转换为简化的JSON格式的文件config.json,它将作为我们更新的基准。因为我们不想直接编辑这个文件,我们会先创建一个可以编辑的副本。我们将在以后的步骤中使用原始的通道配置。

1
cp config.json config_copy.json

You can use the jq tool to add the Org1 anchor peer to the channel configuration.

你可以使用jq 工具来添加Org1组织的锚节点到通道配置。

1
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

After this step, we have an updated version of channel configuration in JSON format in the modified_config.json file. We can now convert both the original and modified channel configurations back into protobuf format and calculate the difference between them.

完成此步骤后,我们在modified_config.json文件中以JSON格式获取了通道配置的更新版本。现在,我们可以将原始的和修改后的通道配置都转换回protobuf格式,并计算它们之间的差异。

1
2
3
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

The new protobuf named channel_update.pb contains the anchor peer update that we need to apply to the channel configuration. We can wrap the configuration update in a transaction envelope to create the channel configuration update transaction.

格式为protobuf的新的channel_update.pb文件包含我们需要应用于通道配置上的锚节点更新。我们可以将配置更新包装在交易信封中以创建通道配置更新交易。

1
2
3
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

We can now use the final artifact, config_update_in_envelope.pb, that can be used to update the channel. Navigate back to the test-network directory:

现在,我们可以使用最终工件config_update_in_envelope.pb,该工件可以用于更新通道。回到test-network 目录:

1
cd ..

We can add the anchor peer by providing the new channel configuration to the peer channel update command. Because we are updating a section of the channel configuration that only affects Org1, other channel members do not need to approve the channel update.

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

1
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

When the channel update is successful, you should see the following response:

当渠道更新成功后,你会看到下面的响应:

1
2
2020-12-23 17:05:48.187 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
2020-12-23 17:05:48.222 CST [channelCmd] update -> INFO 002 Successfully submitted channel update

We can set the anchor peers for Org2. Because we are going through the process a second time, we will go through the steps more quickly. Set the environment variables to operate the peer CLI as the Org2 admin:

我们可以为Org2设置锚节点。因为我们是第二次进行该过程,所以我们将更快地完成这些步骤。设置环境变量以Org2管理员的身份操作 peer CLI :

1
2
3
4
5
export CORE_PEER_TLS_ENABLED=true
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

Pull the latest channel configuration block, which is now the second block on the channel:

拉去最新的通道配置区块,即目前通道上的第二个区块:

1
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

Navigate back to the channel-artifacts directory(切换回 channel-artifacts 目录):

1
cd channel-artifacts

You can then decode and copy the configuration block.(你可以解码并复制配置区块)

1
2
3
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

Add the Org2 peer that is joined to the channel as the anchor peer in the channel configuration:

在通道配置中添加Org2的已经加入通道的节点作为锚节点:

1
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

We can now convert both the original and updated channel configurations back into protobuf format and calculate the difference between them.

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

1
2
3
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

Wrap the configuration update in a transaction envelope to create the channel configuration update transaction:

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

1
2
3
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

Navigate back to the test-network directory.

1
cd ..

Update the channel and set the Org2 anchor peer by issuing the following command:

1
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

You can confirm that the channel has been updated successfully by running the peer channel info command:

你可以使用 peer channel info命令来确认通道已经成功更新。

1
peer channel getinfo -c channel1

Now that the channel has been updated by adding two channel configuration blocks to the channel genesis block, the height of the channel will have grown to three:

现在已经通过在创世纪区块上添加两个通道配置区块更新了通道,通道的区块高度会增长到3:

1
2
2020-12-23 17:19:08.620 CST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
Blockchain info: {"height":3,"currentBlockHash":"0xMLgGnvbUE+gfDpxjbfB1OsxROF3djLzPX9S76ai2I=","previousBlockHash":"6oIrHH8zjeOuhlj2/rrpzxh0pNmGOdPTDjiphJwCXcQ="}

Deploy a chaincode to the new channel(部署链码到新通道上)

We can confirm that the channel was created successfully by deploying a chaincode to the channel. We can use the network.sh script to deploy the Basic asset transfer chaincode to any test network channel. Deploy a chaincode to our new channel using the following command:

我们可以通过在通道上部署链码来确认通道已经创建成功。我们可以使用 network.sh 脚本部署Basic asset transfer 链码到任何测试通道,使用下面的命令将链码部署到新通道上:

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

After you run the command, you should see the chaincode being deployed to the channel in your logs. The chaincode is invoked to add data to the channel ledger.

运行命令后,您应该在日志中看到链码已部署到通道。调用链码将数据添加到通道账本。

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

After you run the query, you should see the assets that were added to the channel ledger.

在运行查询之后,你会看到已经添加到通道账本上的资产列表。

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