github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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:: bash 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 cd .. 198 199 Because Org3 is not yet a member of the channel, we need to operate as the admin 200 of another organization to fetch the channel config. Because Org1 is a member of the channel, the 201 Org1 admin has permission to fetch the channel config from the ordering service. 202 Issue the following commands to operate as the Org1 admin. 203 204 .. code:: bash 205 206 # you can issue all of these commands at once 207 208 export PATH=${PWD}/../bin:$PATH 209 export FABRIC_CFG_PATH=${PWD}/../config/ 210 export CORE_PEER_TLS_ENABLED=true 211 export CORE_PEER_LOCALMSPID="Org1MSP" 212 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 213 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 214 export CORE_PEER_ADDRESS=localhost:7051 215 216 We can now issue the command to fetch the latest config block: 217 218 .. code:: bash 219 220 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 221 222 223 This command saves the binary protobuf channel configuration block to 224 ``config_block.pb``. Note that the choice of name and file extension is arbitrary. 225 However, following a convention which identifies both the type of object being 226 represented and its encoding (protobuf or JSON) is recommended. 227 228 When you issued the ``peer channel fetch`` command, the following output is 229 displayed in your logs: 230 231 .. code:: bash 232 233 2021-01-07 18:46:33.687 UTC [cli.common] readBlock -> INFO 004 Received block: 2 234 235 This is telling us that the most recent configuration block for ``channel1`` is 236 actually block 2, **NOT** the genesis block. By default, the ``peer channel fetch config`` 237 command returns the most **recent** configuration block for the targeted channel, which 238 in this case is the third block. This is because the test network script, ``network.sh``, defined anchor 239 peers for our two organizations -- ``Org1`` and ``Org2`` -- in two separate channel update 240 transactions. As a result, we have the following configuration sequence: 241 242 * block 0: genesis block 243 * block 1: Org1 anchor peer update 244 * block 2: Org2 anchor peer update 245 246 Convert the Configuration to JSON and Trim It Down 247 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 248 249 The channel configuration block was stored in the ``channel-artifacts`` folder to keep 250 the update process separate from other artifacts. Change into the ``channel-artifacts`` 251 folder to complete the next steps: 252 253 .. code:: bash 254 cd channel-artifacts 255 256 Now we will make use of the ``configtxlator`` tool to decode this channel 257 configuration block into JSON format (which can be read and modified by humans). 258 We also must strip away all of the headers, metadata, creator signatures, and 259 so on that are irrelevant to the change we want to make. We accomplish this by 260 means of the ``jq`` tool (you will need to install the `jq tool <https://stedolan.github.io/jq/>`_ on your local machine): 261 262 .. code:: bash 263 264 configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json 265 jq .data.data[0].payload.data.config config_block.json > config.json 266 267 This command leaves us with a trimmed down JSON object -- ``config.json`` -- which 268 will serve as the baseline for our config update. 269 270 Take a moment to open this file inside your text editor of choice (or in your 271 browser). Even after you're done with this tutorial, it will be worth studying it 272 as it reveals the underlying configuration structure and the other kind of channel 273 updates that can be made. We discuss them in more detail in :doc:`config_update`. 274 275 Add the Org3 Crypto Material 276 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 278 .. note:: The steps you've taken up to this point will be nearly identical no matter 279 what kind of config update you're trying to make. We've chosen to add an 280 org with this tutorial because it's one of the most complex channel 281 configuration updates you can attempt. 282 283 We'll use the ``jq`` tool once more to append the Org3 configuration definition 284 -- ``org3.json`` -- to the channel's application groups field, and name the output 285 -- ``modified_config.json``. 286 287 .. code:: bash 288 289 jq -s '.[0] * {"channel_group":{"groups":{"Application":{"groups": {"Org3MSP":.[1]}}}}}' config.json ../organizations/peerOrganizations/org3.example.com/org3.json > modified_config.json 290 291 Now we have two JSON files of interest -- ``config.json`` and 292 ``modified_config.json``. The initial file contains only Org1 and Org2 293 material, whereas the "modified" file contains all three Orgs. At this 294 point it's simply a matter of re-encoding these two JSON files and calculating 295 the delta. 296 297 First, translate ``config.json`` back into a protobuf called ``config.pb``: 298 299 .. code:: bash 300 301 configtxlator proto_encode --input config.json --type common.Config --output config.pb 302 303 Next, encode ``modified_config.json`` to ``modified_config.pb``: 304 305 .. code:: bash 306 307 configtxlator proto_encode --input modified_config.json --type common.Config --output modified_config.pb 308 309 Now use ``configtxlator`` to calculate the delta between these two config 310 protobufs. This command will output a new protobuf binary named ``org3_update.pb``: 311 312 .. code:: bash 313 314 configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_config.pb --output org3_update.pb 315 316 This new proto -- ``org3_update.pb`` -- contains the Org3 definitions and high 317 level pointers to the Org1 and Org2 material. We are able to forgo the extensive 318 MSP material and modification policy information for Org1 and Org2 because this 319 data is already present within the channel's genesis block. As such, we only need 320 the delta between the two configurations. 321 322 Before submitting the channel update, we need to perform a few final steps. First, 323 let's decode this object into editable JSON format and call it ``org3_update.json``: 324 325 .. code:: bash 326 327 configtxlator proto_decode --input org3_update.pb --type common.ConfigUpdate --output org3_update.json 328 329 Now, we have a decoded update file -- ``org3_update.json`` -- that we need to wrap 330 in an envelope message. This step will give us back the header field that we stripped away 331 earlier. We'll name this file ``org3_update_in_envelope.json``: 332 333 .. code:: bash 334 335 echo '{"payload":{"header":{"channel_header":{"channel_id":"'channel1'", "type":2}},"data":{"config_update":'$(cat org3_update.json)'}}}' | jq . > org3_update_in_envelope.json 336 337 Using our properly formed JSON -- ``org3_update_in_envelope.json`` -- we will 338 leverage the ``configtxlator`` tool one last time and convert it into the 339 fully fledged protobuf format that Fabric requires. We'll name our final update 340 object ``org3_update_in_envelope.pb``: 341 342 .. code:: bash 343 344 configtxlator proto_encode --input org3_update_in_envelope.json --type common.Envelope --output org3_update_in_envelope.pb 345 346 Sign and Submit the Config Update 347 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 348 349 Almost done! 350 351 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. 352 353 First, let's sign this update proto as Org1. Navigate back to the ``test-network`` 354 directory: 355 356 .. code:: bash 357 cd .. 358 359 Remember that we exported the necessary environment variables to operate as the Org1 admin. 360 As a result, the following ``peer channel signconfigtx`` command will sign the update as Org1. 361 362 .. code:: bash 363 364 peer channel signconfigtx -f channel-artifacts/org3_update_in_envelope.pb 365 366 The final step is to switch the container's identity to reflect the Org2 Admin 367 user. We do this by exporting four environment variables specific to the Org2 MSP. 368 369 .. note:: Switching between organizations to sign a config transaction (or to do anything 370 else) is not reflective of a real-world Fabric operation. A single container 371 would never be mounted with an entire network's crypto material. Rather, the 372 config update would need to be securely passed out-of-band to an Org2 373 Admin for inspection and approval. 374 375 Export the Org2 environment variables: 376 377 .. code:: bash 378 379 # you can issue all of these commands at once 380 381 export CORE_PEER_TLS_ENABLED=true 382 export CORE_PEER_LOCALMSPID="Org2MSP" 383 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 384 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 385 export CORE_PEER_ADDRESS=localhost:9051 386 387 Lastly, we will issue the ``peer channel update`` command. The Org2 Admin signature 388 will be attached to this call so there is no need to manually sign the protobuf a 389 second time: 390 391 .. note:: The upcoming update call to the ordering service will undergo a series 392 of systematic signature and policy checks. As such you may find it 393 useful to stream and inspect the ordering node's logs. You can issue a 394 ``docker logs -f orderer.example.com`` command to display them. 395 396 Send the update call: 397 398 .. code:: bash 399 400 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 401 402 You should see a message similar to the following if your update has been submitted successfully: 403 404 .. code:: bash 405 406 2021-01-07 18:51:48.015 UTC [channelCmd] update -> INFO 002 Successfully submitted channel update 407 408 The successful channel update call returns a new block -- block 3 -- to all of the 409 peers on the channel. If you remember, blocks 0-2 are the initial channel 410 configurations. Block 3 serves as the most recent channel configuration with 411 Org3 now defined on the channel. 412 413 You can inspect the logs for ``peer0.org1.example.com`` by issuing the following command: 414 415 .. code:: bash 416 417 docker logs -f peer0.org1.example.com 418 419 420 Join Org3 to the Channel 421 ~~~~~~~~~~~~~~~~~~~~~~~~ 422 423 At this point, the channel configuration has been updated to include our new 424 organization -- Org3 -- meaning that peers attached to it can now join ``channel1``. 425 426 Export the following environment variables to operate as the Org3 Admin: 427 428 .. code:: bash 429 430 # you can issue all of these commands at once 431 432 export CORE_PEER_TLS_ENABLED=true 433 export CORE_PEER_LOCALMSPID="Org3MSP" 434 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 435 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 436 export CORE_PEER_ADDRESS=localhost:11051 437 438 As a result of the successful channel update, the ordering service will verify 439 that Org3 can pull the genesis block and join the channel. If Org3 had not 440 been successfully appended to the channel config, the ordering service would 441 reject this request. 442 443 .. note:: Again, you may find it useful to stream the ordering node's logs 444 to reveal the sign/verify logic and policy checks. 445 446 Use the ``peer channel fetch`` command to retrieve this block: 447 448 .. code:: bash 449 450 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 451 452 Notice, that we are passing a ``0`` to indicate that we want the first block on 453 the channel's ledger; the genesis block. If we simply passed the 454 ``peer channel fetch config`` command, then we would have received block 3 -- the 455 updated config with Org3 defined. However, we can't begin our ledger with a 456 downstream block -- we must start with block 0. 457 458 If successful, the command returned the genesis block to a file named ``channel1.block``. 459 We can now use this block to join the peer to the channel. Issue the 460 ``peer channel join`` command and pass in the genesis block to join the Org3 461 peer to the channel: 462 463 .. code:: bash 464 465 peer channel join -b channel-artifacts/channel1.block 466 467 Configuring Leader Election 468 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 470 .. note:: This section is included as a general reference for understanding 471 the leader election settings when adding organizations to a network 472 after the initial channel configuration has completed. 473 474 Newly joining peers are bootstrapped with the genesis block, which does not 475 contain information about the organization that is being added in the channel 476 configuration update. Therefore new peers are not able to utilize gossip as 477 they cannot verify blocks forwarded by other peers from their own organization 478 until they get the configuration transaction which added the organization to the 479 channel. Newly added peers must therefore have one of the following 480 configurations so that they receive blocks from the ordering service: 481 482 1. To ensure that peers always receive blocks directly from the ordering service, 483 configure the peer to be an organization leader: 484 485 :: 486 487 CORE_PEER_GOSSIP_USELEADERELECTION=false 488 CORE_PEER_GOSSIP_ORGLEADER=true 489 490 491 .. note:: This configuration is the default starting in Fabric v2.2 and must be the 492 same for all new peers added to the channel. 493 494 2. To eventually utilize dynamic leader election within the organization, 495 configure the peer to use leader election: 496 497 :: 498 499 CORE_PEER_GOSSIP_USELEADERELECTION=true 500 CORE_PEER_GOSSIP_ORGLEADER=false 501 502 503 .. note:: Because peers of the newly added organization won't initially be able to form 504 membership view, this option will be similar to the static 505 configuration, as each peer will start proclaiming itself to be a 506 leader. However, once they get updated with the configuration 507 transaction that adds the organization to the channel, there will be 508 only one active leader for the organization. Therefore, it is 509 recommended to leverage this option if you eventually want the 510 organization's peers to utilize leader election. 511 512 513 .. _upgrade-and-invoke: 514 515 Install, define, and invoke chaincode 516 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 517 518 We can confirm that Org3 is a member of ``channel1`` by installing and invoking 519 a chaincode on the channel. If the existing channel members have already committed 520 a chaincode definition to the channel, a new organization can start using the 521 chaincode by approving the chaincode definition. 522 523 .. note:: These instructions use the Fabric chaincode lifecycle introduced in 524 the v2.0 release. If you would like to use the previous lifecycle to 525 install and instantiate a chaincode, visit the v1.4 version of the 526 `Adding an org to a channel tutorial <https://hyperledger-fabric.readthedocs.io/en/release-1.4/channel_update_tutorial.html>`__. 527 528 Before we install a chaincode as Org3, we can use the ``./network.sh`` script to 529 deploy the Basic chaincode on the channel. Open a new terminal and navigate to the ``test-network`` directory. You can then use 530 use the ``test-network`` script to deploy the Basic chaincode: 531 532 .. code:: bash 533 534 cd fabric-samples/test-network 535 ./network.sh deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go/ -ccl go -c channel1 536 537 The script will install the Basic chaincode on the Org1 and Org2 peers, approve 538 the chaincode definition for Org1 and Org2, and then commit the chaincode 539 definition to the channel. Once the chaincode definition has been committed to 540 the channel, the Basic chaincode is initialized and invoked to put initial data 541 on the ledger. The commands below assume that we are still using the channel 542 ``channel1``. 543 544 After the chaincode has been to deployed we can use the following steps to use 545 invoke Basic chaincode as Org3. Copy and paste the following environment 546 variables in your terminal in order to interact with the network as the Org3 547 admin: 548 549 .. code:: bash 550 551 export PATH=${PWD}/../bin:$PATH 552 export FABRIC_CFG_PATH=$PWD/../config/ 553 export CORE_PEER_TLS_ENABLED=true 554 export CORE_PEER_LOCALMSPID="Org3MSP" 555 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 556 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 557 export CORE_PEER_ADDRESS=localhost:11051 558 559 The first step is to package the Basic chaincode: 560 561 .. code:: bash 562 563 peer lifecycle chaincode package basic.tar.gz --path ../asset-transfer-basic/chaincode-go/ --lang golang --label basic_1 564 565 This command will create a chaincode package named ``basic.tar.gz``, which we can 566 install on the Org3 peer. Modify the command accordingly if the channel is running a 567 chaincode written in Java or Node.js. Issue the following command to install the 568 chaincode package ``peer0.org3.example.com``: 569 570 .. code:: bash 571 572 peer lifecycle chaincode install basic.tar.gz 573 574 575 The next step is to approve the chaincode definition of Basic as Org3. Org3 576 needs to approve the same definition that Org1 and Org2 approved and committed 577 to the channel. In order to invoke the chaincode, Org3 needs to include the 578 package identifier in the chaincode definition. You can find the package 579 identifier by querying your peer: 580 581 .. code:: bash 582 583 peer lifecycle chaincode queryinstalled 584 585 You should see output similar to the following: 586 587 .. code:: bash 588 589 Get installed chaincodes on peer: 590 Package ID: basic_1:5443b5b557efd3faece8723883d28d6f7026c0bf12245de109b89c5c4fe64887, Label: basic_1 591 592 We are going to need the package ID in a future command, so lets go ahead and 593 save it as an environment variable. Paste the package ID returned by the 594 ``peer lifecycle chaincode queryinstalled`` command into the command below. The 595 package ID may not be the same for all users, so you need to complete this step 596 using the package ID returned from your console. 597 598 .. code:: bash 599 600 export CC_PACKAGE_ID=basic_1:5443b5b557efd3faece8723883d28d6f7026c0bf12245de109b89c5c4fe64887 601 602 Use the following command to approve a definition of the basic chaincode 603 for Org3: 604 605 .. code:: bash 606 607 # use the --package-id flag to provide the package identifier 608 # use the --init-required flag to request the ``Init`` function be invoked to initialize the chaincode 609 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 610 611 612 You can use the ``peer lifecycle chaincode querycommitted`` command to check if 613 the chaincode definition you have approved has already been committed to the 614 channel. 615 616 .. code:: bash 617 618 # use the --name flag to select the chaincode whose definition you want to query 619 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 620 621 A successful command will return information about the committed definition: 622 623 .. code:: bash 624 625 Committed chaincode definition for chaincode 'basic' on channel 'channel1': 626 Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals: [Org1MSP: true, Org2MSP: true, Org3MSP: true] 627 628 Org3 can use the basic chaincode after it approves the chaincode definition 629 that was committed to the channel. The chaincode definition uses the default endorsement 630 policy, which requires a majority of organizations on the channel endorse a transaction. 631 This implies that if an organization is added to or removed from the channel, the 632 endorsement policy will be updated automatically. We previously needed endorsements 633 from Org1 and Org2 (2 out of 2). Now we need endorsements from two organizations 634 out of Org1, Org2, and Org3 (2 out of 3). 635 636 Populate the ledger with some sample assets. We'll get endorsements from the Org2 peer 637 and the new Org3 peer so that the endorsement policy is satisfied. 638 639 .. code:: bash 640 641 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":[]}' 642 643 You can query the chaincode to ensure that the Org3 peer committed the data. 644 645 .. code:: bash 646 647 peer chaincode query -C channel1 -n basic -c '{"Args":["GetAllAssets"]}' 648 649 You should see the initial list of assets that were added to the ledger as a 650 response. 651 652 653 Conclusion 654 ~~~~~~~~~~ 655 656 The channel configuration update process is indeed quite involved, but there is a 657 logical method to the various steps. The endgame is to form a delta transaction object 658 represented in protobuf binary format and then acquire the requisite number of admin 659 signatures such that the channel configuration update transaction fulfills the channel's 660 modification policy. 661 662 The ``configtxlator`` and ``jq`` tools, along with the ``peer channel`` 663 commands, provide us with the functionality to accomplish this task. 664 665 Updating the Channel Config to include an Org3 Anchor Peer (Optional) 666 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 667 668 The Org3 peers were able to establish gossip connection to the Org1 and Org2 669 peers since Org1 and Org2 had anchor peers defined in the channel configuration. 670 Likewise newly added organizations like Org3 should also define their anchor peers 671 in the channel configuration so that any new peers from other organizations can 672 directly discover an Org3 peer. In this section, we will make a channel 673 configuration update to define an Org3 anchor peer. The process will be similar 674 to the previous configuration update, therefore we'll go faster this time. 675 676 As before, we will fetch the latest channel configuration to get started. 677 Fetch the most recent config block for the channel, using the ``peer channel fetch`` command. 678 679 .. code:: bash 680 681 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 682 683 After fetching the config block we will want to convert it into JSON format. To do 684 this we will use the configtxlator tool, as done previously when adding Org3 to the 685 channel. First, change into the ``channel-artifacts`` folder: 686 687 .. code:: bash 688 cd channel-artifacts 689 690 When converting it we need to remove all the headers, metadata, and signatures 691 that are not required to update Org3 to include an anchor peer by using the ``jq`` 692 tool. This information will be reincorporated later before we proceed to update the 693 channel configuration. 694 695 .. code:: bash 696 697 configtxlator proto_decode --input config_block.pb --type common.Block --output config_block.json 698 jq .data.data[0].payload.data.config config_block.json > config.json 699 700 The ``config.json`` is the now trimmed JSON representing the latest channel configuration 701 that we will update. 702 703 Using the ``jq`` tool again, we will update the configuration JSON with the Org3 anchor peer we 704 want to add. 705 706 .. code:: bash 707 708 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 709 710 We now have two JSON files, one for the current channel configuration, 711 ``config.json``, and one for the desired channel configuration ``modified_anchor_config.json``. 712 Next we convert each of these back into protobuf format and calculate the delta between the two. 713 714 Translate ``config.json`` back into protobuf format as ``config.pb`` 715 716 .. code:: bash 717 718 configtxlator proto_encode --input config.json --type common.Config --output config.pb 719 720 Translate the ``modified_anchor_config.json`` into protobuf format as ``modified_anchor_config.pb`` 721 722 .. code:: bash 723 724 configtxlator proto_encode --input modified_anchor_config.json --type common.Config --output modified_anchor_config.pb 725 726 Calculate the delta between the two protobuf formatted configurations. 727 728 .. code:: bash 729 730 configtxlator compute_update --channel_id channel1 --original config.pb --updated modified_anchor_config.pb --output anchor_update.pb 731 732 Now that we have the desired update to the channel we must wrap it in an envelope 733 message so that it can be properly read. To do this we must first convert the protobuf 734 back into a JSON that can be wrapped. 735 736 We will use the ``configtxlator`` command again to convert ``anchor_update.pb`` into ``anchor_update.json`` 737 738 .. code:: bash 739 740 configtxlator proto_decode --input anchor_update.pb --type common.ConfigUpdate --output anchor_update.json 741 742 Next we will wrap the update in an envelope message, restoring the previously 743 stripped away header, outputting it to ``anchor_update_in_envelope.json`` 744 745 .. code:: bash 746 747 echo '{"payload":{"header":{"channel_header":{"channel_id":"channel1", "type":2}},"data":{"config_update":'$(cat anchor_update.json)'}}}' | jq . > anchor_update_in_envelope.json 748 749 Now that we have reincorporated the envelope we need to convert it 750 to a protobuf so it can be properly signed and submitted to the orderer for the update. 751 752 .. code:: bash 753 754 configtxlator proto_encode --input anchor_update_in_envelope.json --type common.Envelope --output anchor_update_in_envelope.pb 755 756 Now that the update has been properly formatted it is time to sign off and submit it. 757 758 Navigate back to the ``test-network`` directory: 759 760 .. code:: bash 761 cd .. 762 763 764 Since this is only an update to Org3 we only need to have Org3 sign off on the update. Run the following 765 commands to make sure that we are operating as the Org3 admin: 766 767 .. code:: bash 768 769 # you can issue all of these commands at once 770 771 export CORE_PEER_LOCALMSPID="Org3MSP" 772 export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org3.example.com/peers/peer0.org3.example.com/tls/ca.crt 773 export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org3.example.com/users/Admin@org3.example.com/msp 774 export CORE_PEER_ADDRESS=localhost:11051 775 776 We can now just use the ``peer channel update`` command to sign the update as the 777 Org3 admin before submitting it to the orderer. 778 779 .. code:: bash 780 781 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 782 783 The orderer receives the config update request and cuts a block with the updated configuration. 784 As peers receive the block, they will process the configuration updates. 785 786 Inspect the logs for one of the peers. While processing the configuration transaction from the new block, 787 you will see gossip re-establish connections using the new anchor peer for Org3. This is proof 788 that the configuration update has been successfully applied! 789 790 .. code:: bash 791 792 docker logs -f peer0.org1.example.com 793 794 .. code:: bash 795 796 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}] 797 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}] 798 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}] 799 800 Congratulations, you have now made two configuration updates --- one to add Org3 to the channel, 801 and a second to define an anchor peer for Org3. 802 803 .. Licensed under Creative Commons Attribution 4.0 International License 804 https://creativecommons.org/licenses/by/4.0/