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