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