github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/docs/source/create_channel/create_channel_test_net.md (about)

     1  # Create a channel using the test network
     2  
     3  Use this tutorial along with the test network to learn how to create a channel genesis block and then create a new application channel that the test network peers can join. Rather than requiring you to set up an orderer, or remove the system channel from an existing orderer, this tutorial leverages the nodes from the Fabric sample test network. Because the test network deploys an ordering service and peers for you, this tutorial focuses solely on the process to create a channel. It is worth noting that the test network includes a `createChannel` subcommand that can be used to create a channel, but this tutorial explains how do it manually, the process that is required when you do not use the test network.
     4  
     5  Fabric v2.3 introduces the capability to create a channel without requiring a system channel, removing an extra layer of administration from the process. In this tutorial, we use the [configtxgen](../commands/configtxgen.html) tool to create a channel genesis block and then use the [osnadmin channel](../commands/osnadminchannel.html) command to create the channel.
     6  
     7  **Note:**
     8  - If you are _not_ using the test network, you should follow the instructions for [how to deploy an ordering service without a system channel](create_channel_participation.html#deploy-a-new-set-of-orderers). In the Fabric v2.3 test network sample, the single-node ordering service is deployed without a system channel.
     9  - If you prefer to learn how to create a channel on an ordering service that includes the system channel, you should refer to the [Create a channel tutorial](https://hyperledger-fabric.readthedocs.io/en/release-2.2/create_channel/create_channel.html) from Fabric v2.2. In the Fabric v2.2 test network sample, the single-node ordering service is deployed with a system channel.
    10  
    11  To create a channel using the test network, this tutorial takes you through the following steps and concepts:
    12  - [Prerequisites](#prerequisites)
    13  - [Step one: Generate the genesis block of the channel](#step-one-generate-the-genesis-block-of-the-channel)
    14  - [Step two: Create the application channel](#step-two-create-the-application-channel)
    15  - [Next steps](#next-steps)
    16  
    17  ## Before you begin
    18  
    19  To run the test network, you need to clone the `fabric-samples`
    20  repository and download the latest production Fabric images. Make sure that you have installed
    21  the [Prerequisites](../prereqs.html) and [Installed the Samples, Binaries, and Docker Images](../install.html).  
    22  
    23  **Note:** After you create a channel and join peers to it, you will need to you add anchor peers to the channel, in order for service discovery and private data to work. Instructions on how to set an anchor peer on your channel are included in this tutorial, but require that the [jq tool](https://stedolan.github.io/jq/) is installed on your local machine.
    24  
    25  ## Prerequisites
    26  
    27  ### Start the test network
    28  
    29  We will use a running instance of the Fabric test network to create the new channel. Because it's important to operate from a known initial state, the following command destroys any active containers and removes any previously generated artifacts. For the purposes of this tutorial, we operate from the `test-network` directory inside `fabric-samples`. If you are not already there, navigate to that directory using the following command:
    30  ```
    31  cd fabric-samples/test-network
    32  ```
    33  Run the following command to bring down the network:
    34  ```
    35  ./network.sh down
    36  ```
    37  You can then use the following command to start the test network:
    38  ```
    39  ./network.sh up
    40  ```
    41  This command creates a Fabric network with the two peer organizations and the single ordering node ordering organization. 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 prints out the nodes being created:
    42  ```
    43  Creating network "fabric_test" with the default driver
    44  Creating volume "net_orderer.example.com" with default driver
    45  Creating volume "net_peer0.org1.example.com" with default driver
    46  Creating volume "net_peer0.org2.example.com" with default driver
    47  Creating peer0.org2.example.com ... done
    48  Creating orderer.example.com    ... done
    49  Creating peer0.org1.example.com ... done
    50  Creating cli                    ... done
    51  CONTAINER ID   IMAGE                               COMMAND             CREATED         STATUS                  PORTS                                            NAMES
    52  1667543b5634   hyperledger/fabric-tools:latest     "/bin/bash"         1 second ago    Up Less than a second                                                    cli
    53  b6b117c81c7f   hyperledger/fabric-peer:latest      "peer node start"   2 seconds ago   Up 1 second             0.0.0.0:7051->7051/tcp                           peer0.org1.example.com
    54  703ead770e05   hyperledger/fabric-orderer:latest   "orderer"           2 seconds ago   Up Less than a second   0.0.0.0:7050->7050/tcp, 0.0.0.0:7053->7053/tcp   orderer.example.com
    55  718d43f5f312   hyperledger/fabric-peer:latest      "peer node start"   2 seconds ago   Up 1 second             7051/tcp, 0.0.0.0:9051->9051/tcp                 peer0.org2.example.com
    56  ```
    57  
    58  Notice that the peers are running on ports `7051` and `9051`, while the orderer is running on port `7050`. We will use these ports in subsequent commands.  
    59  
    60  By default, when you start the test network, it does not contain any channels. The following instructions demonstrate how to add a channel that is named `channel1` to this network.
    61  
    62  ### Set up the configtxgen tool
    63  
    64  Channels are created by generating a channel creation transaction in a genesis block, and then passing that genesis block to an ordering service node in a join request. The channel creation transaction specifies the initial configuration of the channel and can be created by the [configtxgen](../commands/configtxgen.html) tool. The tool reads the `configtx.yaml` file that defines the configuration of our channel, and then writes the relevant information into the channel creation transaction and outputs a genesis block including the channel creation transaction. When you [installed Fabric](../install.html), the `configtxgen` tool was installed in the `fabric-samples\bin` directory for you.
    65  
    66  Ensure that you are still operating from the `test-network` directory of your local clone of `fabric-samples` and run this command:
    67  
    68  ```
    69  export PATH=${PWD}/../bin:$PATH
    70  ```
    71  
    72  Next, before you can use `configtxgen`, you need to the set the `FABRIC_CFG_PATH` environment variable to the location of the test network folder that contains the `configtx.yaml` file. Because we are using the test network, we reference the `configtx` folder:
    73  ```
    74  export FABRIC_CFG_PATH=${PWD}/configtx
    75  ```
    76  
    77  Now verify that you can use the tool by printing the `configtxgen` help text:
    78  ```
    79  configtxgen --help
    80  ```
    81  
    82  ### The configtx.yaml file
    83  
    84  For the test network, the `configtxgen` tool uses the channel profiles that are defined in the `configtxt\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.
    85  
    86  This `configtx.yaml` file contains the following information that we will use to create our new channel:
    87  
    88  - **Organizations:** The peer and ordering 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).
    89  - **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. This section also defines the ordering nodes that are part of the ordering service consenter set. In the test network sample, there is only a single ordering node, but in a production network we recommend **five** ordering nodes to allow for two ordering nodes to go down and still maintain consensus.
    90      ```
    91      EtcdRaft:
    92          Consenters:
    93          - Host: orderer.example.com
    94            Port: 7050
    95            ClientTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
    96            ServerTLSCert: ../organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
    97      ```
    98  - **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.
    99  - **Channel profiles** Each channel profile references information from other sections of the `configtx.yaml` file to build a channel configuration. The profiles are used to create the genesis block of application channel. Notice that the `configtx.yaml` file in the test network includes a single profile named `TwoOrgsApplicationGenesis` that we will use to generate the create channel transaction.
   100      ```yaml
   101      TwoOrgsApplicationGenesis:
   102          <<: *ChannelDefaults
   103          Orderer:
   104              <<: *OrdererDefaults
   105              Organizations:
   106                  - *OrdererOrg
   107              Capabilities: *OrdererCapabilities
   108          Application:
   109              <<: *ApplicationDefaults
   110              Organizations:
   111                  - *Org1
   112                  - *Org2
   113              Capabilities: *ApplicationCapabilities
   114      ```
   115  
   116  The profile includes both peer organizations, `Org1` and `Org2` as well as the ordering organization `OrdererOrg`. Additional ordering nodes and ordering organizations can be added or removed from the consenter set at a later time using a channel update transaction.
   117  
   118  Want to learn more about this file and how to build your own channel application profiles? Visit [Using configtx.yaml to create a channel genesis block](create_channel_config.html) tutorial for more details. For now, we will return to the operational aspects of creating the channel, though we will reference parts of this file in future steps.
   119  
   120  ## Step one: Generate the genesis block of the channel
   121  
   122  Because we have started the Fabric test network, we are ready to create a new channel. We have already set the environment variables that are required to use the `configtxgen` tool.   
   123  
   124  Run the following command to create the channel genesis block for `channel1`:
   125  ```
   126  configtxgen -profile TwoOrgsApplicationGenesis -outputBlock ./channel-artifacts/channel1.block -channelID channel1
   127  ```
   128  
   129  - **`-profile`**: The command uses the `-profile` flag to reference the `TwoOrgsApplicationGenesis:` profile from `configtx.yaml` that is used by the test network to create application channels.
   130  - **`-outputBlock`**: The output of this command is the channel genesis block that is written to `-outputBlock ./channel-artifacts/channel1.block`.
   131  - **`-channelID`**: The `-channelID` parameter will be the name of the future channel. You can specify any name you want for your channel but for illustration purposes in this tutorial we use `channel1`. Channel names must be all lowercase, fewer than 250 characters long and match the regular expression ``[a-z][a-z0-9.-]*``.
   132  
   133  When the command is successful, you can see the logs of `configtxgen` loading the `configtx.yaml` file and printing a channel creation transaction:
   134  ```
   135  [common.tools.configtxgen] main -> INFO 001 Loading configuration
   136  [common.tools.configtxgen.localconfig] completeInitialization -> INFO 002 orderer type: etcdraft
   137  [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
   138  [common.tools.configtxgen.localconfig] Load -> INFO 004 Loaded configuration: /Users/fabric-samples/test-network/configtx/configtx.yaml
   139  [common.tools.configtxgen] doOutputBlock -> INFO 005 Generating genesis block
   140  [common.tools.configtxgen] doOutputBlock -> INFO 006 Creating application channel genesis block
   141  [common.tools.configtxgen] doOutputBlock -> INFO 007 Writing genesis block
   142  ```
   143  
   144  ## Step two: Create the application channel
   145  
   146  Now that we have the channel genesis block, it is easy to use the `osnadmin channel join` command to create the channel. To simplify subsequent commands, we also need to set some environment variables to establish the locations of the certificates for the nodes in the test network:
   147  
   148  ```
   149  export ORDERER_CA=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
   150  export ORDERER_ADMIN_TLS_SIGN_CERT=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.crt
   151  export ORDERER_ADMIN_TLS_PRIVATE_KEY=${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/tls/server.key
   152  ```
   153  
   154  Run the following command to create the channel named `channel1` on the ordering service.
   155  ```
   156  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"
   157  ```
   158  
   159  - **`--channelID`**: Specify the name of the application channel that you provided when you created the channel genesis block.
   160  - **`--config-block`**: Specify the location of the channel genesis block that you created with the `configtxgen` command, or the latest config block.
   161  - **`-o`**: Specify the hostname and port of the orderer admin endpoint. For the test network ordering node this is set to `localhost:7053`.
   162  
   163  In addition, because the `osnadmin channel` commands communicate with the ordering node using mutual TLS, you need to provide the following certificates:
   164  - **`--ca-file`**: Specify the location and file name of the orderer organization TLS CA root certificate.
   165  - **`--client-cert`**: Specify the location and file name of admin client signed certificate from the TLS CA.
   166  - **`--client-key`**: Specify the location and file name of admin client private key from the TLS CA.
   167  
   168  When successful, the output of the command contains the following:
   169  ```
   170  Status: 201
   171  {
   172  	"name": "channel1",
   173  	"url": "/participation/v1/channels/channel1",
   174  	"consensusRelation": "consenter",
   175  	"status": "active",
   176  	"height": 1
   177  }
   178  ```
   179  
   180  The channel is active and ready for peers to join.
   181  
   182  ### Consenter vs. Follower
   183  
   184  Notice the ordering node was joined to the channel with a `consensusRelation: "consenter"`. If you ran the command against an ordering node that is not included in the list of `Consenters:` in the `configtx.yaml` file (or the channel configuration consenter set), it is added to the channel as a `follower`. To learn more about considerations when joining additional ordering nodes see the topic on [Joining additional ordering nodes](create_channel_participation.html#step-three-join-additional-ordering-nodes).
   185  
   186  ### Active vs. onboarding
   187  
   188  An orderer can join the channel by providing the channel **genesis block**, or the **latest config block**. If joining from the latest config block, the orderer status is set to `onboarding` until the channel ledger has caught up to the specified config block, when it becomes `active`. At this point, you could then add the orderer to the channel consenter set by submitting a channel update transaction, which will cause the  `consensusRelation` to change from `follower` to `consenter`.
   189  
   190  ## Next steps
   191  
   192  After you have created the channel, the next steps are to join peers to the channel and deploy smart contracts. This section walks you through those processes using the test network.
   193  
   194  ### List channels on an orderer
   195  
   196  Before you join peers to the channel, you might want to try to create additional channels. As you create more channels, the `osnadmin channel list` command is useful to view the channels that this orderer is a member of. The same parameters are used here as in the `osnadmin channel join` command from the previous step:
   197  ```
   198  osnadmin channel list -o localhost:7053 --ca-file "$ORDERER_CA" --client-cert "$ORDERER_ADMIN_TLS_SIGN_CERT" --client-key "$ORDERER_ADMIN_TLS_PRIVATE_KEY"
   199  ```
   200  The output of this command looks similar to:
   201  
   202  ```
   203  Status: 200
   204  {
   205  	"systemChannel": null,
   206  	"channels": [
   207  		{
   208  			"name": "channel1",
   209  			"url": "/participation/v1/channels/channel1"
   210  		}
   211  	]
   212  }
   213  ```
   214  
   215  ### Join peers to the channel
   216  
   217  The test network includes two peer organizations each with one peer. But before we can use the peer CLI, we need to set some environment variables to specify which user (client MSP) we are acting as and which peer we are targeting. Set the following environment variables to indicate that we are acting as the Org1 admin and targeting the Org1 peer.
   218  
   219  ```
   220  export CORE_PEER_TLS_ENABLED=true
   221  export CORE_PEER_LOCALMSPID="Org1MSP"
   222  export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
   223  export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
   224  export CORE_PEER_ADDRESS=localhost:7051
   225  ```
   226  
   227  In order to use the peer CLI, we also need to modify the `FABRIC_CONFIG_PATH`:
   228  ```
   229  export FABRIC_CFG_PATH=$PWD/../config/
   230  ```
   231  To join the test network peer from `Org1` to the channel `channel1` simply pass the genesis block in a join request:
   232  ```
   233  peer channel join -b ./channel-artifacts/channel1.block
   234  ```
   235  When successful, the output of this command contains the following:
   236  ```
   237  [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
   238  [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
   239  ```
   240  
   241  We repeat these steps for the `Org2` peer. Set the following environment variables to operate the `peer` CLI as the `Org2` admin. The environment variables will also set the `Org2` peer, ``peer0.org2.example.com``, as the target peer.
   242  ```
   243  export CORE_PEER_LOCALMSPID="Org2MSP"
   244  export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
   245  export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
   246  export CORE_PEER_ADDRESS=localhost:9051
   247  ```
   248  Now repeat the command to join the peer from `Org2` to `channel1`:
   249  ```
   250  peer channel join -b ./channel-artifacts/channel1.block
   251  ```
   252  When successful, the output of this command contains the following:
   253  ```
   254  [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
   255  [channelCmd] executeJoin -> INFO 002 Successfully submitted proposal to join channel
   256  ```
   257  
   258  ## Set anchor peer
   259  
   260  Finally, after an organization 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).
   261  
   262  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`.
   263  
   264  **Note:** If [jq](https://stedolan.github.io/jq/) is not already installed on your local machine, you need to install it now to complete these steps.  
   265  
   266  We will start by selecting the peer from `Org1` to be an anchor peer. 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:
   267  ```
   268  export CORE_PEER_LOCALMSPID="Org1MSP"
   269  export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
   270  export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
   271  export CORE_PEER_ADDRESS=localhost:7051
   272  ```
   273  
   274  You can use the following command to fetch the channel configuration:
   275  ```
   276  peer channel fetch config channel-artifacts/config_block.pb -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com -c channel1 --tls --cafile "$ORDERER_CA"
   277  ```
   278  Because the most recent channel configuration block is the channel genesis block, the command returns block `0` from the channel.
   279  ```
   280  [channelCmd] InitCmdFactory -> INFO 001 Endorser and orderer connections initialized
   281  [cli.common] readBlock -> INFO 002 Received block: 0
   282  [channelCmd] fetch -> INFO 003 Retrieving last config block: 0
   283  [cli.common] readBlock -> INFO 004 Received block: 0
   284  ```
   285  
   286  The channel configuration block `config_block.pb` is 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:
   287  ```
   288  cd channel-artifacts
   289  ```
   290  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.
   291  
   292  ```
   293  configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
   294  jq '.data.data[0].payload.data.config' config_block.json > config.json
   295  ```
   296  
   297  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.
   298  ```
   299  cp config.json config_copy.json
   300  ```
   301  
   302  You can use the `jq` tool to add the `Org1` anchor peer to the channel configuration.
   303  ```
   304  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
   305  ```
   306  
   307  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.
   308  ```
   309  configtxlator proto_encode --input config.json --type common.Config --output config.pb
   310  configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
   311  configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb
   312  ```
   313  
   314  The new protobuf named `config_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.
   315  
   316  ```
   317  configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
   318  echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
   319  configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
   320  ```
   321  
   322  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:
   323  ```
   324  cd ..
   325  ```
   326  
   327  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.
   328  ```
   329  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"
   330  ```
   331  
   332  When the channel update is successful, you should see the following response:
   333  ```
   334  [channelCmd] update -> INFO 002 Successfully submitted channel update
   335  ```
   336  
   337  We can also set the peer from `Org2` to be an anchor peer. 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:
   338  ```
   339  export CORE_PEER_LOCALMSPID="Org2MSP"
   340  export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
   341  export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp
   342  export CORE_PEER_ADDRESS=localhost:9051
   343  ```
   344  
   345  Pull the latest channel configuration block, which is now the second block on the channel:
   346  ```
   347  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"
   348  ```
   349  
   350  Navigate back to the `channel-artifacts` directory:
   351  ```
   352  cd channel-artifacts
   353  ```
   354  
   355  You can then decode and copy the configuration block.
   356  ```
   357  configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json
   358  jq '.data.data[0].payload.data.config' config_block.json > config.json
   359  cp config.json config_copy.json
   360  ```
   361  
   362  Add the `Org2` peer that is joined to the channel as the anchor peer in the channel configuration:
   363  ```
   364  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
   365  ```
   366  
   367  We can now convert both the original and updated channel configurations back into protobuf format and calculate the difference between them.
   368  ```
   369  configtxlator proto_encode --input config.json --type common.Config --output config.pb
   370  configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb
   371  configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output config_update.pb
   372  ```
   373  
   374  Wrap the configuration update in a transaction envelope to create the channel configuration update transaction:
   375  ```
   376  configtxlator proto_decode --input config_update.pb --type common.ConfigUpdate --output config_update.json
   377  echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat config_update.json)'}}}' | jq . > config_update_in_envelope.json
   378  configtxlator proto_encode --input config_update_in_envelope.json --type common.Envelope --output config_update_in_envelope.pb
   379  ```
   380  
   381  Navigate back to the `test-network` directory.
   382  ```
   383  cd ..
   384  ```
   385  
   386  Update the channel and set the `Org2` anchor peer by issuing the following command:
   387  ```
   388  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"
   389  ```
   390  
   391  If you want to learn more about how to submit a channel update request, see [update a channel configuration](../config_update.html).
   392  
   393  You can confirm that the channel has been updated successfully by running the `peer channel info` command:
   394  ```
   395  peer channel getinfo -c channel1
   396  ```
   397  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 and the hashes are updated:
   398  ```
   399  Blockchain info: {"height":3,"currentBlockHash":"GKqqk/HNi9x/6YPnaIUpMBlb0Ew6ovUnSB5MEF7Y5Pc=","previousBlockHash":"cl4TOQpZ30+d17OF5YOkX/mtMjJpUXiJmtw8+sON8a8="}
   400  ```
   401  
   402  ## Deploy a chaincode to the new channel
   403  
   404  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:
   405  ```
   406  ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go/ -ccl go -c channel1
   407  ```
   408  
   409  After you run the command, you should see the chaincode being deployed to the channel in your logs.
   410  
   411  ```
   412  Committed chaincode definition for chaincode 'basic' on channel 'channel1':
   413  Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true]
   414  Query chaincode definition successful on peer0.org2 on channel 'channel1'
   415  Chaincode initialization is not required
   416  ```
   417  Then run the following command to initialize some assets on the ledger:
   418  ```
   419  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":[]}'
   420  ```
   421  When successful you will see:
   422  ```
   423  [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001 Chaincode invoke successful. result: status:200
   424  ```
   425  
   426  Confirm the assets were added to the ledger by issuing the following query:
   427  
   428  ```
   429  peer chaincode query -C channel1 -n basic -c '{"Args":["getAllAssets"]}'
   430  ```
   431  
   432  You should see output similar to the following:
   433  ```
   434  [{"ID":"asset1","color":"blue","size":5,"owner":"Tomoko","appraisedValue":300},
   435  {"ID":"asset2","color":"red","size":5,"owner":"Brad","appraisedValue":400},
   436  {"ID":"asset3","color":"green","size":10,"owner":"Jin Soo","appraisedValue":500},
   437  {"ID":"asset4","color":"yellow","size":10,"owner":"Max","appraisedValue":600},
   438  {"ID":"asset5","color":"black","size":15,"owner":"Adriana","appraisedValue":700},
   439  {"ID":"asset6","color":"white","size":15,"owner":"Michel","appraisedValue":800}]
   440  ```
   441  
   442  ### Create a channel without the test network
   443  
   444  This tutorial has taken you through the basic steps to create a channel on the test network by using the `osnadmin channel join` command. When you are ready to build your own network, follow the steps in the [Create a channel](create_channel_participation.html) tutorial to learn more about using the `osnadmin channel` commands.
   445  <!--- Licensed under Creative Commons Attribution 4.0 International License
   446  https://creativecommons.org/licenses/by/4.0/ -->