github.com/true-sqn/fabric@v2.1.1+incompatible/docs/source/create_channel/create_channel.md (about) 1 # Creating a channel 2 3 In order to create and transfer assets on a Hyperledger Fabric network, an organization needs to join a channel. Channels are a private layer of communication between specific organizations. Each channel consists of a separate ledger that can only be read and written to by channel members, who are allowed to join their peers to the channel and receive new blocks of transactions from the ordering service. While the peers, nodes, and Certificate Authorities form the physical infrastructure of the network, channels are the process by which organizations connect with each other and interact. Channels are invisible to members of the network that are not channel members. 4 5 You can use this tutorial to learn how to create new channels using the [configtxgen](../commands/configtxgen.html) CLI tool and then use the [peer channel](../commands/peerchannel.html) 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. 6 7 In the process of creating the channel, this tutorial will take you through the following steps and concepts: 8 9 - [Setting up the configtxgen tool](#setting-up-the-configtxgen-tool) 10 - [Using the configtx.yaml file](#the-configtx-yaml-file) 11 - [The orderer system channel](#the-orderer-system-channel) 12 - [Creating an application channel](#creating-an-application-channel) 13 - [Joining peers to the channel](#join-peers-to-the-channel) 14 - [Setting anchor peers](#set-anchor-peers) 15 16 ## Setting up the configtxgen tool 17 18 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](../commands/configtxgen.html) 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. 19 20 You can download the `configtxgen` binaries by following the steps to [install the samples, binaries and Docker images](../install.html). `configtxgen` will be downloaded to the `bin` folder of your local clone of the `fabric-samples` repository along with other Fabric tools. 21 22 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: 23 ``` 24 cd fabric-samples/test-network 25 ``` 26 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: 27 ``` 28 export PATH=${PWD}/../bin:$PATH 29 ``` 30 31 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: 32 ``` 33 export FABRIC_CFG_PATH=${PWD}/configtx 34 ``` 35 36 You can check that you can are able to use the tool by printing the `configtxgen` help text: 37 ``` 38 configtxgen --help 39 ``` 40 41 42 ## The configtx.yaml file 43 44 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](https://developers.google.com/protocol-buffers) that can be read by Fabric. 45 46 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: 47 48 - **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](../membership/membership.html). 49 - **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. 50 - **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. 51 - **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. 52 53 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. 54 55 ## Start the network 56 57 We will use a running instance of the Fabric test network to create the new channel. For the sake of this tutorial, we want to operate from a known initial state. The following command will kill any active containers and remove any previously generated artifacts. Make sure that you are still operating from the `test-network` directory of your local clone of `fabric-samples`. 58 ``` 59 ./network.sh down 60 ``` 61 You can then use the following command to start the test network: 62 ``` 63 ./network.sh up 64 ``` 65 This command will create a Fabric network with the two peer organizations and the single ordering organization defined in the `configtx.yaml` file. The peer organizations will operate one peer each, while the ordering service administrator will operate a single ordering node. When you run the command, the script will print out logs of the nodes being created: 66 ``` 67 Creating network "net_test" with the default driver 68 Creating volume "net_orderer.example.com" with default driver 69 Creating volume "net_peer0.org1.example.com" with default driver 70 Creating volume "net_peer0.org2.example.com" with default driver 71 Creating orderer.example.com ... done 72 Creating peer0.org2.example.com ... done 73 Creating peer0.org1.example.com ... done 74 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 75 8d0c74b9d6af hyperledger/fabric-orderer:latest "orderer" 4 seconds ago Up Less than a second 0.0.0.0:7050->7050/tcp orderer.example.com 76 ea1cf82b5b99 hyperledger/fabric-peer:latest "peer node start" 4 seconds ago Up Less than a second 0.0.0.0:7051->7051/tcp peer0.org1.example.com 77 cd8d9b23cb56 hyperledger/fabric-peer:latest "peer node start" 4 seconds ago Up 1 second 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com 78 ``` 79 80 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. 81 82 ## The orderer system channel 83 84 The first channel that is created in a Fabric network is the system channel. The system channel defines the set of ordering nodes that form the ordering service and the set of organizations that serve as ordering service administrators. 85 86 The system channel also includes the organizations that are members of blockchain [consortium](../glossary.html#consortium). 87 The consortium is a set of peer organizations that belong to the system channel, but are not administrators of the ordering service. Consortium members have the ability to create new channels and include other consortium organizations as channel members. 88 89 The genesis block of the system channel is required to deploy a new ordering service. The test network script already created the system channel genesis block when you issued the `./network.sh up` command. The genesis block was used to deploy the single ordering node, which used the block to create the system channel and form the ordering service of the network. If you examine the output of the `./network.sh` script, you can find the command that created the genesis block in your logs: 90 ``` 91 configtxgen -profile TwoOrgsOrdererGenesis -channelID system-channel -outputBlock ./system-genesis-block/genesis.block 92 ``` 93 94 The `configtxgen` tool used the `TwoOrgsOrdererGenesis` channel profile from `configtx.yaml` to write the genesis block and store it in the `system-genesis-block` folder. You can see the `TwoOrgsOrdererGenesis` profile below: 95 ```yaml 96 TwoOrgsOrdererGenesis: 97 <<: *ChannelDefaults 98 Orderer: 99 <<: *OrdererDefaults 100 Organizations: 101 - *OrdererOrg 102 Capabilities: 103 <<: *OrdererCapabilities 104 Consortiums: 105 SampleConsortium: 106 Organizations: 107 - *Org1 108 - *Org2 109 ``` 110 111 The `Orderer:` section of the profile creates the single node Raft ordering service used by the test network, with the `OrdererOrg` as the ordering service administrator. The `Consortiums` section of the profile creates a consortium of peer organizations named `SampleConsortium:`. Both peer organizations, Org1 and Org2, are members of the consortium. As a result, we can include both organizations in new channels created by the test network. If we wanted to add another organization as a channel member without adding that organization to the consortium, we would first need to create the channel with Org1 and Org2, and then add the other organization by [updating the channel configuration](../channel_update_tutorial.html). 112 113 ## Creating an application channel 114 115 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`: 116 ``` 117 configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel1.tx -channelID channel1 118 ``` 119 120 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: 121 ```yaml 122 TwoOrgsChannel: 123 Consortium: SampleConsortium 124 <<: *ChannelDefaults 125 Application: 126 <<: *ApplicationDefaults 127 Organizations: 128 - *Org1 129 - *Org2 130 Capabilities: 131 <<: *ApplicationCapabilities 132 ``` 133 134 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](../glossary.html#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. 135 136 If the command successful, you will see logs of `configtxgen` loading the `configtx.yaml` file and printing a channel creation transaction: 137 ``` 138 2020-03-11 16:37:12.695 EDT [common.tools.configtxgen] main -> INFO 001 Loading configuration 139 2020-03-11 16:37:12.738 EDT [common.tools.configtxgen.localconfig] Load -> INFO 002 Loaded configuration: /Usrs/fabric-samples/test-network/configtx/configtx.yaml 140 2020-03-11 16:37:12.740 EDT [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 003 Generating new channel configtx 141 2020-03-11 16:37:12.789 EDT [common.tools.configtxgen] doOutputChannelCreateTx -> INFO 004 Writing new channel tx 142 ``` 143 144 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: 145 ``` 146 export FABRIC_CFG_PATH=$PWD/../config/ 147 ``` 148 149 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: 150 ``` 151 export CORE_PEER_TLS_ENABLED=true 152 export CORE_PEER_LOCALMSPID="Org1MSP" 153 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 154 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 155 export CORE_PEER_ADDRESS=localhost:7051 156 ``` 157 158 You can now create the channel by using the following command: 159 ``` 160 peer channel create -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 -f ./channel-artifacts/channel1.tx --outputBlock ./channel-artifacts/channel1.block --tls true --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 161 ``` 162 163 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: 164 ``` 165 2020-03-06 17:33:49.322 EST [channelCmd] InitCmdFactory -> INFO 00b Endorser and orderer connections initialized 166 2020-03-06 17:33:49.550 EST [cli.common] readBlock -> INFO 00c Received block: 0 167 ``` 168 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. 169 170 ## Join peers to the channel 171 172 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](../commands/peerchannel.html#peer-channel-fetch) command. The organization can then use the genesis block to join the peer to the channel using the [peer channel join](../commands/peerchannel.html#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. 173 174 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. 175 ``` 176 peer channel join -b ./channel-artifacts/channel1.block 177 ``` 178 179 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: 180 ``` 181 2020-03-06 17:49:09.903 EST [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized 182 2020-03-06 17:49:10.060 EST [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel 183 ``` 184 185 You can verify that the peer has joined the chanel using the [peer channel getinfo](../commands/peerchannel.html#peer-channel-getinfo) command: 186 ``` 187 peer channel getinfo -c channel1 188 ``` 189 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: 190 ``` 191 2020-03-13 10:50:06.978 EDT [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized 192 Blockchain info: {"height":1,"currentBlockHash":"kvtQYYEL2tz0kDCNttPFNC4e6HVUFOGMTIDxZ+DeNQM="} 193 ``` 194 195 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. 196 ``` 197 export CORE_PEER_TLS_ENABLED=true 198 export CORE_PEER_LOCALMSPID="Org2MSP" 199 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 200 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 201 export CORE_PEER_ADDRESS=localhost:9051 202 ``` 203 204 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: 205 ``` 206 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 207 ``` 208 209 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: 210 ``` 211 2020-03-13 11:32:06.309 EDT [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized 212 2020-03-13 11:32:06.336 EDT [cli.common] readBlock -> INFO 002 Received block: 0 213 ``` 214 215 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: 216 ``` 217 peer channel join -b ./channel-artifacts/channel_org2.block 218 ``` 219 220 ## Set anchor peers 221 222 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](../gossip.html#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](../gossip.html). 223 224 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](../commands/configtxlator.html) 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](../config_update.html). You will also need to install the [jq tool](https://stedolan.github.io/jq/) on your local machine. 225 226 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: 227 ``` 228 export FABRIC_CFG_PATH=$PWD/../config/ 229 export CORE_PEER_TLS_ENABLED=true 230 export CORE_PEER_LOCALMSPID="Org1MSP" 231 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 232 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 233 export CORE_PEER_ADDRESS=localhost:7051 234 ``` 235 236 You can use the following command to fetch the channel configuration: 237 ``` 238 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 239 ``` 240 Because the most recent channel configuration block is the channel genesis block, you will see the command return block 0 from the channel. 241 ``` 242 2020-04-15 20:41:56.595 EDT [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized 243 2020-04-15 20:41:56.603 EDT [cli.common] readBlock -> INFO 002 Received block: 0 244 2020-04-15 20:41:56.603 EDT [channelCmd] fetch -> INFO 003 Retrieving last config block: 0 245 2020-04-15 20:41:56.608 EDT [cli.common] readBlock -> INFO 004 Received block: 0 246 ``` 247 248 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: 249 ``` 250 cd channel-artifacts 251 ``` 252 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. 253 254 ``` 255 configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json 256 jq .data.data[0].payload.data.config config_block.json > config.json 257 ``` 258 259 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. 260 ``` 261 cp config.json config_copy.json 262 ``` 263 264 You can use the `jq` tool to add the Org1 anchor peer to the channel configuration. 265 ``` 266 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 267 ``` 268 269 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. 270 ``` 271 configtxlator proto_encode --input config.json --type common.Config --output config.pb 272 configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb 273 configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb 274 ``` 275 276 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. 277 278 ``` 279 configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json 280 echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json 281 configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb 282 ``` 283 284 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: 285 ``` 286 cd .. 287 ``` 288 289 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. 290 ``` 291 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 292 ``` 293 294 When the channel update is successful, you should see the following response: 295 ``` 296 2020-01-09 21:30:45.791 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update 297 ``` 298 299 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: 300 ``` 301 export CORE_PEER_TLS_ENABLED=true 302 export CORE_PEER_LOCALMSPID="Org2MSP" 303 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 304 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 305 export CORE_PEER_ADDRESS=localhost:9051 306 ``` 307 308 Pull the latest channel configuration block, which is now the second block on the channel: 309 ``` 310 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 311 ``` 312 313 Navigate back to the `channel-artifacts` directory: 314 ``` 315 cd channel-artifacts 316 ``` 317 318 You can then decode and copy the configuration block. 319 ``` 320 configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json 321 jq .data.data[0].payload.data.config config_block.json > config.json 322 cp config.json config_copy.json 323 ``` 324 325 Add the Org2 peer that is joined to the channel as the anchor peer in the channel configuration: 326 ``` 327 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 328 ``` 329 330 We can now convert both the original and updated channel configurations back into protobuf format and calculate the difference between them. 331 ``` 332 configtxlator proto_encode --input config.json --type common.Config --output config.pb 333 configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb 334 configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb 335 ``` 336 337 Wrap the configuration update in a transaction envelope to create the channel configuration update transaction: 338 ``` 339 configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json 340 echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json 341 configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb 342 ``` 343 344 Navigate back to the `test-network` directory. 345 ``` 346 cd .. 347 ``` 348 349 Update the channel and set the Org2 anchor peer by issuing the following command: 350 ``` 351 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 352 ``` 353 354 You can confirm that the channel has been updated successfully by running the `peer channel info` command: 355 ``` 356 peer channel getinfo -c channel1 357 ``` 358 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: 359 ``` 360 Blockchain info: {"height":3,"currentBlockHash":"eBpwWKTNUgnXGpaY2ojF4xeP3bWdjlPHuxiPCTIMxTk=","previousBlockHash":"DpJ8Yvkg79XHXNfdgneDb0jjQlXLb/wxuNypbfHMjas="} 361 ``` 362 363 ## Deploy a chaincode to the new channel 364 365 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 Fabcar chaincode to any test network channel. Deploy a chaincode to our new channel using the following command: 366 ``` 367 ./network.sh deployCC -c channel1 368 ``` 369 370 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 and then queried. 371 ``` 372 [{"Key":"CAR0","Record":{"make":"Toyota","model":"Prius","colour":"blue","owner":"Tomoko"}}, 373 {"Key":"CAR1","Record":{"make":"Ford","model":"Mustang","colour":"red","owner":"Brad"}}, 374 {"Key":"CAR2","Record":{"make":"Hyundai","model":"Tucson","colour":"green","owner":"Jin Soo"}}, 375 {"Key":"CAR3","Record":{"make":"Volkswagen","model":"Passat","colour":"yellow","owner":"Max"}}, 376 {"Key":"CAR4","Record":{"make":"Tesla","model":"S","colour":"black","owner":"Adriana"}}, 377 {"Key":"CAR5","Record":{"make":"Peugeot","model":"205","colour":"purple","owner":"Michel"}}, 378 {"Key":"CAR6","Record":{"make":"Chery","model":"S22L","colour":"white","owner":"Aarav"}}, 379 {"Key":"CAR7","Record":{"make":"Fiat","model":"Punto","colour":"violet","owner":"Pari"}}, 380 {"Key":"CAR8","Record":{"make":"Tata","model":"Nano","colour":"indigo","owner":"Valeria"}}, 381 {"Key":"CAR9","Record":{"make":"Holden","model":"Barina","colour":"brown","owner":"Shotaro"}}] 382 ===================== Query successful on peer0.org1 on channel 'channel1' ===================== 383 ``` 384 385 <!--- Licensed under Creative Commons Attribution 4.0 International License 386 https://creativecommons.org/licenses/by/4.0/ -->