github.com/yous1230/fabric@v2.0.0-beta.0.20191224111736-74345bee6ac2+incompatible/docs/source/build_network.rst (about) 1 Building Your First Network 2 =========================== 3 4 .. note:: These instructions have been verified to work against the 5 latest stable Docker images and the pre-compiled 6 setup utilities within the supplied tar file. If you run 7 these commands with images or tools from the current master 8 branch, it is possible that you will see configuration and panic 9 errors. 10 11 The build your first network (BYFN) scenario provisions a sample Hyperledger 12 Fabric network consisting of two organizations, each maintaining two peer 13 nodes. It also will deploy a Raft ordering service by default. 14 15 Install prerequisites 16 --------------------- 17 18 Before we begin, if you haven't already done so, you may wish to check that 19 you have all the :doc:`prereqs` installed on the platform(s) on which you'll be 20 developing blockchain applications and/or operating Hyperledger Fabric. 21 22 You will also need to :doc:`install`. You will notice that there are a number of 23 samples included in the ``fabric-samples`` repository. We will be using the 24 ``first-network`` sample. Let's open that sub-directory now. 25 26 .. code:: bash 27 28 cd fabric-samples/first-network 29 30 .. note:: The supplied commands in this documentation **MUST** be run from your 31 ``first-network`` sub-directory of the ``fabric-samples`` repository 32 clone. If you elect to run the commands from a different location, 33 the various provided scripts will be unable to find the binaries. 34 35 Want to run it now? 36 ------------------- 37 38 We provide a fully annotated script --- ``byfn.sh`` --- that leverages these Docker 39 images to quickly bootstrap a Hyperledger Fabric network that by default is 40 comprised of four peers representing two different organizations, and a Raft ordering 41 service. It will also launch a container to run a scripted execution that will join 42 peers to a channel, deploy a chaincode and drive execution of transactions 43 against the deployed chaincode. 44 45 Here's the help text for the ``byfn.sh`` script: 46 47 .. code:: bash 48 49 Usage: 50 byfn.sh <mode> [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>] [-l <language>] [-o <consensus-type>] [-i <imagetag>] [-v]" 51 <mode> - one of 'up', 'down', 'restart', 'generate' or 'upgrade'" 52 - 'up' - bring up the network with docker-compose up" 53 - 'down' - clear the network with docker-compose down" 54 - 'restart' - restart the network" 55 - 'generate' - generate required certificates and genesis block" 56 - 'upgrade' - upgrade the network from version 1.3.x to 1.4.0" 57 -c <channel name> - channel name to use (defaults to \"mychannel\")" 58 -t <timeout> - CLI timeout duration in seconds (defaults to 10)" 59 -d <delay> - delay duration in seconds (defaults to 3)" 60 -f <docker-compose-file> - specify which docker-compose file use (defaults to docker-compose-cli.yaml)" 61 -s <dbtype> - the database backend to use: goleveldb (default) or couchdb" 62 -l <language> - the chaincode language: golang (default), javascript, or java" 63 -a - launch certificate authorities (no certificate authorities are launched by default) 64 -n - do not deploy chaincode (abstore chaincode is deployed by default) 65 -i <imagetag> - the tag to be used to launch the network (defaults to \"latest\")" 66 -v - verbose mode" 67 byfn.sh -h (print this message)" 68 69 Typically, one would first generate the required certificates and 70 genesis block, then bring up the network. e.g.:" 71 72 byfn.sh generate -c mychannel" 73 byfn.sh up -c mychannel -s couchdb" 74 byfn.sh up -c mychannel -s couchdb -i 1.4.0" 75 byfn.sh up -l javascript" 76 byfn.sh down -c mychannel" 77 byfn.sh upgrade -c mychannel" 78 79 Taking all defaults:" 80 byfn.sh generate" 81 byfn.sh up" 82 byfn.sh down" 83 84 If you choose not to supply a flag, the script will use default values. 85 86 Generate Network Artifacts 87 ^^^^^^^^^^^^^^^^^^^^^^^^^^ 88 89 Ready to give it a go? Okay then! Execute the following command: 90 91 .. code:: bash 92 93 ./byfn.sh generate 94 95 You will see a brief description as to what will occur, along with a yes/no command line 96 prompt. Respond with a ``y`` or hit the return key to execute the described action. 97 98 .. code:: bash 99 100 Generating certs and genesis block for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds 101 Continue? [Y/n] y 102 proceeding ... 103 /Users/xxx/dev/fabric-samples/bin/cryptogen 104 105 ########################################################## 106 ##### Generate certificates using cryptogen tool ######### 107 ########################################################## 108 org1.example.com 109 2017-06-12 21:01:37.334 EDT [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP. 110 ... 111 112 /Users/xxx/dev/fabric-samples/bin/configtxgen 113 ########################################################## 114 ######### Generating Orderer Genesis block ############## 115 ########################################################## 116 2017-06-12 21:01:37.558 EDT [common/configtx/tool] main -> INFO 001 Loading configuration 117 2017-06-12 21:01:37.562 EDT [msp] getMspConfig -> INFO 002 intermediate certs folder not found at [/Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts]. Skipping.: [stat /Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts: no such file or directory] 118 ... 119 2017-06-12 21:01:37.588 EDT [common/configtx/tool] doOutputBlock -> INFO 00b Generating genesis block 120 2017-06-12 21:01:37.590 EDT [common/configtx/tool] doOutputBlock -> INFO 00c Writing genesis block 121 122 ################################################################# 123 ### Generating channel configuration transaction 'channel.tx' ### 124 ################################################################# 125 2017-06-12 21:01:37.634 EDT [common/configtx/tool] main -> INFO 001 Loading configuration 126 2017-06-12 21:01:37.644 EDT [common/configtx/tool] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx 127 2017-06-12 21:01:37.645 EDT [common/configtx/tool] doOutputChannelCreateTx -> INFO 003 Writing new channel tx 128 129 ################################################################# 130 ####### Generating anchor peer update for Org1MSP ########## 131 ################################################################# 132 2017-06-12 21:01:37.674 EDT [common/configtx/tool] main -> INFO 001 Loading configuration 133 2017-06-12 21:01:37.678 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update 134 2017-06-12 21:01:37.679 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update 135 136 ################################################################# 137 ####### Generating anchor peer update for Org2MSP ########## 138 ################################################################# 139 2017-06-12 21:01:37.700 EDT [common/configtx/tool] main -> INFO 001 Loading configuration 140 2017-06-12 21:01:37.704 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update 141 2017-06-12 21:01:37.704 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update 142 143 This first step generates all of the certificates and keys for our various 144 network entities, the ``genesis block`` used to bootstrap the ordering service, 145 and a collection of configuration transactions required to configure a 146 :ref:`Channel`. 147 148 Bring Up the Network 149 ^^^^^^^^^^^^^^^^^^^^ 150 151 Next, you can bring the network up with one of the following commands: 152 153 .. code:: bash 154 155 ./byfn.sh up 156 157 The above command will compile Golang chaincode images and spin up the corresponding 158 containers. Go is the default chaincode language, however there is also support 159 for `Node.js <https://fabric-shim.github.io/>`_ and `Java <https://hyperledger.github.io/fabric-chaincode-java/>`_ 160 chaincode. If you'd like to run through this tutorial with node chaincode, pass 161 the following command instead: 162 163 .. code:: bash 164 165 # we use the -l flag to specify the chaincode language 166 # forgoing the -l flag will default to Golang 167 168 ./byfn.sh up -l javascript 169 170 .. note:: For more information on the Node.js shim, please refer to its 171 `documentation <https://fabric-shim.github.io/ChaincodeInterface.html>`_. 172 173 .. note:: For more information on the Java shim, please refer to its 174 `documentation <https://hyperledger.github.io/fabric-chaincode-java/master/api/org/hyperledger/fabric/shim/Chaincode.html>`_. 175 176 Тo make the sample run with Java chaincode, you have to specify ``-l java`` as follows: 177 178 .. code:: bash 179 180 ./byfn.sh up -l java 181 182 .. note:: Do not run both of these commands. Only one language can be tried unless 183 you bring down and recreate the network between. 184 185 You will be prompted as to whether you wish to continue or abort. 186 Respond with a ``y`` or hit the return key: 187 188 .. code:: bash 189 190 Starting for channel 'mychannel' with CLI timeout of '10' seconds and CLI delay of '3' seconds 191 Continue? [Y/n] 192 proceeding ... 193 Creating network "net_byfn" with the default driver 194 Creating peer0.org1.example.com 195 Creating peer1.org1.example.com 196 Creating peer0.org2.example.com 197 Creating orderer.example.com 198 Creating peer1.org2.example.com 199 Creating cli 200 201 202 ____ _____ _ ____ _____ 203 / ___| |_ _| / \ | _ \ |_ _| 204 \___ \ | | / _ \ | |_) | | | 205 ___) | | | / ___ \ | _ < | | 206 |____/ |_| /_/ \_\ |_| \_\ |_| 207 208 Channel name : mychannel 209 Creating channel... 210 211 The logs will continue from there. This will launch all of the containers, and 212 then drive a complete end-to-end application scenario. Upon successful 213 completion, it should report the following in your terminal window: 214 215 .. code:: bash 216 217 Query Result: 90 218 2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting..... 219 ===================== Query successful on peer1.org2 on channel 'mychannel' ===================== 220 221 ===================== All GOOD, BYFN execution completed ===================== 222 223 224 _____ _ _ ____ 225 | ____| | \ | | | _ \ 226 | _| | \| | | | | | 227 | |___ | |\ | | |_| | 228 |_____| |_| \_| |____/ 229 230 You can scroll through these logs to see the various transactions. If you don't 231 get this result, then jump down to the :ref:`Troubleshoot` section and let's see 232 whether we can help you discover what went wrong. 233 234 Bring Down the Network 235 ^^^^^^^^^^^^^^^^^^^^^^ 236 237 Finally, let's bring it all down so we can explore the network setup one step 238 at a time. The following will kill your containers, remove the crypto material 239 and four artifacts, and delete the chaincode images from your Docker Registry: 240 241 .. code:: bash 242 243 ./byfn.sh down 244 245 Once again, you will be prompted to continue, respond with a ``y`` or hit the return key: 246 247 .. code:: bash 248 249 Stopping with channel 'mychannel' and CLI timeout of '10' 250 Continue? [Y/n] y 251 proceeding ... 252 WARNING: The CHANNEL_NAME variable is not set. Defaulting to a blank string. 253 WARNING: The TIMEOUT variable is not set. Defaulting to a blank string. 254 Removing network net_byfn 255 468aaa6201ed 256 ... 257 Untagged: dev-peer1.org2.example.com-mycc-1.0:latest 258 Deleted: sha256:ed3230614e64e1c83e510c0c282e982d2b06d148b1c498bbdcc429e2b2531e91 259 ... 260 261 If you'd like to learn more about the underlying tooling and bootstrap mechanics, 262 continue reading. In these next sections we'll walk through the various steps 263 and requirements to build a fully-functional Hyperledger Fabric network. 264 265 .. note:: The manual steps outlined below assume that the ``FABRIC_LOGGING_SPEC`` in 266 the ``cli`` container is set to ``DEBUG``. You can set this by modifying 267 the ``docker-compose-cli.yaml`` file in the ``first-network`` directory. 268 e.g. 269 270 .. code:: 271 272 cli: 273 container_name: cli 274 image: hyperledger/fabric-tools:$IMAGE_TAG 275 tty: true 276 stdin_open: true 277 environment: 278 - GOPATH=/opt/gopath 279 - CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock 280 - FABRIC_LOGGING_SPEC=DEBUG 281 #- FABRIC_LOGGING_SPEC=INFO 282 283 Crypto Generator 284 ---------------- 285 286 We will use the ``cryptogen`` tool to generate the cryptographic material 287 (x509 certs and signing keys) for our various network entities. These certificates are 288 representative of identities, and they allow for sign/verify authentication to 289 take place as our entities communicate and transact. 290 291 How does it work? 292 ^^^^^^^^^^^^^^^^^ 293 294 Cryptogen consumes a file --- ``crypto-config.yaml`` --- that contains the network 295 topology and allows us to generate a set of certificates and keys for both the 296 Organizations and the components that belong to those Organizations. Each 297 Organization is provisioned a unique root certificate (``ca-cert``) that binds 298 specific components (peers and orderers) to that Org. By assigning each 299 Organization a unique CA certificate, we are mimicking a typical network where 300 a participating :ref:`Member` would use its own Certificate Authority. 301 Transactions and communications within Hyperledger Fabric are signed by an 302 entity's private key (``keystore``), and then verified by means of a public 303 key (``signcerts``). 304 305 You will notice a ``count`` variable within this file. We use this to specify 306 the number of peers per Organization; in our case there are two peers per Org. 307 We won't delve into the minutiae of `x.509 certificates and public key 308 infrastructure <https://en.wikipedia.org/wiki/Public_key_infrastructure>`_ 309 right now. If you're interested, you can peruse these topics on your own time. 310 311 After we run the ``cryptogen`` tool, the generated certificates and keys will be 312 saved to a folder titled ``crypto-config``. Note that the ``crypto-config.yaml`` 313 file lists five orderers as being tied to the orderer organization. While the 314 ``cryptogen`` tool will create certificates for all five of these orderers. These orderers 315 will be used in a etcdraft ordering service implementation and be used to create the 316 system channel and ``mychannel``. 317 318 Configuration Transaction Generator 319 ----------------------------------- 320 321 The ``configtxgen`` tool is used to create four configuration artifacts: 322 323 * orderer ``genesis block``, 324 * channel ``configuration transaction``, 325 * and two ``anchor peer transactions`` - one for each Peer Org. 326 327 Please see :doc:`commands/configtxgen` for a complete description of this tool's functionality. 328 329 The orderer block is the :ref:`Genesis-Block` for the ordering service, and the 330 channel configuration transaction file is broadcast to the orderer at :ref:`Channel` creation 331 time. The anchor peer transactions, as the name might suggest, specify each 332 Org's :ref:`Anchor-Peer` on this channel. 333 334 How does it work? 335 ^^^^^^^^^^^^^^^^^ 336 337 Configtxgen consumes a file - ``configtx.yaml`` - that contains the definitions 338 for the sample network. There are three members - one Orderer Org (``OrdererOrg``) 339 and two Peer Orgs (``Org1`` & ``Org2``) each managing and maintaining two peer nodes. 340 This file also specifies a consortium - ``SampleConsortium`` - consisting of our 341 two Peer Orgs. Pay specific attention to the "Profiles" section at the bottom of 342 this file. You will notice that we have several unique profiles. A few are worth 343 noting: 344 345 * ``SampleMultiNodeEtcdRaft``: generates the genesis block for a Raft ordering 346 service. Only used if you issue the ``-o`` flag and specify ``etcdraft``. 347 348 * ``TwoOrgsChannel``: generates the genesis block for our channel, ``mychannel``. 349 350 These headers are important, as we will pass them in as arguments when we create 351 our artifacts. 352 353 .. note:: Notice that our ``SampleConsortium`` is defined in 354 the system-level profile and then referenced by 355 our channel-level profile. Channels exist within 356 the purview of a consortium, and all consortia 357 must be defined in the scope of the network at 358 large. 359 360 This file also contains two additional specifications that are worth 361 noting. Firstly, we specify the anchor peers for each Peer Org 362 (``peer0.org1.example.com`` & ``peer0.org2.example.com``). Secondly, we point to 363 the location of the MSP directory for each member, in turn allowing us to store the 364 root certificates for each Org in the orderer genesis block. This is a critical 365 concept. Now any network entity communicating with the ordering service can have 366 its digital signature verified. 367 368 Run the tools 369 ------------- 370 371 You can manually generate the certificates/keys and the various configuration 372 artifacts using the ``configtxgen`` and ``cryptogen`` commands. Alternately, 373 you could try to adapt the byfn.sh script to accomplish your objectives. 374 375 Manually generate the artifacts 376 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 377 378 You can refer to the ``generateCerts`` function in the byfn.sh script for the 379 commands necessary to generate the certificates that will be used for your 380 network configuration as defined in the ``crypto-config.yaml`` file. However, 381 for the sake of convenience, we will also provide a reference here. 382 383 First let's run the ``cryptogen`` tool. Our binary is in the ``bin`` 384 directory, so we need to provide the relative path to where the tool resides. 385 386 .. code:: bash 387 388 ../bin/cryptogen generate --config=./crypto-config.yaml 389 390 You should see the following in your terminal: 391 392 .. code:: bash 393 394 org1.example.com 395 org2.example.com 396 397 The certs and keys (i.e. the MSP material) will be output into a directory - ``crypto-config`` - 398 at the root of the ``first-network`` directory. 399 400 Next, we need to tell the ``configtxgen`` tool where to look for the 401 ``configtx.yaml`` file that it needs to ingest. We will tell it look in our 402 present working directory: 403 404 .. code:: bash 405 406 export FABRIC_CFG_PATH=$PWD 407 408 Then, we'll invoke the ``configtxgen`` tool to create the orderer genesis block: 409 410 .. code:: bash 411 412 ../bin/configtxgen -profile SampleMultiNodeEtcdRaft -channelID byfn-sys-channel -outputBlock ./channel-artifacts/genesis.block 413 414 .. note:: The orderer genesis block and the subsequent artifacts we are about to create 415 will be output into the ``channel-artifacts`` directory at the root of this 416 project. The `channelID` in the above command is the name of the system channel. 417 418 .. _createchanneltx: 419 420 Create a Channel Configuration Transaction 421 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 422 423 Next, we need to create the channel transaction artifact. Be sure to replace ``$CHANNEL_NAME`` or 424 set ``CHANNEL_NAME`` as an environment variable that can be used throughout these instructions: 425 426 .. code:: bash 427 428 # The channel.tx artifact contains the definitions for our sample channel 429 430 export CHANNEL_NAME=mychannel && ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME 431 432 Note that the ``TwoOrgsChannel`` profile will use the ordering service 433 configuration you specified when creating the genesis block for the network. 434 435 You should see an output similar to the following in your terminal: 436 437 .. code:: bash 438 439 2017-10-26 19:24:05.324 EDT [common/tools/configtxgen] main -> INFO 001 Loading configuration 440 2017-10-26 19:24:05.329 EDT [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx 441 2017-10-26 19:24:05.329 EDT [common/tools/configtxgen] doOutputChannelCreateTx -> INFO 003 Writing new channel tx 442 443 Next, we will define the anchor peer for Org1 on the channel that we are 444 constructing. Again, be sure to replace ``$CHANNEL_NAME`` or set the environment 445 variable for the following commands. The terminal output will mimic that of the 446 channel transaction artifact: 447 448 .. code:: bash 449 450 ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP 451 452 Now, we will define the anchor peer for Org2 on the same channel: 453 454 .. code:: bash 455 456 ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP 457 458 Start the network 459 ----------------- 460 461 .. note:: If you ran the ``byfn.sh`` example above previously, be sure that you 462 have brought down the test network before you proceed (see 463 `Bring Down the Network`_). 464 465 We will leverage a script to spin up our network. The 466 docker-compose file references the images that we have previously downloaded, 467 and bootstraps the orderer with our previously generated ``genesis.block``. 468 469 We want to go through the commands manually in order to expose the 470 syntax and functionality of each call. 471 472 First let's start our network: 473 474 .. code:: bash 475 476 docker-compose -f docker-compose-cli.yaml up -d 477 478 If you want to see the realtime logs for your network, then do not supply the ``-d`` flag. 479 If you let the logs stream, then you will need to open a second terminal to execute the CLI calls. 480 481 .. _peerenvvars: 482 483 Create & Join Channel 484 ^^^^^^^^^^^^^^^^^^^^^ 485 486 Recall that we created the channel configuration transaction using the 487 ``configtxgen`` tool in the :ref:`createchanneltx` section, above. You can 488 repeat that process to create additional channel configuration transactions, 489 using the same or different profiles in the ``configtx.yaml`` that you pass 490 to the ``configtxgen`` tool. Then you can repeat the process defined in this 491 section to establish those other channels in your network. 492 493 We will enter the CLI container using the ``docker exec`` command: 494 495 .. code:: bash 496 497 docker exec -it cli bash 498 499 If successful you should see the following: 500 501 .. code:: bash 502 503 root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer# 504 505 For the following CLI commands against ``peer0.org1.example.com`` to work, we need 506 to preface our commands with the four environment variables given below. These 507 variables for ``peer0.org1.example.com`` are baked into the CLI container, 508 therefore we can operate without passing them. **HOWEVER**, if you want to send 509 calls to other peers or the orderer, keep the CLI container defaults targeting 510 ``peer0.org1.example.com``, but override the environment variables as seen in the 511 example below when you make any CLI calls: 512 513 .. code:: bash 514 515 # Environment variables for PEER0 516 517 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 518 CORE_PEER_ADDRESS=peer0.org1.example.com:7051 519 CORE_PEER_LOCALMSPID="Org1MSP" 520 CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 521 522 Next, we are going to pass in the generated channel configuration transaction 523 artifact that we created in the :ref:`createchanneltx` section (we called 524 it ``channel.tx``) to the orderer as part of the create channel request. 525 526 We specify our channel name with the ``-c`` flag and our channel configuration 527 transaction with the ``-f`` flag. In this case it is ``channel.tx``, however 528 you can mount your own configuration transaction with a different name. Once again 529 we will set the ``CHANNEL_NAME`` environment variable within our CLI container so that 530 we don't have to explicitly pass this argument. Channel names must be all lower 531 case, less than 250 characters long and match the regular expression 532 ``[a-z][a-z0-9.-]*``. 533 534 .. code:: bash 535 536 export CHANNEL_NAME=mychannel 537 538 # the channel.tx file is mounted in the channel-artifacts directory within your CLI container 539 # as a result, we pass the full path for the file 540 # we also pass the path for the orderer ca-cert in order to verify the TLS handshake 541 # be sure to export or replace the $CHANNEL_NAME variable appropriately 542 543 peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 544 545 .. note:: Notice the ``--cafile`` that we pass as part of this command. It is 546 the local path to the orderer's root cert, allowing us to verify the 547 TLS handshake. 548 549 This command returns a genesis block - ``<CHANNEL_NAME.block>`` - which we will use to join the channel. 550 It contains the configuration information specified in ``channel.tx`` If you have not 551 made any modifications to the default channel name, then the command will return you a 552 proto titled ``mychannel.block``. 553 554 .. note:: You will remain in the CLI container for the remainder of 555 these manual commands. You must also remember to preface all commands 556 with the corresponding environment variables when targeting a peer other than 557 ``peer0.org1.example.com``. 558 559 Now let's join ``peer0.org1.example.com`` to the channel. 560 561 .. code:: bash 562 563 # By default, this joins ``peer0.org1.example.com`` only 564 # the <CHANNEL_NAME.block> was returned by the previous command 565 # if you have not modified the channel name, you will join with mychannel.block 566 # if you have created a different channel name, then pass in the appropriately named block 567 568 peer channel join -b mychannel.block 569 570 You can make other peers join the channel as necessary by making appropriate 571 changes in the four environment variables we used in the :ref:`peerenvvars` 572 section, above. 573 574 Rather than join every peer, we will simply join ``peer0.org2.example.com`` so that 575 we can properly update the anchor peer definitions in our channel. Since we are 576 overriding the default environment variables baked into the CLI container, this full 577 command will be the following: 578 579 .. code:: bash 580 581 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel join -b mychannel.block 582 583 Alternatively, you could choose to set these environment variables individually 584 rather than passing in the entire string. Once they've been set, you simply need 585 to issue the ``peer channel join`` command again and the CLI container will act 586 on behalf of ``peer0.org2.example.com``. 587 588 Update the anchor peers 589 ^^^^^^^^^^^^^^^^^^^^^^^ 590 591 The following commands are channel updates and they will propagate to the definition 592 of the channel. In essence, we adding additional configuration information on top 593 of the channel's genesis block. Note that we are not modifying the genesis block, but 594 simply adding deltas into the chain that will define the anchor peers. 595 596 Update the channel definition to define the anchor peer for Org1 as ``peer0.org1.example.com``: 597 598 .. code:: bash 599 600 peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org1MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 601 602 Now update the channel definition to define the anchor peer for Org2 as ``peer0.org2.example.com``. 603 Identically to the ``peer channel join`` command for the Org2 peer, we will need to 604 preface this call with the appropriate environment variables. 605 606 .. code:: bash 607 608 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer0.org2.example.com:9051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt peer channel update -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/Org2MSPanchors.tx --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 609 610 .. _install-define-chaincode: 611 612 Install and define a chaincode 613 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 614 615 .. note:: We will utilize a simple existing chaincode. To learn how to write 616 your own chaincode, see the :doc:`chaincode4ade` tutorial. 617 618 .. note:: These instructions use the Fabric chaincode lifecycle introduced in 619 the v2.0 release. If you would like to use the previous lifecycle to 620 install and instantiate a chaincode, visit the v1.4 version of the 621 `Building your first network tutorial <https://hyperledger-fabric.readthedocs.io/en/release-1.4/build_network.html>`__. 622 623 Applications interact with the blockchain ledger through ``chaincode``. 624 Therefore we need to install a chaincode on every peer that will execute and 625 endorse our transactions. However, before we can interact with our chaincode, 626 the members of the channel need to agree on a chaincode definition that 627 establishes chaincode governance. 628 629 We need to package the chaincode before it can be installed on our peers. For 630 each package you create, you need to provide a chaincode package label as a 631 description of the chaincode. Use the following commands to package a sample 632 Go, Node.js or Java chaincode. 633 634 **Golang** 635 636 .. code:: bash 637 638 # this packages a Golang chaincode. 639 # make note of the --lang flag to indicate "golang" chaincode 640 # for go chaincode --path takes the relative path from $GOPATH/src 641 # The --label flag is used to create the package label 642 peer lifecycle chaincode package mycc.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/abstore/go/ --lang golang --label mycc_1 643 644 **Node.js** 645 646 .. code:: bash 647 648 # this packages a Node.js chaincode 649 # make note of the --lang flag to indicate "node" chaincode 650 # for node chaincode --path takes the absolute path to the node.js chaincode 651 # The --label flag is used to create the package label 652 peer lifecycle chaincode package mycc.tar.gz --path /opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/abstore/node/ --lang node --label mycc_1 653 654 **Java** 655 656 .. code:: bash 657 658 # this packages a java chaincode 659 # make note of the --lang flag to indicate "java" chaincode 660 # for java chaincode --path takes the absolute path to the java chaincode 661 # The --label flag is used to create the package label 662 peer lifecycle chaincode package mycc.tar.gz --path /opt/gopath/src/github.com/hyperledger/fabric-samples/chaincode/abstore/java/ --lang java --label mycc_1 663 664 Each of the above commands will create a chaincode package named ``mycc.tar.gz``, 665 which we can use to install the chaincode on our peers. Issue the following 666 command to install the package on peer0 of Org1. 667 668 .. code:: bash 669 670 # this command installs a chaincode package on your peer 671 peer lifecycle chaincode install mycc.tar.gz 672 673 A successful install command will return a chaincode package identifier. You 674 should see output similar to the following: 675 676 .. code:: bash 677 678 2019-03-13 13:48:53.691 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nEmycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173" > 679 2019-03-13 13:48:53.691 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 680 681 You can also find the chaincode package identifier by querying your peer for 682 information about the packages you have installed. 683 684 .. code:: bash 685 686 # this returns the details of the chaincode packages installed on your peers 687 peer lifecycle chaincode queryinstalled 688 689 The command above will return the same package identifier as the install command. 690 You should see output similar to the following: 691 692 .. code:: bash 693 694 Get installed chaincodes on peer: 695 Package ID: mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173, Label: mycc_1 696 697 We are going to need the package ID for future commands, so let's go ahead and 698 save it as an environment variable. Paste the package ID returned by the 699 `peer lifecycle chaincode queryinstalled` command into the command below. The 700 package ID may not be the same for all users, so you need to complete this step 701 using the package ID returned from your console. 702 703 .. code:: bash 704 705 # Save the package ID as an environment variable. 706 707 CC_PACKAGE_ID=mycc_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 708 709 The endorsement policy of ``mycc`` will be set to require endorsements from a 710 peer in both Org1 and Org2. Therefore, we also need to install the chaincode on 711 a peer in Org2. 712 713 Modify the following four environment variables to issue the install command 714 as Org2: 715 716 .. code:: bash 717 718 # Environment variables for PEER0 in Org2 719 720 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 721 CORE_PEER_ADDRESS=peer0.org2.example.com:9051 722 CORE_PEER_LOCALMSPID="Org2MSP" 723 CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 724 725 Now install the chaincode package onto peer0 of Org2. The following command 726 will install the chaincode and return same identifier as the install command we 727 issued as Org1. 728 729 .. code:: bash 730 731 # this installs a chaincode package on your peer 732 peer lifecycle chaincode install mycc.tar.gz 733 734 After you install the package, you need to approve a chaincode definition 735 for your organization. The chaincode definition includes the important 736 parameters of chaincode governance, including the chaincode name and version. 737 The definition also includes the package identifier used to associate the 738 chaincode package installed on your peers with a chaincode definition approved 739 by your organization. 740 741 Because we set the environment variables to operate as Org2, we can use the 742 following command to approve a definition of the ``mycc`` chaincode for 743 Org2. The approval is distributed to peers within each organization, so 744 the command does not need to target every peer within an organization. 745 746 .. code:: bash 747 748 # this approves a chaincode definition for your org 749 # make note of the --package-id flag that provides the package ID 750 # use the --init-required flag to request the ``Init`` function be invoked to initialize the chaincode 751 peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 752 753 We could have provided a ``--signature-policy`` or ``--channel-config-policy`` 754 argument to the command above to set the chaincode endorsement policy. The 755 endorsement policy specifies how many peers belonging to different channel 756 members need to validate a transaction against a given chaincode. Because we did 757 not set a policy, the definition of ``mycc`` will use the default endorsement 758 policy, which requires that a transaction be endorsed by a majority of channel 759 members present when the transaction is submitted. This implies that if new 760 organizations are added to or removed from the channel, the endorsement policy 761 is updated automatically to require more or fewer endorsements. In this tutorial, 762 the default policy will require an endorsement from a peer belonging to Org1 763 **AND** Org2 (i.e. two endorsements). See the :doc:`endorsement-policies` 764 documentation for more details on policy implementation. 765 766 All organizations need to agree on the definition before they can use the 767 chaincode. Modify the following four environment variables to operate as Org1: 768 769 .. code:: bash 770 771 # Environment variables for PEER0 772 773 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp 774 CORE_PEER_ADDRESS=peer0.org1.example.com:7051 775 CORE_PEER_LOCALMSPID="Org1MSP" 776 CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt 777 778 You can now approve a definition for the ``mycc`` chaincode as Org1. Chaincode is 779 approved at the organization level. You can issue the command once even if you 780 have multiple peers. 781 782 .. code:: bash 783 784 # this defines a chaincode for your org 785 # make note of the --package-id flag that provides the package ID 786 # use the --init-required flag to request the Init function be invoked to initialize the chaincode 787 peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 788 789 Once a sufficient number of channel members have approved a chaincode definition, 790 one member can commit the definition to the channel. By default a majority of 791 channel members need to approve a definition before it can be committed. It is 792 possible to check whether the chaincode definition is ready to be committed and 793 view the current approvals by organization by issuing the following query: 794 795 .. code:: bash 796 797 # the flags used for this command are identical to those used for approveformyorg 798 # except for --package-id which is not required since it is not stored as part of 799 # the definition 800 peer lifecycle chaincode checkcommitreadiness --channelID $CHANNEL_NAME --name mycc --version 1.0 --init-required --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json 801 802 The command will produce as output a JSON map showing if the organizations in the 803 channel have approved the chaincode definition provided in the checkcommitreadiness 804 command. In this case, given that both organizations have approved, we obtain: 805 806 .. code:: bash 807 808 { 809 "Approvals": { 810 "Org1MSP": true, 811 "Org2MSP": true 812 } 813 } 814 815 Since both channel members have approved the definition, we can now commit it to 816 the channel using the following command. You can issue this command as either 817 Org1 or Org2. Note that the transaction targets peers in Org1 and Org2 to 818 collect endorsements. 819 820 .. code:: bash 821 822 # this commits the chaincode definition to the channel 823 peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID $CHANNEL_NAME --name mycc --version 1.0 --sequence 1 --init-required --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 824 825 Invoking the chaincode 826 ^^^^^^^^^^^^^^^^^^^^^^ 827 828 After a chaincode definition has been committed to a channel, we are ready to 829 invoke the chaincode and start interacting with the ledger. We requested the 830 execution of the ``Init`` function in the chaincode definition using the 831 ``--init-required`` flag. As a result, we need to pass the ``--isInit`` flag to 832 its first invocation and supply the arguments to the ``Init`` function. Issue the 833 following command to initialize the chaincode and put the initial data on the 834 ledger. 835 836 .. code:: bash 837 838 # be sure to set the -C and -n flags appropriately 839 # use the --isInit flag if you are invoking an Init function 840 peer chaincode invoke -o orderer.example.com:7050 --isInit --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["Init","a","100","b","100"]}' --waitForEvent 841 842 The first invoke will start the chaincode container. We may need to wait for the 843 container to start. Node.js images will take longer. 844 845 Query 846 ^^^^^ 847 848 Let's query the chaincode to make sure that the container was properly started 849 and the state DB was populated. The syntax for query is as follows: 850 851 .. code:: bash 852 853 # be sure to set the -C and -n flags appropriately 854 855 peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' 856 857 Invoke 858 ^^^^^^ 859 860 Now let’s move ``10`` from ``a`` to ``b``. This transaction will cut a new block 861 and update the state DB. The syntax for invoke is as follows: 862 863 .. code:: bash 864 865 # be sure to set the -C and -n flags appropriately 866 peer chaincode invoke -o orderer.example.com:7050 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["invoke","a","b","10"]}' --waitForEvent 867 868 Query 869 ^^^^^ 870 871 Let's confirm that our previous invocation executed properly. We initialized the 872 key ``a`` with a value of ``100`` and just removed ``10`` with our previous 873 invocation. Therefore, a query against ``a`` should return ``90``. The syntax 874 for query is as follows. 875 876 .. code:: bash 877 878 # be sure to set the -C and -n flags appropriately 879 880 peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' 881 882 We should see the following: 883 884 .. code:: bash 885 886 Query Result: 90 887 888 Install the chaincode on an additional peer 889 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 890 891 If you want additional peers to interact with the ledger, then you will need to 892 join them to the channel and install the same chaincode package on the peers. 893 You only need to approve the chaincode definition once from your organization. 894 A chaincode container will be launched for each peer as soon as they try to 895 interact with that specific chaincode. Again, be cognizant of the fact that the 896 Node.js images will be slower to build and start upon the first invoke. 897 898 We will install the chaincode on a third peer, peer1 in Org2. Modify the 899 following four environment variables to issue the install command against peer1 900 in Org2: 901 902 .. code:: bash 903 904 # Environment variables for PEER1 in Org2 905 906 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 907 CORE_PEER_ADDRESS=peer1.org2.example.com:10051 908 CORE_PEER_LOCALMSPID="Org2MSP" 909 CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt 910 911 Now install the ``mycc`` package on peer1 of Org2: 912 913 .. code:: bash 914 915 # this command installs a chaincode package on your peer 916 peer lifecycle chaincode install mycc.tar.gz 917 918 Query 919 ^^^^^ 920 921 Let's confirm that we can issue the query to Peer1 in Org2. We initialized the 922 key ``a`` with a value of ``100`` and just removed ``10`` with our previous 923 invocation. Therefore, a query against ``a`` should still return ``90``. 924 925 Peer1 in Org2 must first join the channel before it can respond to queries. The 926 channel can be joined by issuing the following command: 927 928 .. code:: bash 929 930 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp CORE_PEER_ADDRESS=peer1.org2.example.com:10051 CORE_PEER_LOCALMSPID="Org2MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt peer channel join -b mychannel.block 931 932 After the join command returns, the query can be issued. The syntax for query is 933 as follows. 934 935 .. code:: bash 936 937 # be sure to set the -C and -n flags appropriately 938 939 peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' 940 941 We should see the following: 942 943 .. code:: bash 944 945 Query Result: 90 946 947 If you received an error, it may be because it takes a few seconds for the 948 peer to join and catch up to the current blockchain height. You may 949 re-query as needed. Feel free to perform additional invokes as well. 950 951 .. _behind-scenes: 952 953 What's happening behind the scenes? 954 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 955 956 .. note:: These steps describe the scenario in which 957 ``script.sh`` is run by './byfn.sh up'. Clean your network 958 with ``./byfn.sh down`` and ensure 959 this command is active. Then use the same 960 docker-compose prompt to launch your network again 961 962 - A script - ``script.sh`` - is baked inside the CLI container. The 963 script drives the ``createChannel`` command against the supplied channel name 964 and uses the channel.tx file for channel configuration. 965 966 - The output of ``createChannel`` is a genesis block - 967 ``<your_channel_name>.block`` - which gets stored on the peers' file systems and contains 968 the channel configuration specified from channel.tx. 969 970 - The ``joinChannel`` command is exercised for all four peers, which takes as 971 input the previously generated genesis block. This command instructs the 972 peers to join ``<your_channel_name>`` and create a chain starting with ``<your_channel_name>.block``. 973 974 - Now we have a channel consisting of four peers, and two 975 organizations. This is our ``TwoOrgsChannel`` profile. 976 977 - ``peer0.org1.example.com`` and ``peer1.org1.example.com`` belong to Org1; 978 ``peer0.org2.example.com`` and ``peer1.org2.example.com`` belong to Org2 979 980 - These relationships are defined through the ``crypto-config.yaml`` and 981 the MSP path is specified in our docker compose. 982 983 - The anchor peers for Org1MSP (``peer0.org1.example.com``) and 984 Org2MSP (``peer0.org2.example.com``) are then updated. We do this by passing 985 the ``Org1MSPanchors.tx`` and ``Org2MSPanchors.tx`` artifacts to the ordering 986 service along with the name of our channel. 987 988 - A chaincode - **abstore** - is packaged and installed on ``peer0.org1.example.com`` 989 and ``peer0.org2.example.com`` 990 991 - The chaincode is then separately approved by Org1 and Org2, and then committed 992 on the channel. Since an endorsement policy was not specified, the channel's 993 default endorsement policy of a majority of organizations will get utilized, 994 meaning that any transaction must be endorsed by a peer tied to Org1 and Org2. 995 996 - The chaincode Init is then called which starts the container for the target peer, 997 and initializes the key value pairs associated with the chaincode. The initial 998 values for this example are ["a","100" "b","200"]. This first invoke results 999 in a container by the name of ``dev-peer0.org2.example.com-mycc-1.0`` starting. 1000 1001 - A query against the value of "a" is issued to ``peer0.org2.example.com``. 1002 A container for Org2 peer0 by the name of ``dev-peer0.org2.example.com-mycc-1.0`` 1003 was started when the chaincode was initialized. The result of the query is 1004 returned. No write operations have occurred, so a query against "a" will 1005 still return a value of "100". 1006 1007 - An invoke is sent to ``peer0.org1.example.com`` and ``peer0.org2.example.com`` 1008 to move "10" from "a" to "b" 1009 1010 - A query is sent to ``peer0.org2.example.com`` for the value of "a". A 1011 value of 90 is returned, correctly reflecting the previous 1012 transaction during which the value for key "a" was modified by 10. 1013 1014 - The chaincode - **abstore** - is installed on ``peer1.org2.example.com`` 1015 1016 - A query is sent to ``peer1.org2.example.com`` for the value of "a". This starts a 1017 third chaincode container by the name of ``dev-peer1.org2.example.com-mycc-1.0``. A 1018 value of 90 is returned, correctly reflecting the previous 1019 transaction during which the value for key "a" was modified by 10. 1020 1021 What does this demonstrate? 1022 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1023 1024 Chaincode **MUST** be installed on a peer in order for it to 1025 successfully perform read/write operations against the ledger. 1026 Furthermore, a chaincode container is not started for a peer until an ``init`` or 1027 traditional transaction - read/write - is performed against that chaincode (e.g. query for 1028 the value of "a"). The transaction causes the container to start. Also, 1029 all peers in a channel maintain an exact copy of the ledger which 1030 comprises the blockchain to store the immutable, sequenced record in 1031 blocks, as well as a state database to maintain a snapshot of the current state. 1032 This includes those peers that do not have chaincode installed on them 1033 (like ``peer1.org1.example.com`` in the above example) . Finally, the chaincode is accessible 1034 after it is installed (like ``peer1.org2.example.com`` in the above example) because its 1035 definition has already been committed on the channel. 1036 1037 How do I see these transactions? 1038 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1039 1040 Check the logs for the CLI Docker container. 1041 1042 .. code:: bash 1043 1044 docker logs -f cli 1045 1046 You should see the following output: 1047 1048 .. code:: bash 1049 1050 2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP 1051 2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity 1052 2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161 1053 2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54 1054 Query Result: 90 1055 2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting..... 1056 ===================== Query successful on peer1.org2 on channel 'mychannel' ===================== 1057 1058 ===================== All GOOD, BYFN execution completed ===================== 1059 1060 1061 _____ _ _ ____ 1062 | ____| | \ | | | _ \ 1063 | _| | \| | | | | | 1064 | |___ | |\ | | |_| | 1065 |_____| |_| \_| |____/ 1066 1067 You can scroll through these logs to see the various transactions. 1068 1069 How can I see the chaincode logs? 1070 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1071 1072 You can inspect the individual chaincode containers to see the separate 1073 transactions executed against each container. Use the following command to find 1074 the list of running containers to find your chaincode containers: 1075 1076 .. code:: bash 1077 1078 $ docker ps -a 1079 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1080 7aa7d9e199f5 dev-peer1.org2.example.com-mycc_1-27ef99cb3cbd1b545063f018f3670eddc0d54f40b2660b8f853ad2854c49a0d8-2eba360c66609a3ba78327c2c86bc3abf041c78f5a35553191a1acf1efdd5a0d "chaincode -peer.add…" About a minute ago Up About a minute dev-peer1.org2.example.com-mycc_1-27ef99cb3cbd1b545063f018f3670eddc0d54f40b2660b8f853ad2854c49a0d8 1081 82ce129c0fe6 dev-peer0.org2.example.com-mycc_1-27ef99cb3cbd1b545063f018f3670eddc0d54f40b2660b8f853ad2854c49a0d8-1297906045aa77086daba21aba47e8eef359f9498b7cb2b010dff3e2a354565a "chaincode -peer.add…" About a minute ago Up About a minute dev-peer0.org2.example.com-mycc_1-27ef99cb3cbd1b545063f018f3670eddc0d54f40b2660b8f853ad2854c49a0d8 1082 eaef1a8f7acf dev-peer0.org1.example.com-mycc_1-27ef99cb3cbd1b545063f018f3670eddc0d54f40b2660b8f853ad2854c49a0d8-00d8dbefd85a4aeb9428b7df95df9744be1325b2a60900ac7a81796e67e4280a "chaincode -peer.add…" 2 minutes ago Up 2 minutes dev-peer0.org1.example.com-mycc_1-27ef99cb3cbd1b545063f018f3670eddc0d54f40b2660b8f853ad2854c49a0d8 1083 da403175b785 hyperledger/fabric-tools:latest "/bin/bash" 4 minutes ago Up 4 minutes cli 1084 c62a8d03818f hyperledger/fabric-peer:latest "peer node start" 4 minutes ago Up 4 minutes 7051/tcp, 0.0.0.0:9051->9051/tcp peer0.org2.example.com 1085 06593c4f3e53 hyperledger/fabric-peer:latest "peer node start" 4 minutes ago Up 4 minutes 0.0.0.0:7051->7051/tcp peer0.org1.example.com 1086 4ddc928ebffe hyperledger/fabric-orderer:latest "orderer" 4 minutes ago Up 4 minutes 0.0.0.0:7050->7050/tcp orderer.example.com 1087 6d79e95ec059 hyperledger/fabric-peer:latest "peer node start" 4 minutes ago Up 4 minutes 7051/tcp, 0.0.0.0:10051->10051/tcp peer1.org2.example.com 1088 6aad6b40fd30 hyperledger/fabric-peer:latest "peer node start" 4 minutes ago Up 4 minutes 7051/tcp, 0.0.0.0:8051->8051/tcp peer1.org1.example.com 1089 1090 The chaincode containers are the images starting with `dev-peer`. You can then 1091 use the container ID to find the logs from each chaincode container. 1092 1093 .. code:: bash 1094 1095 $ docker logs 7aa7d9e199f5 1096 ABstore Init 1097 Aval = 100, Bval = 100 1098 ABstore Invoke 1099 Aval = 90, Bval = 110 1100 1101 $ docker logs eaef1a8f7acf 1102 ABstore Init 1103 Aval = 100, Bval = 100 1104 ABstore Invoke 1105 Query Response:{"Name":"a","Amount":"100"} 1106 ABstore Invoke 1107 Aval = 90, Bval = 110 1108 ABstore Invoke 1109 Query Response:{"Name":"a","Amount":"90"} 1110 1111 You can also see the peer logs to view chaincode invoke messages 1112 and block commit messages: 1113 1114 .. code:: bash 1115 1116 $ docker logs peer0.org1.example.com 1117 1118 Understanding the Docker Compose topology 1119 ----------------------------------------- 1120 1121 The BYFN sample offers us two flavors of Docker Compose files, both of which 1122 are extended from the ``docker-compose-base.yaml`` (located in the ``base`` 1123 folder). Our first flavor, ``docker-compose-cli.yaml``, provides us with a 1124 CLI container, along with an orderer, four peers. We use this file 1125 for the entirety of the instructions on this page. 1126 1127 .. note:: the remainder of this section covers a docker-compose file designed for the 1128 SDK. Refer to the `Node SDK <https://github.com/hyperledger/fabric-sdk-node>`__ 1129 repo for details on running these tests. 1130 1131 The second flavor, ``docker-compose-e2e.yaml``, is constructed to run end-to-end tests 1132 using the Node.js SDK. Aside from functioning with the SDK, its primary differentiation 1133 is that there are containers for the fabric-ca servers. As a result, we are able 1134 to send REST calls to the organizational CAs for user registration and enrollment. 1135 1136 If you want to use the ``docker-compose-e2e.yaml`` without first running the 1137 byfn.sh script, then we will need to make four slight modifications. 1138 We need to point to the private keys for our Organization's CA's. You can locate 1139 these values in your crypto-config folder. For example, to locate the private 1140 key for Org1 we would follow this path - ``crypto-config/peerOrganizations/org1.example.com/ca/``. 1141 The private key is a long hash value followed by ``_sk``. The path for Org2 1142 would be - ``crypto-config/peerOrganizations/org2.example.com/ca/``. 1143 1144 In the ``docker-compose-e2e.yaml`` update the FABRIC_CA_SERVER_TLS_KEYFILE variable 1145 for ca0 and ca1. You also need to edit the path that is provided in the command 1146 to start the ca server. You are providing the same private key twice for each 1147 CA container. 1148 1149 Using CouchDB 1150 ------------- 1151 1152 The state database can be switched from the default (goleveldb) to CouchDB. 1153 The same chaincode functions are available with CouchDB, however, there is the 1154 added ability to perform rich and complex queries against the state database 1155 data content contingent upon the chaincode data being modeled as JSON. 1156 1157 To use CouchDB instead of the default database (goleveldb), follow the same 1158 procedures outlined earlier for generating the artifacts, except when starting 1159 the network pass ``docker-compose-couch.yaml`` as well: 1160 1161 .. code:: bash 1162 1163 docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d 1164 1165 **abstore** should now work using CouchDB underneath. 1166 1167 .. note:: If you choose to implement mapping of the fabric-couchdb container 1168 port to a host port, please make sure you are aware of the security 1169 implications. Mapping of the port in a development environment makes the 1170 CouchDB REST API available, and allows the 1171 visualization of the database via the CouchDB web interface (Fauxton). 1172 Production environments would likely refrain from implementing port mapping in 1173 order to restrict outside access to the CouchDB containers. 1174 1175 You can use **abstore** chaincode against the CouchDB state database 1176 using the steps outlined above, however in order to exercise the CouchDB query 1177 capabilities you will need to use a chaincode that has data modeled as JSON. 1178 The sample chaincode **marbles02** has been written to demostrate the queries 1179 you can issue from your chaincode if you are using a CouchDB database. You can 1180 locate the **marbles02** chaincode in the ``fabric/examples/chaincode/go`` 1181 directory. 1182 1183 We will follow the same process to create and join the channel as outlined in the 1184 :ref:`peerenvvars` section above. Once you have joined your peer(s) to the 1185 channel, use the following steps to interact with the **marbles02** chaincode: 1186 1187 1188 - Package and install the chaincode on ``peer0.org1.example.com``: 1189 1190 .. code:: bash 1191 1192 peer lifecycle chaincode package marbles.tar.gz --path github.com/hyperledger/fabric-samples/chaincode/marbles02/go/ --lang golang --label marbles_1 1193 peer lifecycle chaincode install marbles.tar.gz 1194 1195 The install command will return a chaincode packageID that you will use to 1196 approve a chaincode definition. 1197 1198 .. code:: bash 1199 1200 2019-04-08 20:10:32.568 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 001 Installed remotely: response:<status:200 payload:"\nJmarbles_1:cfb623954827aef3f35868764991cc7571b445a45cfd3325f7002f14156d61ae\022\tmarbles_1" > 1201 2019-04-08 20:10:32.568 UTC [cli.lifecycle.chaincode] submitInstallProposal -> INFO 002 Chaincode code package identifier: marbles_1:cfb623954827aef3f35868764991cc7571b445a45cfd3325f7002f14156d61ae 1202 1203 - Save the packageID as an environment variable so you can pass it to future 1204 commands: 1205 1206 .. code:: bash 1207 1208 CC_PACKAGE_ID=marbles_1:3a8c52d70c36313cfebbaf09d8616e7a6318ababa01c7cbe40603c373bcfe173 1209 1210 - Approve a chaincode definition as Org1: 1211 1212 .. code:: bash 1213 1214 # be sure to modify the $CHANNEL_NAME variable accordingly for the command 1215 1216 peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name marbles --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 1217 1218 - Install the chaincode on ``peer0.org2.example.com``: 1219 1220 .. code:: bash 1221 1222 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp 1223 CORE_PEER_ADDRESS=peer0.org2.example.com:9051 1224 CORE_PEER_LOCALMSPID="Org2MSP" 1225 CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 1226 peer lifecycle chaincode install marbles.tar.gz 1227 1228 - Approve a chaincode definition as Org2, and then commit the definition to the 1229 channel: 1230 1231 .. code:: bash 1232 1233 # be sure to modify the $CHANNEL_NAME variable accordingly for the command 1234 1235 peer lifecycle chaincode approveformyorg --channelID $CHANNEL_NAME --name marbles --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem 1236 peer lifecycle chaincode commit -o orderer.example.com:7050 --channelID $CHANNEL_NAME --name marbles --version 1.0 --sequence 1 --tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt 1237 1238 - We can now create some marbles. The first invoke of the chaincode will start 1239 the chaincode container. You may need to wait for the container to start. 1240 1241 .. code:: bash 1242 1243 # be sure to modify the $CHANNEL_NAME variable accordingly 1244 1245 peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["initMarble","marble1","blue","35","tom"]}' 1246 1247 Once the container has started, you can issue additional commands to create 1248 some marbles and move them around: 1249 1250 .. code:: bash 1251 1252 # be sure to modify the $CHANNEL_NAME variable accordingly 1253 1254 peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["initMarble","marble2","red","50","tom"]}' 1255 peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["initMarble","marble3","blue","70","tom"]}' 1256 peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["transferMarble","marble2","jerry"]}' 1257 peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}' 1258 peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles --peerAddresses peer0.org1.example.com:7051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses peer0.org2.example.com:9051 --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"Args":["delete","marble1"]}' 1259 1260 - If you chose to map the CouchDB ports in docker-compose, you can now view 1261 the state database through the CouchDB web interface (Fauxton) by opening 1262 a browser and navigating to the following URL: 1263 1264 ``http://localhost:5984/_utils`` 1265 1266 You should see a database named ``mychannel`` (or your unique channel name) and 1267 the documents inside it. 1268 1269 .. note:: For the below commands, be sure to update the $CHANNEL_NAME variable appropriately. 1270 1271 You can run regular queries from the CLI (e.g. reading ``marble2``): 1272 1273 .. code:: bash 1274 1275 peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["readMarble","marble2"]}' 1276 1277 The output should display the details of ``marble2``: 1278 1279 .. code:: bash 1280 1281 Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50} 1282 1283 You can retrieve the history of a specific marble - e.g. ``marble1``: 1284 1285 .. code:: bash 1286 1287 peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}' 1288 1289 The output should display the transactions on ``marble1``: 1290 1291 .. code:: bash 1292 1293 Query Result: [{"TxId":"1c3d3caf124c89f91a4c0f353723ac736c58155325f02890adebaa15e16e6464", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"tom"}},{"TxId":"755d55c281889eaeebf405586f9e25d71d36eb3d35420af833a20a2f53a3eefd", "Value":{"docType":"marble","name":"marble1","color":"blue","size":35,"owner":"jerry"}},{"TxId":"819451032d813dde6247f85e56a89262555e04f14788ee33e28b232eef36d98f", "Value":}] 1294 1295 You can also perform rich queries on the data content, such as querying marble fields by owner ``jerry``: 1296 1297 .. code:: bash 1298 1299 peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}' 1300 1301 The output should display the two marbles owned by ``jerry``: 1302 1303 .. code:: bash 1304 1305 Query Result: [{"Key":"marble2", "Record":{"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}},{"Key":"marble3", "Record":{"color":"blue","docType":"marble","name":"marble3","owner":"jerry","size":70}}] 1306 1307 1308 Why CouchDB 1309 ------------- 1310 CouchDB is a kind of NoSQL solution. It is a document-oriented database where document fields are stored as key-value maps. Fields can be either a simple key-value pair, list, or map. 1311 In addition to keyed/composite-key/key-range queries which are supported by LevelDB, CouchDB also supports full data rich queries capability, such as non-key queries against the whole blockchain data, 1312 since its data content is stored in JSON format and fully queryable. Therefore, CouchDB can meet chaincode, auditing, reporting requirements for many use cases that not supported by LevelDB. 1313 1314 CouchDB can also enhance the security for compliance and data protection in the blockchain. As it is able to implement field-level security through the filtering and masking of individual attributes within a transaction, and only authorizing the read-only permission if needed. 1315 1316 In addition, CouchDB falls into the AP-type (Availability and Partition Tolerance) of the CAP theorem. It uses a master-master replication model with ``Eventual Consistency``. 1317 More information can be found on the 1318 `Eventual Consistency page of the CouchDB documentation <http://docs.couchdb.org/en/latest/intro/consistency.html>`__. 1319 However, under each fabric peer, there is no database replicas, writes to database are guaranteed consistent and durable (not ``Eventual Consistency``). 1320 1321 CouchDB is the first external pluggable state database for Fabric, and there could and should be other external database options. For example, IBM enables the relational database for its blockchain. 1322 And the CP-type (Consistency and Partition Tolerance) databases may also in need, so as to enable data consistency without application level guarantee. 1323 1324 1325 A Note on Data Persistence 1326 -------------------------- 1327 1328 If data persistence is desired on the peer container or the CouchDB container, 1329 one option is to mount a directory in the docker-host into a relevant directory 1330 in the container. For example, you may add the following two lines in 1331 the peer container specification in the ``docker-compose-base.yaml`` file: 1332 1333 .. code:: bash 1334 1335 volumes: 1336 - /var/hyperledger/peer0:/var/hyperledger/production 1337 1338 For the CouchDB container, you may add the following two lines in the CouchDB 1339 container specification: 1340 1341 .. code:: bash 1342 1343 volumes: 1344 - /var/hyperledger/couchdb0:/opt/couchdb/data 1345 1346 .. _Troubleshoot: 1347 1348 Troubleshooting 1349 --------------- 1350 1351 - Always start your network fresh. Use the following command 1352 to remove artifacts, crypto, containers and chaincode images: 1353 1354 .. code:: bash 1355 1356 ./byfn.sh down 1357 1358 .. note:: You **will** see errors if you do not remove old containers 1359 and images. 1360 1361 - If you see Docker errors, first check your docker version (:doc:`prereqs`), 1362 and then try restarting your Docker process. Problems with Docker are 1363 oftentimes not immediately recognizable. For example, you may see errors 1364 resulting from an inability to access crypto material mounted within a 1365 container. 1366 1367 If they persist remove your images and start from scratch: 1368 1369 .. code:: bash 1370 1371 docker rm -f $(docker ps -aq) 1372 docker rmi -f $(docker images -q) 1373 1374 - If you see errors on your create, approve, commit, invoke or query commands, 1375 make sure you have properly updated the channel name and chaincode name. 1376 There are placeholder values in the supplied sample commands. 1377 1378 - If you see the below error: 1379 1380 .. code:: bash 1381 1382 Error: Error endorsing chaincode: rpc error: code = 2 desc = Error installing chaincode code mycc:1.0(chaincode /var/hyperledger/production/chaincodes/mycc.1.0 exits) 1383 1384 You likely have chaincode images (e.g. ``dev-peer1.org2.example.com-mycc-1.0`` or 1385 ``dev-peer0.org1.example.com-mycc-1.0``) from prior runs. Remove them and try 1386 again. 1387 1388 .. code:: bash 1389 1390 docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}') 1391 1392 - If you see something similar to the following: 1393 1394 .. code:: bash 1395 1396 Error connecting: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure 1397 Error: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure 1398 1399 Make sure you are running your network against the "1.0.0" images that have 1400 been retagged as "latest". 1401 1402 - If you see the below error: 1403 1404 .. code:: bash 1405 1406 [configtx/tool/localconfig] Load -> CRIT 002 Error reading configuration: Unsupported Config Type "" 1407 panic: Error reading configuration: Unsupported Config Type "" 1408 1409 Then you did not set the ``FABRIC_CFG_PATH`` environment variable properly. The 1410 configtxgen tool needs this variable in order to locate the configtx.yaml. Go 1411 back and execute an ``export FABRIC_CFG_PATH=$PWD``, then recreate your 1412 channel artifacts. 1413 1414 - To cleanup the network, use the ``down`` option: 1415 1416 .. code:: bash 1417 1418 ./byfn.sh down 1419 1420 - If you see an error stating that you still have "active endpoints", then prune 1421 your Docker networks. This will wipe your previous networks and start you with a 1422 fresh environment: 1423 1424 .. code:: bash 1425 1426 docker network prune 1427 1428 You will see the following message: 1429 1430 .. code:: bash 1431 1432 WARNING! This will remove all networks not used by at least one container. 1433 Are you sure you want to continue? [y/N] 1434 1435 Select ``y``. 1436 1437 - If you see an error similar to the following: 1438 1439 .. code:: bash 1440 1441 /bin/bash: ./scripts/script.sh: /bin/bash^M: bad interpreter: No such file or directory 1442 1443 Ensure that the file in question (**script.sh** in this example) is encoded 1444 in the Unix format. This was most likely caused by not setting 1445 ``core.autocrlf`` to ``false`` in your Git configuration (see 1446 :ref:`windows-extras`). There are several ways of fixing this. If you have 1447 access to the vim editor for instance, open the file: 1448 1449 .. code:: bash 1450 1451 vim ./fabric-samples/first-network/scripts/script.sh 1452 1453 Then change its format by executing the following vim command: 1454 1455 .. code:: bash 1456 1457 :set ff=unix 1458 1459 .. note:: If you continue to see errors, share your logs on the 1460 **fabric-questions** channel on 1461 `Hyperledger Rocket Chat <https://chat.hyperledger.org/home>`__ 1462 or on `StackOverflow <https://stackoverflow.com/questions/tagged/hyperledger-fabric>`__. 1463 1464 .. Licensed under Creative Commons Attribution 4.0 International License 1465 https://creativecommons.org/licenses/by/4.0/