github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/examples/dchackfest/samples/e2e/README.rst (about) 1 Getting Started 2 =============== 3 4 The getting started scenario provisions a sample Fabric network consisting of 5 two organizations, each maintaining two peers, and a "solo" ordering service. 6 7 Prior to launching the network, we will demonstrate the usage of two fundamental tools: 8 - cryptogen - generates the x509 certificates used to identify and authenticate 9 the various components in the network. 10 - configtxgen - generates the requisite configuration artifacts for orderer 11 bootstrap and channel creation. 12 13 In no time we'll have a fully-functioning transactional network with a shared 14 ledger and digital signature verification. Let's get going... 15 16 Prerequisites and setup 17 ----------------------- 18 19 - `Docker <https://www.docker.com/products/overview>`__ - v1.12 or higher 20 - `Docker Compose <https://docs.docker.com/compose/overview/>`__ - v1.8 or higher 21 - `Docker Toolbox <https://docs.docker.com/toolbox/toolbox_install_windows/>`__ - Windows users only 22 - `Go <https://golang.org/>`__ - 1.7 or higher 23 - `Git Bash <https://git-scm.com/downloads>`__ - Windows users only; provides a better alternative to the Windows command prompt 24 25 Curl the artifacts and binaries 26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 27 28 .. note:: If you are running on Windows you will want to make use of your Git 29 Bash shell for the upcoming terminal commands. 30 31 - Download the `cURL <https://curl.haxx.se/download.html>`__ tool if not already installed. 32 - Determine a location on your machine where you want to place the artifacts and binaries. 33 34 .. code:: bash 35 36 mkdir -p <my_dev_workspace>/dchackfest 37 cd <my_dev_workspace>/dchackfest 38 39 Next, execute the following command: 40 41 .. code:: bash 42 43 curl -L https://logs.hyperledger.org/sandbox/vex-yul-hyp-jenkins-2/fabric-verify-x86_64_1/4/release.tar.gz -o release.tar.gz 2> /dev/null; tar -xvf release.tar.gz 44 45 This command pulls and extracts all of the necessary artifacts to set up your 46 network and places them into a folder titled ``release``. It also retrieves the 47 two binaries - cryptogen and configtxgen - which are briefly described at the top 48 of this page. 49 50 Pulling the docker images 51 ^^^^^^^^^^^^^^^^^^^^^^^^^ 52 53 Change directories into ``release``. You should see the following: 54 55 .. code:: bash 56 57 jdoe-mbp:release johndoe$ ls 58 darwin-amd64 linux-amd64 linux-ppc64le linux-s390x samples templates windows-amd64 59 60 You will notice that there are platform-specific folders. Each folder contains the 61 corresponding binaries for that platform, along with a script that we will use 62 to download the Fabric images. Right now we're only interested in the script. 63 Navigate into the folder matching your machine's OS and then into ``install``. 64 For example, if you were running on OSX: 65 66 .. code:: bash 67 68 cd darwin-amd64/install 69 70 Now run the shell script to download the docker images. This will take a few 71 minutes so remember that patience is a virtue: 72 73 .. code:: bash 74 75 ./get-docker-images.sh 76 77 Execute a ``docker images`` command to view your images. Assuming you had no 78 images on your machine prior to running the script, you should see the following: 79 80 .. code:: bash 81 82 jdoe-mbp:install johndoe$ docker images 83 REPOSITORY TAG IMAGE ID CREATED SIZE 84 hyperledger/fabric-couchdb x86_64-1.0.0-alpha f3ce31e25872 5 weeks ago 1.51 GB 85 hyperledger/fabric-kafka x86_64-1.0.0-alpha 589dad0b93fc 5 weeks ago 1.3 GB 86 hyperledger/fabric-zookeeper x86_64-1.0.0-alpha 9a51f5be29c1 5 weeks ago 1.31 GB 87 hyperledger/fabric-orderer x86_64-1.0.0-alpha 5685fd77ab7c 5 weeks ago 182 MB 88 hyperledger/fabric-peer x86_64-1.0.0-alpha 784c5d41ac1d 5 weeks ago 184 MB 89 hyperledger/fabric-javaenv x86_64-1.0.0-alpha a08f85d8f0a9 5 weeks ago 1.42 GB 90 hyperledger/fabric-ccenv x86_64-1.0.0-alpha 91792014b61f 5 weeks ago 1.29 GB 91 92 Look at the names for each image; these are the components that will ultimately 93 comprise our Fabric network. 94 95 Using the cryptogen tool 96 ------------------------ 97 98 First, lets set the environment variable for our platform. This command 99 will detect your OS and use the appropriate binaries for the subsequent steps: 100 101 .. code:: bash 102 103 # for power or z 104 os_arch=$(echo "$(uname -s)-$(uname -m)" | awk '{print tolower($0)}') 105 # for linux, osx or windows 106 os_arch=$(echo "$(uname -s)-amd64" | awk '{print tolower($0)}') 107 108 Ok now for the fun stuff - generating the crypto material. Pop into the ``e2e`` folder: 109 110 .. code:: bash 111 112 cd ../../samples/e2e 113 114 We are going to pass in the ``crypto-config.yaml`` file as an argument for the 115 upcoming command. This file contains the definition/structure of our network 116 and lists the components that we are generating certs for. If you open the file 117 you will see that our network will consist of - one ``OrdererOrg`` and two 118 ``PeerOrgs`` each maintaining two peers. You can easily modify this file to 119 generate certs for a more elaborate network, however we will leave the sample configuration 120 for the sake of simplicity. Got it? Let's run the tool now: 121 122 .. code:: bash 123 124 # this syntax requires you to be in the e2e directory 125 # notice that we will pass in the $os_arch variable in order to use the correct binary 126 ./../../$os_arch/bin/cryptogen generate --config=./crypto-config.yaml 127 128 If the tool runs successfully, you will see the various KeyStores churn out in 129 your terminal. The certs are then parked into a ``crypto-config`` folder that 130 is generated when you run the tool. 131 132 Using the configtxgen tool 133 -------------------------- 134 135 We will now use our second tool - configtxgen - to create our ordering service 136 genesis block and a channel configuration artifact. As the abbreviation suggests, 137 this tool is a configuration transaction generator. More info on the configtxgen 138 tool can be found `here <http://hyperledger-fabric.readthedocs.io/en/latest/configtxgen.html>`__ 139 However, at this stage (and for the sake of brevity) we will simply make use of 140 the tool to generate our two artifacts. 141 142 .. note:: The ``configtx.yaml`` file contains the definitions for our sample 143 network and presents the topology of the network components - three members 144 (OrdererOrg, Org0 & Org1), and the anchor peers for each PeerOrg 145 (peer0 and peer2). You will notice 146 that it is structured similarly to the ``crypto-config.yaml`` that we 147 just passed to generate our certs. The main difference is that we can 148 now point to the locations of those certs. You'll recall that in the 149 previous step we created a new folder called ``crypto-config`` and parked 150 the certs there. The ``configtx.yaml`` points to that directory and 151 allows us to bundle the root certs for the Orgs constituting our 152 network into the genesis block. This is a critical concept. Now any 153 network entity communicating with the ordering service can have its 154 digital signature verified. 155 156 Generate the orderer genesis block 157 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 158 159 From your ``e2e`` folder first execute the following: 160 161 .. code:: bash 162 163 # this command will not return a response 164 export ORDERER_CFG_PATH=$PWD 165 166 Then use the tool: 167 168 .. code:: bash 169 170 # notice at the top of configtx.yaml we define the profile as TwoOrgs 171 ./../../$os_arch/bin/configtxgen -profile TwoOrgs -outputBlock orderer.block 172 # for example, if you are running OSX then the binary from darwin-amd64 would have been used 173 174 The orderer genesis block - ``orderer.block`` - is output into the ``e2e`` directory. 175 176 Generate the channel configuration artifact 177 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 178 179 When we call the ``createChannel`` API, and send the proposal to the ordering 180 service, we need to pass a channel configuration artifact along with this call. 181 We will once again leverage the ``configtx.yaml`` and use the same profile 182 definition - TwoOrgs - that we used to create the orderer genesis block. In 183 other words, this channel we are creating is a network-wide channel. All Orgs 184 are included. 185 186 Still in your ``e2e`` folder execute the following: 187 188 .. code:: bash 189 190 191 # replace the <CHANNEL_NAME> parm with a name of your choosing 192 ./../../$os_arch/bin/configtxgen -profile TwoOrgs -outputCreateChannelTx channel.tx -channelID <CHANNEL_NAME> 193 194 The channel configuration artifact - ``channel.tx`` - is output into the ``e2e`` directory. 195 196 .. note:: Our configtx.yaml only contains one profile, therefore our channel and 197 our network are the same. However, this file could have multiple profiles 198 allowing channel creation to be scoped more granularly. 199 200 Start the network (No TLS) 201 -------------------------- 202 203 We will leverage a docker-compose script to spin up our network. The docker-compose 204 points to the images that we have already downloaded, and bootstraps the orderer 205 with our previously generated ``orderer.block``. Before launching the network, 206 open the docker-compose file and comment out the ``script.sh`` in the CLI container. 207 Your docker-compose should look like this: 208 209 .. code:: bash 210 211 working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer 212 #command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; ' 213 volumes: 214 215 If left uncommented, the script will exercise all of the CLI commands when the 216 network is started. However, we want to go through the commands manually in order to 217 expose the syntax and functionality of each call. 218 219 Start your network: 220 221 .. code:: bash 222 223 # this sets our OS 224 export ARCH_TAG=$(uname -m) 225 # this starts the network in "detached" mode; enter the appropriate value for the CHANNEL_NAME parm 226 CHANNEL_NAME=<CHANNEL_NAME> docker-compose -f docker-compose-no-tls.yaml up -d 227 228 If you'd like to see the realtime logs for the components, then remove the ``-d`` flag: 229 230 .. code:: bash 231 232 CHANNEL_NAME=<CHANNEL_NAME> docker-compose -f docker-compose-no-tls.yaml up 233 234 Now open another terminal and navigate back to ``release/samples/e2e``. 235 236 Create & Join Channel 237 --------------------- 238 239 Go into the cli container: 240 241 .. code:: bash 242 243 docker exec -it cli bash 244 245 You should see the following: 246 247 .. code:: bash 248 249 root@bb5e894d9668:/opt/gopath/src/github.com/hyperledger/fabric/peer# 250 251 Create Channel 252 ^^^^^^^^^^^^^^ 253 254 Recall that we used the configtxgen tool to generate a channel configuration 255 artifact - ``channel.tx``. We are going to pass in this artifact to the 256 orderer as part of the create channel request. 257 258 .. note:: For this command we don't need to pass in any MSP or crypto material 259 attached to our peer. We do, however, need to pass in the MSP info 260 for our orderer. 261 262 The following environment variables for the orderer must be passed: 263 264 .. code:: bash 265 266 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com 267 CORE_PEER_LOCALMSPID="OrdererMSP" 268 CHANNEL_NAME=<YOUR_CHANNEL_NAME> 269 270 The syntax is as follows: 271 272 .. code:: bash 273 274 peer channel create -o <ORDERER_NAME>:7050 -c <CHANNEL_NAME> -f channel.tx 275 276 So our command in its entirety would be: 277 278 .. code:: bash 279 280 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com CORE_PEER_LOCALMSPID="OrdererMSP" peer channel create -o orderer.example.com:7050 -c mychannel -f channel.tx 281 282 This command returns a genesis block - ``mychannel.block`` - which we will use 283 to join the channel. 284 285 Environment Variables 286 ~~~~~~~~~~~~~~~~~~~~~ 287 288 You can see the syntax for all commands by inspecting the ``script.sh`` file in the ``scripts`` directory. 289 290 For the following cli commands against ``PEER0`` to work, we need to set the 291 values for the four global environment variables given below. Please make sure to override 292 the values accordingly when calling commands against other peers and the orderer. 293 294 .. code:: bash 295 296 # Environment variables for PEER0 297 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com 298 CORE_PEER_ADDRESS=peer0.org1.example.com:7051 299 CORE_PEER_LOCALMSPID="Org0MSP" 300 CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem 301 302 These environment variables for each peer are defined in the supplied docker-compose file. 303 304 .. note:: In these examples, we are use the default ``mychannel`` for all CHANNEL_NAME arguments. 305 If you elect to create a uniquely named channel, be conscious to modify 306 your strings accordingly. 307 308 Join channel 309 ^^^^^^^^^^^^ 310 311 Now let's join ``PEER0`` to the channel by passing in the genesis block that was 312 just returned to us upon the create channel command. 313 314 The syntax is as follows: 315 316 .. code:: bash 317 318 peer channel join -b <CHANNEL_NAME>.block 319 320 Remember, we need to pass the four global variables. So this command in its 321 entirety would be: 322 323 .. code:: bash 324 325 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer channel join -b mychannel.block 326 327 Install 328 ^^^^^^^ 329 330 Now we will install the chaincode source on the peer's filesystem. The syntax 331 is as follows: 332 333 .. code:: bash 334 335 peer chaincode install -n <CHAINCODE_NAME> -v <CHAINCODE_VERSION> -p <CHAINCODE_PATH> 336 337 This command in its entirety would be: 338 339 .. code:: bash 340 341 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 >&log.txt 342 343 Instantiate 344 ^^^^^^^^^^^ 345 346 Now we start the chaincode container and initialize our key value pairs. The 347 syntax for instantiate is as follows: 348 349 .. code:: bash 350 351 peer chaincode instantiate -o <ORDERER_NAME>:7050 -C <CHANNEL_NAME> -n <CHAINCODE_NAME> -v <VERSION> -c '{"Args":["init","key","value"]}' -P "OR/AND (CHAINCODE_POLICY)" 352 353 This command in its entirety would be: 354 355 .. code:: bash 356 357 # we instantiate with the following key value pairs "a","100","b","200" 358 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org0MSP.member','Org1MSP.member')" 359 360 .. note:: The above command will only start a single chaincode container. If 361 you want to interact with different peers, you must first install 362 the source code on that peer's filesystem. You can then send 363 an invoke or query to the peer. You needn't instantiate twice, this 364 command will propagate to the entire channel. 365 366 Query 367 ^^^^^ 368 369 Lets query for the value of "a" to make sure the chaincode was properly instantiated 370 and the state DB was populated. The syntax for query is as follows: 371 372 .. code:: bash 373 374 peer chaincode query -C <CHANNEL_NAME> -n <CHAINCODE_NAME> -c '{"Args":["query","key"]}' 375 376 This command in its entirety would be: 377 378 .. code:: bash 379 380 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}' 381 382 Recall that we initialized our key value pairs as - "a","100","b","200" - therefore, 383 a query against key "a" should return the value of "100". 384 385 Invoke 386 ^^^^^^ 387 388 Lastly we will move "10" from "a" to "b". This transaction will cut a new block 389 and update the state DB. The syntax for invoke is as follows: 390 391 .. code:: bash 392 393 peer chaincode invoke -o <ORDERER_NAME>:7050 -C <CHANNEL_NAME> -n <CHAINCODE_NAME> -c '{"Args":["invoke","key","key","value"]}' 394 395 .. code:: bash 396 397 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}' 398 399 Query 400 ^^^^^ 401 402 Lets confirm that our previous invocation executed properly. We initialized the 403 key "a" with a value of "100". Therefore, removing "10" should return a value 404 of "90" when we query "a". The syntax for query is outlined above. 405 406 .. code:: bash 407 408 CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}' 409 410 411 Start the network (TLS enabled) 412 ------------------------------ 413 414 Use the ``script.sh`` to see the exact syntax for TLS-enabled CLI commands. 415 416 Before starting, we need to modify our docker-compose file to reflect the 417 appropriate private keys for the orderer and peers. 418 419 From your ``e2e`` directory enter the following: 420 421 .. code:: bash 422 423 PRIV_KEY=$(ls crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/keystore/) sed -i "s/ORDERER_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml 424 PRIV_KEY=$(ls crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/keystore/) sed -i "s/PEER0_ORG1_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml 425 PRIV_KEY=$(ls crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/keystore/) sed -i "s/PEER0_ORG2_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml 426 PRIV_KEY=$(ls crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/keystore/) sed -i "s/PEER1_ORG1_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml 427 PRIV_KEY=$(ls crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/keystore/) sed -i "s/PEER1_ORG2_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml 428 429 These commands will modify the TLS_KEY_FILE variables in your docker-compose. 430 Once you have executed all five commands, spin the network back up and begin 431 by creating your channel. 432 433 Scripts 434 ------- 435 436 We exposed the verbosity of the commands in order to provide some edification 437 on the underlying flow and the appropriate syntax. Entering the commands manually 438 through the CLI is quite onerous, therefore we provide a few scripts to do the 439 entirety of the heavy lifting. 440 441 Clean up 442 ^^^^^^^^ 443 444 Lets clean things up before continuing. First, kill your containers: 445 446 .. code:: bash 447 448 docker rm -f $(docker ps -aq) 449 450 Next, execute a ``docker images`` command in your terminal to view the 451 **chaincode** images. They will look similar to the following: 452 453 .. code:: bash 454 455 REPOSITORY TAG IMAGE ID CREATED SIZE 456 dev-peer3-mycc-1.0 latest 13f6c8b042c6 5 minutes ago 176 MB 457 dev-peer0-mycc-1.0 latest e27456b2bd92 5 minutes ago 176 MB 458 dev-peer2-mycc-1.0 latest 111098a7c98c 5 minutes ago 176 MB 459 460 Remove these images: 461 462 .. code:: bash 463 464 docker rmi <IMAGE ID> <IMAGE ID> <IMAGE ID> 465 466 For example: 467 468 .. code:: bash 469 470 docker rmi -f 13f e27 111 471 472 Lastly, remove the `crypto-config`` folder and the two artifacts - ``channel.tx`` 473 & ``orderer.block``. 474 475 All in one 476 ^^^^^^^^^^ 477 478 This script will do it all for you! From the ``e2e`` directory: 479 480 .. code:: bash 481 482 ./network_setup.sh up <channel_name> 483 484 .. note:: If you choose not to pass a channel_name value, then the default 485 ``mychannel`` will be used. 486 487 APIs only 488 ^^^^^^^^^ 489 490 The other option is to manually generate your crypto material and configuration 491 artifacts, and then use the embedded ``script.sh`` in the docker-compose files 492 to drive your network. Make sure this script is not commented out in your 493 CLI container. 494 495 When the scripts complete successfully, you should see the following message 496 in your terminal: 497 498 .. code:: bash 499 500 ===================== Query on PEER3 on channel 'mychannel' is successful ===================== 501 502 ===================== All GOOD, End-2-End execution completed ===================== 503 504 505 Using CouchDB 506 ------------- 507 508 The state database can be switched from the default (goleveldb) to CouchDB. 509 The same chaincode functions are available with CouchDB, however, there is the 510 added ability to perform rich and complex queries against the state database 511 data content contingent upon the chaincode data being modeled as JSON. 512 513 To use CouchDB instead of the default database (goleveldb), follow the same 514 procedure in the **Prerequisites** section, and additionally perform the 515 following two steps to enable the CouchDB containers and associate each peer 516 container with a CouchDB container: 517 518 - Make the CouchDB image. 519 520 .. code:: bash 521 522 # make sure you are in the fabric directory 523 make couchdb 524 525 - Open the ``fabric/examples/e2e_cli/docker-compose.yaml`` and un-comment 526 all commented statements relating to CouchDB containers and peer container 527 use of CouchDB. These instructions are are also outlined in the 528 same ``docker-compose.yaml`` file. Search the file for 'couchdb' (case insensitive) references. 529 530 **chaincode_example02** should now work using CouchDB underneath. 531 532 .. note:: If you choose to implement mapping of the fabric-couchdb container 533 port to a host port, please make sure you are aware of the security 534 implications. Mapping of the port in a development environment allows the 535 visualization of the database via the CouchDB web interface (Fauxton). 536 Production environments would likely refrain from implementing port mapping in 537 order to restrict outside access to the CouchDB containers. 538 539 You can use **chaincode_example02** chaincode against the CouchDB state database 540 using the steps outlined above, however in order to exercise the query 541 capabilities you will need to use a chaincode that has data modeled as JSON, 542 (e.g. **marbles02**). You can locate the **marbles02** chaincode in the 543 ``fabric/examples/chaincode/go`` directory. 544 545 Install, instantiate, invoke, and query **marbles02** chaincode by following the 546 same general steps outlined above for **chaincode_example02** in the 547 **Manually execute transactions** section. After the **Join channel** step, use the 548 following commands to interact with the **marbles02** chaincode: 549 550 - Install and instantiate the chaincode on ``PEER0``: 551 552 .. code:: bash 553 554 peer chaincode install -o orderer0:7050 -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02 555 peer chaincode instantiate -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02 -c '{"Args":["init"]}' -P "OR ('Org0MSP.member','Org1MSP.member')" 556 557 - Create some marbles and move them around: 558 559 .. code:: bash 560 561 peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}' 562 peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}' 563 peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}' 564 peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}' 565 peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}' 566 peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["delete","marble1"]}' 567 568 569 - If you chose to activate port mapping, you can now view the state database 570 through the CouchDB web interface (Fauxton) by opening a browser and 571 navigating to one of the two URLs below. 572 573 For containers running in a vagrant environment: 574 575 ``http://localhost:15984/_utils`` 576 577 For non-vagrant environment, use the port address that was mapped in CouchDB 578 container specification: 579 580 ``http://localhost:5984/_utils`` 581 582 You should see a database named ``mychannel`` and the documents 583 inside it. 584 585 - You can run regular queries from the cli (e.g. reading ``marble2``): 586 587 .. code:: bash 588 589 peer chaincode query -C mychannel -n marbles -c '{"Args":["readMarble","marble2"]}' 590 591 You should see the details of ``marble2``: 592 593 .. code:: bash 594 595 Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50} 596 597 Retrieve the history of ``marble1``: 598 599 .. code:: bash 600 601 peer chaincode query -C mychannel -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}' 602 603 You should see the transactions on ``marble1``: 604 605 .. code:: bash 606 607 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":}] 608 609 You can also perform rich queries on the data content, such as querying marble fields by owner ``jerry``: 610 611 .. code:: bash 612 613 peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}' 614 615 The output should display the two marbles owned by ``jerry``: 616 617 .. code:: bash 618 619 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}}] 620 621 Query by field ``owner`` where the value is ``jerry``: 622 623 .. code:: bash 624 625 peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"jerry\"}}"]}' 626 627 The output should display: 628 629 .. code:: bash 630 631 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}}] 632 633 A Note on Data Persistence 634 -------------------------- 635 636 If data persistence is desired on the peer container or the CouchDB container, 637 one option is to mount a directory in the docker-host into a relevant directory 638 in the container. For example, you may add the following two lines in 639 the peer container specification in the ``docker-compose.yaml`` file: 640 641 .. code:: bash 642 643 volumes: 644 - /var/hyperledger/peer0:/var/hyperledger/production 645 646 647 For the CouchDB container, you may add the following two lines in the CouchDB 648 container specification: 649 650 .. code:: bash 651 652 volumes: 653 - /var/hyperledger/couchdb0:/opt/couchdb/data 654 655 656 Troubleshooting 657 --------------- 658 659 - Ensure you clear the file system after each run 660 661 - If you see docker errors, remove your containers and start again. 662 663 .. code:: bash 664 665 docker rm -f $(docker ps -aq) 666 667 - If you elect to run the "All in one" option, be sure you have deleted your 668 crypto directory and the two artifacts. 669 670 - If you see the below error: 671 672 .. code:: bash 673 674 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) 675 676 You likely have chaincode images (e.g. ``dev-peer0-mycc-1.0`` or ``dev-peer1-mycc-1.0``) 677 from prior runs. Remove them and try again. 678 679 .. code:: bash 680 681 docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}') 682 683 - To cleanup the network, use the ``down`` option: 684 685 .. code:: bash 686 687 ./network_setup.sh down 688 689 -------------------------------------------------------------------------------