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  -------------------------------------------------------------------------------