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