github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/docs/source/channel_update_tutorial.rst (about) 1 Adding an Org to a Channel 2 ========================== 3 4 .. note:: Ensure that you have downloaded the appropriate images and binaries 5 as outlined in :doc:`install` and :doc:`prereqs` that conform to the 6 version of this documentation (which can be found at the bottom of the 7 table of contents to the left). 8 9 This tutorial extends the Fabric test network by adding a new organization 10 -- Org3 -- to an application channel. 11 12 While we will focus on adding a new organization to the channel, you can use a 13 similar process to make other channel configuration updates (updating modification 14 policies or altering batch size, for example). To learn more about the process 15 and possibilities of channel config updates in general, check out :doc:`config_update`). 16 It's also worth noting that channel configuration updates like the one 17 demonstrated here will usually be the responsibility of an organization admin 18 (rather than a chaincode or application developer). 19 20 Setup the Environment 21 ~~~~~~~~~~~~~~~~~~~~~ 22 23 We will be operating from the root of the ``test-network`` subdirectory within 24 your local clone of ``fabric-samples``. Change into that directory now. 25 26 .. code:: bash 27 28 cd fabric-samples/test-network 29 30 First, use the ``network.sh`` script to tidy up. This command will kill any active 31 or stale Docker containers and remove previously generated artifacts. It is by no 32 means **necessary** to bring down a Fabric network in order to perform channel 33 configuration update tasks. However, for the sake of this tutorial, we want to operate 34 from a known initial state. Therefore let's run the following command to clean up any 35 previous environments: 36 37 .. code:: bash 38 39 ./network.sh down 40 41 You can now use the script to bring up the test network with one channel named 42 ``channel1``: 43 44 .. code:: bash 45 46 ./network.sh up createChannel -c channel1 47 48 If the command was successful, you can see the following message printed in your 49 logs: 50 51 .. code:: bash 52 53 Channel 'channel1' joined 54 55 Now that you have a clean version of the test network running on your machine, we 56 can start the process of adding a new org to the channel we created. First, we are 57 going use a script to add Org3 to the channel to confirm that the process works. 58 Then, we will go through the step by step process of adding Org3 by updating the 59 channel configuration. 60 61 Bring Org3 into the Channel with the Script 62 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 63 64 You should be in the ``test-network`` directory. To use the script, simply issue 65 the following commands: 66 67 .. code:: bash 68 69 cd addOrg3 70 ./addOrg3.sh up -c channel1 71 72 The output here is well worth reading. You'll see the Org3 crypto material being 73 generated, the Org3 organization definition being created, and then the channel 74 configuration being updated, signed, and then submitted to the channel. 75 76 If everything goes well, you'll get this message: 77 78 .. code:: bash 79 80 Org3 peer successfully added to network 81 82 Now that we have confirmed we can add Org3 to our channel, we can go through the 83 steps to update the channel configuration that the script completed behind the 84 scenes. 85 86 Bring Org3 into the Channel Manually 87 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 88 89 If you just used the ``addOrg3.sh`` script, you'll need to bring your network down. 90 The following command will bring down all running components and remove the crypto 91 material for all organizations: 92 93 .. code:: bash 94 95 cd .. 96 ./network.sh down 97 98 After the network is brought down, bring it back up again: 99 100 .. code:: bash 101 102 ./network.sh up createChannel -c channel1 103 104 This will bring your network back to the same state it was in before you executed 105 the ``addOrg3.sh`` script. 106 107 Now we're ready to add Org3 to the channel manually. As a first step, we'll need 108 to generate Org3's crypto material. 109 110 Generate the Org3 Crypto Material 111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 112 113 In another terminal, change into the ``addOrg3`` subdirectory from 114 ``test-network``. 115 116 .. code:: bash 117 118 cd addOrg3 119 120 First, we are going to create the certificates and keys for the Org3 peer, along 121 with an application and admin user. Because we are updating an example channel, 122 we are going to use the cryptogen tool instead of using a Certificate Authority. 123 The following command uses cryptogen to read the ``org3-crypto.yaml`` file 124 and generate the Org3 crypto material in a new ``org3.example.com`` folder: 125 126 .. code:: bash 127 128 ../../bin/cryptogen generate --config=org3-crypto.yaml --output="../organizations" 129 130 You can find the generated Org3 crypto material alongside the certificates and 131 keys for Org1 and Org2 in the ``test-network/organizations/peerOrganizations`` 132 directory. 133 134 Once we have created the Org3 crypto material, we can use the configtxgen 135 tool to print out the Org3 organization definition. We will preface the command 136 by telling the tool to look in the current directory for the ``configtx.yaml`` 137 file that it needs to ingest. 138 139 .. code:: bash 140 141 export FABRIC_CFG_PATH=$PWD 142 ../../bin/configtxgen -printOrg Org3MSP > ../organizations/peerOrganizations/org3.example.com/org3.json 143 144 The above command creates a JSON file -- ``org3.json`` -- and writes it to the 145 ``test-network/organizations/peerOrganizations/org3.example.com`` folder. The 146 organization definition contains the policy definitions for Org3, the NodeOU definitions 147 for Org3, and two important certificates encoded in base64 format: 148 149 * a CA root cert, used to establish the organizations root of trust 150 * a TLS root cert, used by the gossip protocol to identify Org3 for block dissemination and service discovery 151 152 We will add Org3 to the channel by appending this organization definition to 153 the channel configuration. 154 155 Bring up Org3 components 156 ~~~~~~~~~~~~~~~~~~~~~~~~ 157 158 After we have created the Org3 certificate material, we can now bring up the 159 Org3 peer. From the ``addOrg3`` directory, issue the following command: 160 161 .. code:: bash 162 163 docker-compose -f docker/docker-compose-org3.yaml up -d 164 165 If the command is successful, you will see the creation of the Org3 peer: 166 167 .. code:: 168 169 Creating peer0.org3.example.com ... done 170 171 This Docker Compose file has been configured to bridge across our initial network, 172 so that the Org3 peer resolves with the existing peers and ordering 173 node of the test network. 174 175 .. note:: the `./addOrg3.sh up` command uses a `fabric-tools` CLI container to perform 176 the channel configuration update process demonstrated below. This is to avoid the 177 `jq` dependency requirement for first-time users. However, it is recommended to 178 follow the process below directly on your local machine instead of using the unnecessary 179 CLI container. 180 181 Fetch the Configuration 182 ~~~~~~~~~~~~~~~~~~~~~~~ 183 184 Let's go fetch the most recent config block for the channel -- ``channel1``. 185 186 The reason why we have to pull the latest version of the config is because channel 187 config elements are versioned. Versioning is important for several reasons. It prevents 188 config changes from being repeated or replayed (for instance, reverting to a channel config 189 with old CRLs would represent a security risk). Also it helps ensure concurrency (if you 190 want to remove an Org from your channel, for example, after a new Org has been added, 191 versioning will help prevent you from removing both Orgs, instead of just the Org you want 192 to remove). 193 194 Navigate back to the ``test-network`` directory. 195 196 .. code:: bash 197 198 cd .. 199 200 Because Org3 is not yet a member of the channel, we need to operate as the admin 201 of another organization to fetch the channel config. Because Org1 is a member of the channel, the 202 Org1 admin has permission to fetch the channel config from the ordering service. 203 Issue the following commands to operate as the Org1 admin. 204 205 .. code:: bash 206 207 # you can issue all of these commands at once 208 209 export PATH=${PWD}/../bin:$PATH 210 export FABRIC_CFG_PATH=${PWD}/../config/ 211 export CORE_PEER_TLS_ENABLED=true 212 export CORE_PEER_LOCALMSPID="Org1MSP" 213 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 214 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 215 export CORE_PEER_ADDRESS=localhost:7051 216 217 We can now issue the command to fetch the latest config block: 218 219 .. code:: bash 220 221 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" 222 223 224 This command saves the binary protobuf channel configuration block to 225 ``config_block.pb``. Note that the choice of name and file extension is arbitrary. 226 However, following a convention which identifies both the type of object being 227 represented and its encoding (protobuf or JSON) is recommended. 228 229 When you issued the ``peer channel fetch`` command, the following output is 230 displayed in your logs: 231 232 .. code:: 233 234 2021-01-07 18:46:33.687 UTC [cli.common] readBlock -> INFO 004 Received block: 2 235 236 This is telling us that the most recent configuration block for ``channel1`` is 237 actually block 2, **NOT** the genesis block. By default, the ``peer channel fetch config`` 238 command returns the most **recent** configuration block for the targeted channel, which 239 in this case is the third block. This is because the test network script, ``network.sh``, defined anchor 240 peers for our two organizations -- ``Org1`` and ``Org2`` -- in two separate channel update 241 transactions. As a result, we have the following configuration sequence: 242 243 * block 0: genesis block 244 * block 1: Org1 anchor peer update 245 * block 2: Org2 anchor peer update 246 247 Convert the Configuration to JSON and Trim It Down 248 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 249 250 The channel configuration block was stored in the ``channel-artifacts`` folder to keep 251 the update process separate from other artifacts. Change into the ``channel-artifacts`` 252 folder to complete the next steps: 253 254 .. code:: bash 255 256 cd channel-artifacts 257 258 Now we will make use of the ``configtxlator`` tool to decode this channel 259 configuration block into JSON format (which can be read and modified by humans). 260 We also must strip away all of the headers, metadata, creator signatures, and 261 so on that are irrelevant to the change we want to make. We accomplish this by 262 means of the ``jq`` tool (you will need to install the `jq tool <https://stedolan.github.io/jq/>`_ on your local machine): 263 264 .. code:: bash 265 266 configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json 267 jq .data.data[0].payload.data.config config_block.json > config.json 268 269 This command leaves us with a trimmed down JSON object -- ``config.json`` -- which 270 will serve as the baseline for our config update. 271 272 Take a moment to open this file inside your text editor of choice (or in your 273 browser). Even after you're done with this tutorial, it will be worth studying it 274 as it reveals the underlying configuration structure and the other kind of channel 275 updates that can be made. We discuss them in more detail in :doc:`config_update`. 276 277 Add the Org3 Crypto Material 278 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 279 280 .. note:: The steps you've taken up to this point will be nearly identical no matter 281 what kind of config update you're trying to make. We've chosen to add an 282 org with this tutorial because it's one of the most complex channel 283 configuration updates you can attempt. 284 285 We'll use the ``jq`` tool once more to append the Org3 configuration definition 286 -- ``org3.json`` -- to the channel's application groups field, and name the output 287 -- ``modified_config.json``. 288 289 .. code:: bash 290 291 jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ../organizations/peerOrganizations/org3.example.com/org3.json > modified_config.json 292 293 Now we have two JSON files of interest -- ``config.json`` and 294 ``modified_config.json``. The initial file contains only Org1 and Org2 295 material, whereas the "modified" file contains all three Orgs. At this 296 point it's simply a matter of re-encoding these two JSON files and calculating 297 the delta. 298 299 First, translate ``config.json`` back into a protobuf called ``config.pb``: 300 301 .. code:: bash 302 303 configtxlator proto_encode --input config.json --type common.Config --output config.pb 304 305 Next, encode ``modified_config.json`` to ``modified_config.pb``: 306 307 .. code:: bash 308 309 configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb 310 311 Now use ``configtxlator`` to calculate the delta between these two config 312 protobufs. This command will output a new protobuf binary named ``org3_update.pb``: 313 314 .. code:: bash 315 316 configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output org3_update.pb 317 318 This new proto -- ``org3_update.pb`` -- contains the Org3 definitions and high 319 level pointers to the Org1 and Org2 material. We are able to forgo the extensive 320 MSP material and modification policy information for Org1 and Org2 because this 321 data is already present within the channel's genesis block. As such, we only need 322 the delta between the two configurations. 323 324 Before submitting the channel update, we need to perform a few final steps. First, 325 let's decode this object into editable JSON format and call it ``org3_update.json``: 326 327 .. code:: bash 328 329 configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate --output org3_update.json 330 331 Now, we have a decoded update file -- ``org3_update.json`` -- that we need to wrap 332 in an envelope message. This step will give us back the header field that we stripped away 333 earlier. We'll name this file ``org3_update_in_envelope.json``: 334 335 .. code:: bash 336 337 echo '{"payload":{"header":{"channel_header":{"channel_id":"'channel1'", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json 338 339 Using our properly formed JSON -- ``org3_update_in_envelope.json`` -- we will 340 leverage the ``configtxlator`` tool one last time and convert it into the 341 fully fledged protobuf format that Fabric requires. We'll name our final update 342 object ``org3_update_in_envelope.pb``: 343 344 .. code:: bash 345 346 configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb 347 348 Sign and Submit the Config Update 349 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 350 351 Almost done! 352 353 We now have a protobuf binary -- ``org3_update_in_envelope.pb``. However, we need signatures from the requisite Admin users before the config can be written to the ledger. The modification policy (mod_policy) for our channel Application group is set to the default of "MAJORITY", which means that we need a majority of existing org admins to sign it. Because we have only two orgs -- Org1 and Org2 -- and the majority of two is two, we need both of them to sign. Without both signatures, the ordering service will reject the transaction for failing to fulfill the policy. 354 355 First, let's sign this update proto as Org1. Navigate back to the ``test-network`` 356 directory: 357 358 .. code:: bash 359 360 cd .. 361 362 Remember that we exported the necessary environment variables to operate as the Org1 admin. 363 As a result, the following ``peer channel signconfigtx`` command will sign the update as Org1. 364 365 .. code:: bash 366 367 peer channel signconfigtx -f channel-artifacts/org3_update_in_envelope.pb 368 369 The final step is to switch the container's identity to reflect the Org2 Admin 370 user. We do this by exporting four environment variables specific to the Org2 MSP. 371 372 .. note:: Switching between organizations to sign a config transaction (or to do anything 373 else) is not reflective of a real-world Fabric operation. A single container 374 would never be mounted with an entire network's crypto material. Rather, the 375 config update would need to be securely passed out-of-band to an Org2 376 Admin for inspection and approval. 377 378 Export the Org2 environment variables: 379 380 .. code:: bash 381 382 # you can issue all of these commands at once 383 384 export CORE_PEER_TLS_ENABLED=true 385 export CORE_PEER_LOCALMSPID="Org2MSP" 386 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 387 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 388 export CORE_PEER_ADDRESS=localhost:9051 389 390 Lastly, we will issue the ``peer channel update`` command. The Org2 Admin signature 391 will be attached to this call so there is no need to manually sign the protobuf a 392 second time: 393 394 .. note:: The upcoming update call to the ordering service will undergo a series 395 of systematic signature and policy checks. As such you may find it 396 useful to stream and inspect the ordering node's logs. You can issue a 397 ``docker logs -f orderer.example.com`` command to display them. 398 399 Send the update call: 400 401 .. code:: bash 402 403 peer channel update -f channel-artifacts/org3_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" 404 405 You should see a message similar to the following if your update has been submitted successfully: 406 407 .. code:: bash 408 409 2021-01-07 18:51:48.015 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update 410 411 The successful channel update call returns a new block -- block 3 -- to all of the 412 peers on the channel. If you remember, blocks 0-2 are the initial channel 413 configurations. Block 3 serves as the most recent channel configuration with 414 Org3 now defined on the channel. 415 416 You can inspect the logs for ``peer0.org1.example.com`` by issuing the following command: 417 418 .. code:: bash 419 420 docker logs -f peer0.org1.example.com 421 422 423 Join Org3 to the Channel 424 ~~~~~~~~~~~~~~~~~~~~~~~~ 425 426 At this point, the channel configuration has been updated to include our new 427 organization -- Org3 -- meaning that peers attached to it can now join ``channel1``. 428 429 Export the following environment variables to operate as the Org3 Admin: 430 431 .. code:: bash 432 433 # you can issue all of these commands at once 434 435 export CORE_PEER_TLS_ENABLED=true 436 export CORE_PEER_LOCALMSPID="Org3MSP" 437 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 438 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 439 export CORE_PEER_ADDRESS=localhost:11051 440 441 Org3 peers can join ``channel1`` by either the genesis block or a snapshot that is created 442 after Org3 has joined the channel. 443 444 To join by the genesis block, send a call to the ordering service asking for the genesis block of 445 ``channel1``. As a result of the successful channel update, the ordering service 446 will verify that Org3 can pull the genesis block and join the channel. If Org3 had not 447 been successfully appended to the channel config, the ordering service would 448 reject this request. 449 450 .. note:: Again, you may find it useful to stream the ordering node's logs 451 to reveal the sign/verify logic and policy checks. 452 453 Use the ``peer channel fetch`` command to retrieve this block: 454 455 .. code:: bash 456 457 peer channel fetch 0 channel-artifacts/channel1.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" 458 459 Notice, that we are passing a ``0`` to indicate that we want the first block on 460 the channel's ledger; the genesis block. If we simply passed the 461 ``peer channel fetch config`` command, then we would have received block 3 -- the 462 updated config with Org3 defined. However, we can't begin our ledger with a 463 downstream block -- we must start with block 0. 464 465 If successful, the command returned the genesis block to a file named ``channel1.block``. 466 We can now use this block to join the peer to the channel. Issue the 467 ``peer channel join`` command and pass in the genesis block to join the Org3 468 peer to the channel: 469 470 .. code:: bash 471 472 peer channel join -b channel-artifacts/channel1.block 473 474 To join by a snapshot, follow the instruction in `Taking a snapshot <peer_ledger_snapshot.html#taking-a-snapshot>`__ 475 to take a snapshot on an existing peer. The snapshot should be taken after Org3 has been added to ``channel1`` 476 to ensure that the snapshot contains the updated channel configuration including Org3. 477 Locate the snapshot directory, copy it to the filesystem of the new Org3 peer, and issue the 478 ``peer channel joinbysnapshot`` command using the path to the snapshot on your file system. 479 480 .. code:: bash 481 482 peer channel joinbysnapshot --snapshotpath <path to snapshot> 483 484 Configuring Leader Election 485 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 486 487 .. note:: This section is included as a general reference for understanding 488 the leader election settings when adding organizations to a network 489 after the initial channel configuration has completed. 490 491 Newly joining peers are bootstrapped with the genesis block, which does not 492 contain information about the organization that is being added in the channel 493 configuration update. Therefore new peers are not able to utilize gossip as 494 they cannot verify blocks forwarded by other peers from their own organization 495 until they get the configuration transaction which added the organization to the 496 channel. Newly added peers must therefore have one of the following 497 configurations so that they receive blocks from the ordering service: 498 499 1. To ensure that peers always receive blocks directly from the ordering service, 500 configure the peer to be an organization leader: 501 502 :: 503 504 CORE_PEER_GOSSIP_USELEADERELECTION=false 505 CORE_PEER_GOSSIP_ORGLEADER=true 506 507 508 .. note:: This configuration is the default starting in Fabric v2.2 and must be the 509 same for all new peers added to the channel. 510 511 2. To eventually utilize dynamic leader election within the organization, 512 configure the peer to use leader election: 513 514 :: 515 516 CORE_PEER_GOSSIP_USELEADERELECTION=true 517 CORE_PEER_GOSSIP_ORGLEADER=false 518 519 520 .. note:: Because peers of the newly added organization won't initially be able to form 521 membership view, this option will be similar to the static 522 configuration, as each peer will start proclaiming itself to be a 523 leader. However, once they get updated with the configuration 524 transaction that adds the organization to the channel, there will be 525 only one active leader for the organization. Therefore, it is 526 recommended to leverage this option if you eventually want the 527 organization's peers to utilize leader election. 528 529 530 .. _upgrade-and-invoke: 531 532 Install, define, and invoke chaincode 533 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 535 We can confirm that Org3 is a member of ``channel1`` by installing and invoking 536 a chaincode on the channel. If the existing channel members have already committed 537 a chaincode definition to the channel, a new organization can start using the 538 chaincode by approving the chaincode definition. 539 540 .. note:: These instructions use the Fabric chaincode lifecycle introduced in 541 the v2.0 release. If you would like to use the previous lifecycle to 542 install and instantiate a chaincode, visit the v1.4 version of the 543 `Adding an org to a channel tutorial <https://hyperledger-fabric.readthedocs.io/en/release-1.4/channel_update_tutorial.html>`__. 544 545 Before we install a chaincode as Org3, we can use the ``./network.sh`` script to 546 deploy the Basic chaincode on the channel. Open a new terminal and navigate to the ``test-network`` directory. You can then use 547 use the ``test-network`` script to deploy the Basic chaincode: 548 549 .. code:: bash 550 551 cd fabric-samples/test-network 552 ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go/ -ccl go -c channel1 553 554 The script will install the Basic chaincode on the Org1 and Org2 peers, approve 555 the chaincode definition for Org1 and Org2, and then commit the chaincode 556 definition to the channel. Once the chaincode definition has been committed to 557 the channel, the Basic chaincode is initialized and invoked to put initial data 558 on the ledger. The commands below assume that we are still using the channel 559 ``channel1``. 560 561 After the chaincode has been to deployed we can use the following steps to use 562 invoke Basic chaincode as Org3. Copy and paste the following environment 563 variables in your terminal in order to interact with the network as the Org3 564 admin: 565 566 .. code:: bash 567 568 export PATH=${PWD}/../bin:$PATH 569 export FABRIC_CFG_PATH=$PWD/../config/ 570 export CORE_PEER_TLS_ENABLED=true 571 export CORE_PEER_LOCALMSPID="Org3MSP" 572 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 573 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 574 export CORE_PEER_ADDRESS=localhost:11051 575 576 The first step is to package the Basic chaincode: 577 578 .. code:: bash 579 580 peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go/ --lang golang --label basic_1 581 582 This command will create a chaincode package named ``basic.tar.gz``, which we can 583 install on the Org3 peer. Modify the command accordingly if the channel is running a 584 chaincode written in Java or Node.js. Issue the following command to install the 585 chaincode package ``peer0.org3.example.com``: 586 587 .. code:: bash 588 589 peer lifecycle chaincode install basic.tar.gz 590 591 592 The next step is to approve the chaincode definition of Basic as Org3. Org3 593 needs to approve the same definition that Org1 and Org2 approved and committed 594 to the channel. In order to invoke the chaincode, Org3 needs to include the 595 package identifier in the chaincode definition. You can find the package 596 identifier by querying your peer: 597 598 .. code:: bash 599 600 peer lifecycle chaincode queryinstalled 601 602 You should see output similar to the following: 603 604 .. code:: bash 605 606 Get installed chaincodes on peer: 607 Package ID: basic_1:5443b5b557efd3faece8723883d28d6f7026c0bf12245de109b89c5c4fe64887, Label: basic_1 608 609 We are going to need the package ID in a future command, so lets go ahead and 610 save it as an environment variable. Paste the package ID returned by the 611 ``peer lifecycle chaincode queryinstalled`` command into the command below. The 612 package ID may not be the same for all users, so you need to complete this step 613 using the package ID returned from your console. 614 615 .. code:: bash 616 617 export CC_PACKAGE_ID=basic_1:5443b5b557efd3faece8723883d28d6f7026c0bf12245de109b89c5c4fe64887 618 619 Use the following command to approve a definition of the basic chaincode 620 for Org3: 621 622 .. code:: bash 623 624 # use the --package-id flag to provide the package identifier 625 # use the --init-required flag to request the ``Init`` function be invoked to initialize the chaincode 626 peer lifecycle chaincode approveformyorg -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" --channelID channel1 --name basic --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 627 628 629 You can use the ``peer lifecycle chaincode querycommitted`` command to check if 630 the chaincode definition you have approved has already been committed to the 631 channel. 632 633 .. code:: bash 634 635 # use the --name flag to select the chaincode whose definition you want to query 636 peer lifecycle chaincode querycommitted --channelID channel1 --name basic --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" 637 638 A successful command will return information about the committed definition: 639 640 .. code:: bash 641 642 Committed chaincode definition for chaincode 'basic' on channel 'channel1': 643 Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true, Org3MSP: true] 644 645 Org3 can use the basic chaincode after it approves the chaincode definition 646 that was committed to the channel. The chaincode definition uses the default endorsement 647 policy, which requires a majority of organizations on the channel endorse a transaction. 648 This implies that if an organization is added to or removed from the channel, the 649 endorsement policy will be updated automatically. We previously needed endorsements 650 from Org1 and Org2 (2 out of 2). Now we need endorsements from two organizations 651 out of Org1, Org2, and Org3 (2 out of 3). 652 653 Populate the ledger with some sample assets. We'll get endorsements from the Org2 peer 654 and the new Org3 peer so that the endorsement policy is satisfied. 655 656 .. code:: bash 657 658 peer chaincode invoke -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" -C channel1 -n basic --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" --peerAddresses localhost:11051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt" -c '{"function":"InitLedger","Args":[]}' 659 660 You can query the chaincode to ensure that the Org3 peer committed the data. 661 662 .. code:: bash 663 664 peer chaincode query -C channel1 -n basic -c '{"Args":["GetAllAssets"]}' 665 666 You should see the initial list of assets that were added to the ledger as a 667 response. 668 669 670 Conclusion 671 ~~~~~~~~~~ 672 673 The channel configuration update process is indeed quite involved, but there is a 674 logical method to the various steps. The endgame is to form a delta transaction object 675 represented in protobuf binary format and then acquire the requisite number of admin 676 signatures such that the channel configuration update transaction fulfills the channel's 677 modification policy. 678 679 The ``configtxlator`` and ``jq`` tools, along with the ``peer channel`` 680 commands, provide us with the functionality to accomplish this task. 681 682 Updating the Channel Config to include an Org3 Anchor Peer (Optional) 683 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 684 685 The Org3 peers were able to establish gossip connection to the Org1 and Org2 686 peers since Org1 and Org2 had anchor peers defined in the channel configuration. 687 Likewise newly added organizations like Org3 should also define their anchor peers 688 in the channel configuration so that any new peers from other organizations can 689 directly discover an Org3 peer. In this section, we will make a channel 690 configuration update to define an Org3 anchor peer. The process will be similar 691 to the previous configuration update, therefore we'll go faster this time. 692 693 As before, we will fetch the latest channel configuration to get started. 694 Fetch the most recent config block for the channel, using the ``peer channel fetch`` command. 695 696 .. code:: bash 697 698 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" 699 700 After fetching the config block we will want to convert it into JSON format. To do 701 this we will use the configtxlator tool, as done previously when adding Org3 to the 702 channel. First, change into the ``channel-artifacts`` folder: 703 704 .. code:: bash 705 706 cd channel-artifacts 707 708 When converting it we need to remove all the headers, metadata, and signatures 709 that are not required to update Org3 to include an anchor peer by using the ``jq`` 710 tool. This information will be reincorporated later before we proceed to update the 711 channel configuration. 712 713 .. code:: bash 714 715 configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json 716 jq .data.data[0].payload.data.config config_block.json > config.json 717 718 The ``config.json`` is the now trimmed JSON representing the latest channel configuration 719 that we will update. 720 721 Using the ``jq`` tool again, we will update the configuration JSON with the Org3 anchor peer we 722 want to add. 723 724 .. code:: bash 725 726 jq '.channel_group.groups.Application.groups.Org3MSP.values += {"AnchorPeers":{"mod_policy": "Admins","value":{"anchor_peers": [{"host": "peer0.org3.example.com","port": 11051}]},"version": "0"}}' config.json > modified_anchor_config.json 727 728 We now have two JSON files, one for the current channel configuration, 729 ``config.json``, and one for the desired channel configuration ``modified_anchor_config.json``. 730 Next we convert each of these back into protobuf format and calculate the delta between the two. 731 732 Translate ``config.json`` back into protobuf format as ``config.pb`` 733 734 .. code:: bash 735 736 configtxlator proto_encode --input config.json --type common.Config --output config.pb 737 738 Translate the ``modified_anchor_config.json`` into protobuf format as ``modified_anchor_config.pb`` 739 740 .. code:: bash 741 742 configtxlator proto_encode --input modified_anchor_config.json --type common.Config --output modified_anchor_config.pb 743 744 Calculate the delta between the two protobuf formatted configurations. 745 746 .. code:: bash 747 748 configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_anchor_config.pb --output anchor_update.pb 749 750 Now that we have the desired update to the channel we must wrap it in an envelope 751 message so that it can be properly read. To do this we must first convert the protobuf 752 back into a JSON that can be wrapped. 753 754 We will use the ``configtxlator`` command again to convert ``anchor_update.pb`` into ``anchor_update.json`` 755 756 .. code:: bash 757 758 configtxlator proto_decode --input anchor_update.pb --type common.ConfigUpdate --output anchor_update.json 759 760 Next we will wrap the update in an envelope message, restoring the previously 761 stripped away header, outputting it to ``anchor_update_in_envelope.json`` 762 763 .. code:: bash 764 765 echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat anchor_update.json)'}}}' | jq . > anchor_update_in_envelope.json 766 767 Now that we have reincorporated the envelope we need to convert it 768 to a protobuf so it can be properly signed and submitted to the orderer for the update. 769 770 .. code:: bash 771 772 configtxlator proto_encode --input anchor_update_in_envelope.json --type common.Envelope --output anchor_update_in_envelope.pb 773 774 Now that the update has been properly formatted it is time to sign off and submit it. 775 776 Navigate back to the ``test-network`` directory: 777 778 .. code:: bash 779 780 cd .. 781 782 783 Since this is only an update to Org3 we only need to have Org3 sign off on the update. Run the following 784 commands to make sure that we are operating as the Org3 admin: 785 786 .. code:: bash 787 788 # you can issue all of these commands at once 789 790 export CORE_PEER_LOCALMSPID="Org3MSP" 791 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 792 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 793 export CORE_PEER_ADDRESS=localhost:11051 794 795 We can now just use the ``peer channel update`` command to sign the update as the 796 Org3 admin before submitting it to the orderer. 797 798 .. code:: bash 799 800 peer channel update -f channel-artifacts/anchor_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" 801 802 The orderer receives the config update request and cuts a block with the updated configuration. 803 As peers receive the block, they will process the configuration updates. 804 805 Inspect the logs for one of the peers. While processing the configuration transaction from the new block, 806 you will see gossip re-establish connections using the new anchor peer for Org3. This is proof 807 that the configuration update has been successfully applied! 808 809 .. code:: bash 810 811 docker logs -f peer0.org1.example.com 812 813 .. code:: bash 814 815 2021-01-07 19:07:01.244 UTC [gossip.gossip] learnAnchorPeers -> INFO 05a Learning about the configured anchor peers of Org1MSP for channel channel1: [{peer0.org1.example.com 7051}] 816 2021-01-07 19:07:01.243 UTC [gossip.gossip] learnAnchorPeers -> INFO 05b Learning about the configured anchor peers of Org2MSP for channel channel1: [{peer0.org2.example.com 9051}] 817 2021-01-07 19:07:01.244 UTC [gossip.gossip] learnAnchorPeers -> INFO 05c Learning about the configured anchor peers of Org3MSP for channel channel1: [{peer0.org3.example.com 11051}] 818 819 Congratulations, you have now made two configuration updates --- one to add Org3 to the channel, 820 and a second to define an anchor peer for Org3. 821 822 .. Licensed under Creative Commons Attribution 4.0 International License 823 https://creativecommons.org/licenses/by/4.0/