github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/examples/e2e_cli/end-to-end.rst (about)

     1  End-to-End Flow
     2  ===============
     3  
     4  The end-to-end verification provisions a sample Fabric network consisting of
     5  two organizations, each maintaining two peers, and a “solo” ordering service.
     6  
     7  This verification makes use of two fundamental tools, which are necessary to
     8  create a functioning transactional network with digital signature validation
     9  and access control:
    10  
    11  * cryptogen - generates the x509 certificates used to identify and authenticate the various components in the network.
    12  * configtxgen - generates the requisite configuration artifacts for orderer bootstrap and channel creation.
    13  
    14  Each tool consumes a configuration yaml file, within which we specify the topology
    15  of our network (cryptogen) and the location of our certificates for various
    16  configuration operations (configtxgen).  Once the tools have been successfully run,
    17  we are able to launch our network.  More detail on the tools and the structure of
    18  the network will be provided later in this document.  For now, let's get going...
    19  
    20  Prerequisites
    21  -------------
    22  
    23  - `Git client <https://git-scm.com/downloads>`__
    24  - `Docker <https://www.docker.com/products/overview>`__ - v1.12 or higher
    25  - `Docker Compose <https://docs.docker.com/compose/overview/>`__ - v1.8 or higher
    26  - `Homebrew <https://brew.sh/>`__ - OSX only
    27  - `Xcode <https://itunes.apple.com/us/app/xcode/id497799835?mt=12>`__ - OSX only (this can take upwards of an hour)
    28  - `Docker Toolbox <https://docs.docker.com/toolbox/toolbox_install_windows/>`__ - Windows users only
    29  - `Go <https://golang.org/>`__ - 1.7 or higher
    30  
    31  On Windows machines you will also need the following which provides a better alternative to the Windows command prompt:
    32  
    33  - `Git Bash <https://git-scm.com/downloads>`__
    34  
    35  .. note:: On older versions of Windows, such as Windows 7, you
    36            typically get this as part of installing Docker
    37            Toolbox. However experience has shown this to be a poor
    38            development environment with limited functionality. It is
    39            suitable to run docker based scenarios, such as
    40            :doc:`getting_started`, but you may not be able to find a
    41            suitable ``make`` command to successfuly go through the
    42            scenario described here.
    43  
    44  Setting the $GOPATH
    45  ^^^^^^^^^^^^^^^^^^^
    46  Make sure you have properly setup your Host's `GOPATH environment
    47  variable <https://github.com/golang/go/wiki/GOPATH>`__. This is necessary for the
    48  code to compile properly.
    49  
    50  Now create the following directory structure and ``cd`` into it:
    51  
    52  .. code:: bash
    53  
    54        mkdir -p $GOPATH/src/github.com/hyperledger
    55        cd $GOPATH/src/github.com/hyperledger
    56  
    57  -  Clone the Fabric code base into this path.
    58  
    59  .. code:: bash
    60  
    61         git clone http://gerrit.hyperledger.org/r/fabric
    62  
    63  or though a mirrored repository in github:
    64  
    65  .. code:: bash
    66  
    67         git clone https://github.com/hyperledger/fabric.git
    68  
    69  - If you are running OSX, perform the following:
    70  
    71  .. code:: bash
    72  
    73          brew install gnu-tar --with-default-names
    74          brew install libtool
    75  
    76  Build the binaries
    77  ^^^^^^^^^^^^^^^^^^
    78  
    79  -  Now make the platform-specific binaries for ``cryptogen`` and ``configtxgen``.
    80  
    81  .. code:: bash
    82  
    83         cd $GOPATH/src/github.com/hyperledger/fabric
    84         # ensure sure you are in the /fabric directory where the Makefile resides
    85         make release
    86  
    87  This will output platform-specific binaries into the ``fabric/release`` folder.
    88  
    89  -  Next, make the Fabric images.  This typically takes between five to ten minutes, so
    90     be patient:
    91  
    92  .. code:: bash
    93  
    94         # make sure you are in the /fabric directory
    95         make docker
    96  
    97  Execute a ``docker images`` command in your terminal. If the images compiled
    98  successfully, you should see an output similar to the following:
    99  
   100  .. code:: bash
   101  
   102    REPOSITORY                     TAG                   IMAGE ID            CREATED             SIZE
   103    hyperledger/fabric-couchdb     latest                e2df4dd39ca9        38 minutes ago      1.51 GB
   104    hyperledger/fabric-couchdb     x86_64-1.0.0-beta     e2df4dd39ca9        38 minutes ago      1.51 GB
   105    hyperledger/fabric-kafka       latest                08af4d797266        40 minutes ago      1.3 GB
   106    hyperledger/fabric-kafka       x86_64-1.0.0-beta     08af4d797266        40 minutes ago      1.3 GB
   107    hyperledger/fabric-zookeeper   latest                444e9e695367        40 minutes ago      1.31 GB
   108    hyperledger/fabric-zookeeper   x86_64-1.0.0-beta     444e9e695367        40 minutes ago      1.31 GB
   109    hyperledger/fabric-testenv     latest                8678d3101930        41 minutes ago      1.41 GB
   110    hyperledger/fabric-testenv     x86_64-1.0.0-beta     8678d3101930        41 minutes ago      1.41 GB
   111    hyperledger/fabric-buildenv    latest                60911392c82e        41 minutes ago      1.33 GB
   112    hyperledger/fabric-buildenv    x86_64-1.0.0-beta     60911392c82e        41 minutes ago      1.33 GB
   113    hyperledger/fabric-orderer     latest                2afab937b9cc        41 minutes ago      182 MB
   114    hyperledger/fabric-orderer     x86_64-1.0.0-beta     2afab937b9cc        41 minutes ago      182 MB
   115    hyperledger/fabric-peer        latest                9560e58e8089        41 minutes ago      185 MB
   116    hyperledger/fabric-peer        x86_64-1.0.0-beta     9560e58e8089        41 minutes ago      185 MB
   117    hyperledger/fabric-javaenv     latest                881ca5219fad        42 minutes ago      1.43 GB
   118    hyperledger/fabric-javaenv     x86_64-1.0.0-beta     881ca5219fad        42 minutes ago      1.43 GB
   119    hyperledger/fabric-ccenv       latest                28af77ffe9e9        43 minutes ago      1.29 GB
   120    hyperledger/fabric-ccenv       x86_64-1.0.0-beta     28af77ffe9e9        43 minutes ago      1.29 GB
   121    hyperledger/fabric-baseimage   x86_64-0.3.0          f4751a503f02        3 months ago        1.27 GB
   122    hyperledger/fabric-baseos      x86_64-0.3.0          c3a4cf3b3350        3 months ago        161 MB
   123  
   124  If you failed to compile the ``fabric-testenv`` image, then you can
   125  perform a ``make clean`` followed by another ``make docker``.
   126  
   127  Cryptogen Tool
   128  --------------
   129  We will use the cryptogen tool to generate the cryptographic material (x509 certs)
   130  for our various network entities.  The certificates are based on a standard PKI
   131  implementation where validation is achieved by reaching a common trust anchor.
   132  
   133  How does it work?
   134  ^^^^^^^^^^^^^^^^^
   135  
   136  Cryptogen consumes a file - ``crypto-config.yaml`` - that contains the network
   137  topology and allows us to generate a library of certificates for both the
   138  Organizations and the components that belong to those Organizations.  Each
   139  Organization is provisioned a unique root certificate (``ca-cert``), that binds
   140  specific components (peers and orderers) to that Org.  Transactions and communications
   141  within Fabric are signed by an entity's private key (``keystore``), and then verified
   142  by means of a public key (``signcerts``).  You will notice a "count" variable within
   143  this file.  We use this to specify the number of peers per Organization; in our
   144  case it's two peers per Org.  The rest of this template is extremely
   145  self-explanatory.
   146  
   147  After we run the tool, the certs will be parked in a folder titled ``crypto-config``.
   148  
   149  Configuration Transaction Generator
   150  -----------------------------------
   151  
   152  The `configtxgen
   153  tool <https://github.com/hyperledger/fabric/blob/master/docs/source/configtxgen.rst>`__
   154  is used to create four artifacts: orderer **bootstrap block**, fabric
   155  **channel configuration transaction**, and two **anchor peer transactions** - one
   156  for each Peer Org.
   157  
   158  The orderer block is the genesis block for the ordering service, and the
   159  channel transaction file is broadcast to the orderer at channel creation
   160  time.  The anchor peer transactions, as the name might suggest, specify each
   161  Org's anchor peer on this channel.
   162  
   163  How does it work?
   164  ^^^^^^^^^^^^^^^^^
   165  
   166  Configtxgen consumes a file - ``configtx.yaml`` - that contains the definitions
   167  for the sample network. There are three members - one Orderer Org (``OrdererOrg``)
   168  and two Peer Orgs (``Org1`` & ``Org2``) each managing and maintaining two peer nodes.
   169  This file also specifies a consortium - ``SampleConsortium`` - consisting of our
   170  two Peer Orgs.  Pay specific attention to the "Profiles" section at the top of
   171  this file.  You will notice that we have two unique headers. One for the orderer genesis
   172  block - ``TwoOrgsOrdererGenesis`` - and one for our channel - ``TwoOrgsChannel``.
   173  These headers are important, as we will pass them in as arguments when we create
   174  our artifacts.  This file also contains two additional specifications that are worth
   175  noting.  Firstly, we specify the anchor peers for each Peer Org
   176  (``peer0.org1.example.com`` & ``peer0.org2.example.com``).  Secondly, we point to
   177  the location of the MSP directory for each member, in turn allowing us to store the
   178  root certificates for each Org in the orderer genesis block.  This is a critical
   179  concept. Now any network entity communicating with the ordering service can have
   180  its digital signature verified.
   181  
   182  For ease of use, a script - ``generateArtifacts.sh`` - is provided. The
   183  script will generate the crypto material and our four configuration artifacts, and
   184  subsequently output these files into the ``channel-artifacts`` folder.
   185  
   186  Run the shell script
   187  ^^^^^^^^^^^^^^^^^^^^
   188  
   189  Make sure you are in the ``examples/e2e_cli`` directory where the script resides.
   190  Decide upon a unique name for your channel and replace the <channel-ID> parm
   191  with a name of your choice.  The script will fail if you do not supply a name.
   192  
   193  .. code:: bash
   194  
   195      cd examples/e2e_cli
   196      ./generateArtifacts.sh <channel-ID>
   197  
   198  The output of the script is somewhat verbose, as it generates the crypto
   199  libraries and multiple artifacts.  However, you will notice five distinct
   200  and self-explanatory messages in your terminal.  They are as follows:
   201  
   202  .. code:: bash
   203  
   204    ##########################################################
   205    ##### Generate certificates using cryptogen tool #########
   206    ##########################################################
   207  
   208    ##########################################################
   209    #########  Generating Orderer Genesis block ##############
   210    ##########################################################
   211  
   212    #################################################################
   213    ### Generating channel configuration transaction 'channel.tx' ###
   214    #################################################################
   215  
   216    #################################################################
   217    #######    Generating anchor peer update for Org0MSP   ##########
   218    #################################################################
   219  
   220    #################################################################
   221    #######    Generating anchor peer update for Org1MSP   ##########
   222    #################################################################
   223  
   224  
   225  These configuration transactions will bundle the crypto material for the
   226  participating members and their network components and output an orderer
   227  genesis block and three channel transaction artifacts. These artifacts are
   228  required to successfully bootstrap a Fabric network and create a channel to
   229  transact upon.
   230  
   231  Manually generate the artifacts (optional)
   232  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   233  
   234  You can refer to the ``generateArtifacts.sh`` script for the commands, however
   235  for the sake of convenience we will also provide them here.
   236  
   237  First, let's set the environment variable for our platform architecture.
   238  This command will detect your OS and use the appropriate binaries for the subsequent steps:
   239  
   240  .. code:: bash
   241  
   242    # for power or z
   243    os_arch=$(echo "$(uname -s)-$(uname -m)" | awk '{print tolower($0)}')
   244  
   245    # for linux, osx or windows
   246    os_arch=$(echo "$(uname -s)-amd64" | awk '{print tolower($0)}')
   247  
   248  Check to make sure it is set properly:
   249  
   250  .. code:: bash
   251  
   252    echo $os_arch
   253  
   254  Now let's run the tool.  Our platform specific binary is in the ``release``
   255  directory, so we need to provide the relative path to where the tool resides.
   256  Make sure you are in ``examples/e2e_cli``:
   257  
   258  .. code:: bash
   259  
   260      ./../../release/$os_arch/bin/cryptogen generate --config=./crypto-config.yaml
   261  
   262  You will likely see the following warning.  It's innocuous, ignore it:
   263  
   264  .. code:: bash
   265  
   266      [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP.
   267  
   268  Next, we need to tell the ``configtxgen`` tool where to look for the
   269  ``configtx.yaml`` file that it needs to ingest.  We will tell it look in our
   270  present working directory:
   271  
   272  .. code:: bash
   273  
   274      FABRIC_CFG_PATH=$PWD
   275  
   276  Create the orderer genesis block:
   277  
   278  .. code:: bash
   279  
   280      ./../../release/$os_arch/bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
   281  
   282  You can ignore the logs regarding intermediate certs, we are not using them in
   283  this crypto implementation.
   284  
   285  Create the channel transaction artifact:
   286  
   287  .. code:: bash
   288  
   289      # make sure to set the <channel-ID> parm
   290      ./../../release/$os_arch/bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID <channel-ID>
   291  
   292  Define the anchor peer for Org1 on the channel:
   293  
   294  .. code:: bash
   295  
   296      # make sure to set the <channel-ID> parm
   297      ./../../release/$os_arch/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID <channel-ID> -asOrg Org1MSP
   298  
   299  Define the anchor peer for Org2 on the channel:
   300  
   301  .. code:: bash
   302  
   303      # make sure to set the <channel-ID> parm
   304      ./../../release/$os_arch/bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID <channel-ID> -asOrg Org2MSP
   305  
   306  Run the end-to-end test with Docker
   307  -----------------------------------
   308  
   309  Make sure you are in the ``/e2e_cli`` directory. Then use docker-compose
   310  to spawn the network entities and drive the tests.  Notice that you can set a
   311  ``TIMEOUT`` variable (specified in seconds) so that your cli container does not
   312  exit after the script completes.  You can choose any value:
   313  
   314  .. code:: bash
   315  
   316      # the TIMEOUT variable is optional
   317      CHANNEL_NAME=<channel-id> TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml up -d
   318  
   319  If you created a unique channel name, be sure to pass in that parameter.
   320  For example,
   321  
   322  .. code:: bash
   323  
   324      CHANNEL_NAME=abc TIMEOUT=1000 docker-compose -f docker-compose-cli.yaml up -d
   325  
   326  Wait, 60 seconds or so. Behind the scenes, there are transactions being sent
   327  to the peers. Execute a ``docker ps`` to view your active containers.
   328  You should see an output identical to the following:
   329  
   330  .. code:: bash
   331  
   332    CONTAINER ID        IMAGE                                 COMMAND                  CREATED             STATUS              PORTS                                              NAMES
   333    b568de3fe931        dev-peer1.org2.example.com-mycc-1.0   "chaincode -peer.a..."   4 minutes ago       Up 4 minutes                                                           dev-peer1.org2.example.com-mycc-1.0
   334    17c1c82087e7        dev-peer0.org1.example.com-mycc-1.0   "chaincode -peer.a..."   4 minutes ago       Up 4 minutes                                                           dev-peer0.org1.example.com-mycc-1.0
   335    0e1c5034c47b        dev-peer0.org2.example.com-mycc-1.0   "chaincode -peer.a..."   4 minutes ago       Up 4 minutes                                                           dev-peer0.org2.example.com-mycc-1.0
   336    71339e7e1d38        hyperledger/fabric-peer               "peer node start -..."   5 minutes ago       Up 5 minutes        0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp     peer1.org1.example.com
   337    add6113ffdcf        hyperledger/fabric-peer               "peer node start -..."   5 minutes ago       Up 5 minutes        0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp   peer1.org2.example.com
   338    689396c0e520        hyperledger/fabric-peer               "peer node start -..."   5 minutes ago       Up 5 minutes        0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp     peer0.org1.example.com
   339    65424407a653        hyperledger/fabric-orderer            "orderer"                5 minutes ago       Up 5 minutes        0.0.0.0:7050->7050/tcp                             orderer.example.com
   340    ce14853db660        hyperledger/fabric-peer               "peer node start -..."   5 minutes ago       Up 5 minutes        0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp     peer0.org2.example.com
   341  
   342  If you set a moderately high ``TIMEOUT`` value, then you will see your cli
   343  container as well.
   344  
   345  What's happening behind the scenes?
   346  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   347  
   348  -  A script - ``script.sh`` - is baked inside the CLI container. The
   349     script drives the ``createChannel`` command against the supplied channel name
   350     and uses the channel.tx file for channel configuration.
   351  
   352  -  The output of ``createChannel`` is a genesis block -
   353     ``<your_channel_name>.block`` - which gets stored on the peers' file systems and contains
   354     the channel configuration specified from channel.tx.
   355  
   356  -  The ``joinChannel`` command is exercised for all four peers, which takes as
   357     input the previously generated genesis block.  This command instructs the
   358     peers to join ``<your_channel_name>`` and create a chain starting with ``<your_channel_name>.block``.
   359  
   360  -  Now we have a channel consisting of four peers, and two
   361     organizations.  This is our ``TwoOrgsChannel`` profile.
   362  
   363  -  ``peer0.org1.example.com`` and ``peer1.org1.example.com`` belong to Org1;
   364     ``peer0.org2.example.com`` and ``peer1.org2.example.com`` belong to Org2
   365  
   366  -  These relationships are defined through the ``crypto-config.yaml`` and
   367     the MSP path is specified in our docker compose.
   368  
   369  -  The anchor peers for Org1MSP (``peer0.org1.example.com``) and
   370     Org2MSP (``peer0.org2.example.com``) are then updated.  We do this by passing
   371     the ``Org1MSPanchors.tx`` and ``Org2MSPanchors.tx`` artifacts to the ordering
   372     service along with the name of our channel.
   373  
   374  -  A chaincode - **chaincode_example02** - is installed on ``peer0.org1.example.com`` and
   375     ``peer0.org2.example.com``
   376  
   377  -  The chaincode is then "instantiated" on ``peer0.org2.example.com``. Instantiation
   378     adds the chaincode to the channel, starts the container for the target peer,
   379     and initializes the key value pairs associated with the chaincode.  The initial
   380     values for this example are ["a","100" "b","200"]. This "instantiation" results
   381     in a container by the name of ``dev-peer0.org2.example.com-mycc-1.0`` starting.
   382  
   383  -  The instantiation also passes in an argument for the endorsement
   384     policy. The policy is defined as
   385     ``-P "OR    ('Org1MSP.member','Org2MSP.member')"``, meaning that any
   386     transaction must be endorsed by a peer tied to Org1 or Org2.
   387  
   388  -  A query against the value of "a" is issued to ``peer0.org1.example.com``. The
   389     chaincode was previously installed on ``peer0.org1.example.com``, so this will start
   390     a container for Org1 peer0 by the name of ``dev-peer0.org1.example.com-mycc-1.0``. The result
   391     of the query is also returned. No write operations have occurred, so
   392     a query against "a" will still return a value of "100".
   393  
   394  -  An invoke is sent to ``peer0.org1.example.com`` to move "10" from "a" to "b"
   395  
   396  -  The chaincode is then installed on ``peer1.org2.example.com``
   397  
   398  -  A query is sent to ``peer1.org2.example.com`` for the value of "a". This starts a
   399     third chaincode container by the name of ``dev-peer1.org2.example.com-mycc-1.0``. A
   400     value of 90 is returned, correctly reflecting the previous
   401     transaction during which the value for key "a" was modified by 10.
   402  
   403  What does this demonstrate?
   404  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   405  
   406  Chaincode **MUST** be installed on a peer in order for it to
   407  successfully perform read/write operations against the ledger.
   408  Furthermore, a chaincode container is not started for a peer until an ``init`` or
   409  traditional transaction - read/write - is performed against that chaincode (e.g. query for
   410  the value of "a"). The transaction causes the container to start. Also,
   411  all peers in a channel maintain an exact copy of the ledger which
   412  comprises the blockchain to store the immutable, sequenced record in
   413  blocks, as well as a state database to maintain current fabric state.
   414  This includes those peers that do not have chaincode installed on them
   415  (like ``peer1.org1.example.com`` in the above example) . Finally, the chaincode is accessible
   416  after it is installed (like ``peer1.org2.example.com`` in the above example) because it
   417  has already been instantiated.
   418  
   419  How do I see these transactions?
   420  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   421  
   422  Check the logs for the CLI docker container.
   423  
   424  .. code:: bash
   425  
   426      docker logs -f cli
   427  
   428  You should see the following output:
   429  
   430  .. code:: bash
   431  
   432    2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP
   433    2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity
   434    2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161
   435    2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54
   436    Query Result: 90
   437    2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
   438    ===================== Query on PEER3 on channel 'mychannel' is successful =====================
   439  
   440    ===================== All GOOD, End-2-End execution completed =====================
   441  
   442  
   443     _____   _   _   ____            _____   ____    _____
   444    | ____| | \ | | |  _ \          | ____| |___ \  | ____|
   445    |  _|   |  \| | | | | |  _____  |  _|     __) | |  _|
   446    | |___  | |\  | | |_| | |_____| | |___   / __/  | |___
   447    |_____| |_| \_| |____/          |_____| |_____| |_____|
   448  
   449  How can I see the chaincode logs?
   450  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   451  
   452  Inspect the individual chaincode containers to see the separate
   453  transactions executed against each container. Here is the combined
   454  output from each container:
   455  
   456  .. code:: bash
   457  
   458      $ docker logs dev-peer0.org2.example.com-mycc-1.0
   459      04:30:45.947 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
   460      ex02 Init
   461      Aval = 100, Bval = 200
   462  
   463      $ docker logs dev-peer0.org1.example.com-mycc-1.0
   464      04:31:10.569 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
   465      ex02 Invoke
   466      Query Response:{"Name":"a","Amount":"100"}
   467      ex02 Invoke
   468      Aval = 90, Bval = 210
   469  
   470      $ docker logs dev-peer1.org2.example.com-mycc-1.0
   471      04:31:30.420 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
   472      ex02 Invoke
   473      Query Response:{"Name":"a","Amount":"90"}
   474  
   475  All in one
   476  ^^^^^^^^^^
   477  
   478  You can also generate the artifacts and crypto, and drive the tests using a single
   479  shell script. The ``cryptogen``, ``configtxgen`` and ``docker-compose`` commands are
   480  embedded in the script.  If you choose not to supply a channel ID, then the
   481  script will use a default name of ``mychannel``.  The cli timeout parameter
   482  is an optional value; if you choose not to set it, then your cli container
   483  will exit upon conclusion of the script.
   484  
   485  .. code:: bash
   486  
   487          ./network_setup.sh up
   488  
   489  OR
   490  
   491  .. code:: bash
   492  
   493          ./network_setup.sh up <channel-ID> <timeout-value>
   494  
   495  Understanding the docker-compose topology
   496  -----------------------------------------
   497  
   498  The ``e2e_cli`` folder offers us two flavors of docker-compose files, both of which
   499  are extended from the ``docker-compose-base.yaml``.  Our first flavor,
   500  ``docker-compose-cli.yaml``, provides us with a CLI container, along with an orderer,
   501  four peers, and the optional couchDB containers.  We use this docker-compose for
   502  the entirety of the instructions on this page.
   503  
   504  The second flavor, ``docker-compose-e2e.yaml``, is constructed to run end-to-end tests
   505  using the Node.js SDK.  Aside from functioning with the SDK, its primary differentiation
   506  is that there are containers for the fabric-ca servers.  As a result, we are able
   507  to send REST calls to the organizational CAs for user registration and enrollment.
   508  
   509  If you want to use the ``docker-compose-e2e.yaml`` without first running the
   510  **All in one** script, then we  will need to make four slight modifications.
   511  We need to point to the private keys for our Organization's CA's.  You can locate
   512  these values in your crypto-config folder.  For example, to locate the private
   513  key for Org1 we would follow this path - ``crypto-config/peerOrganizations/org1.example.com/ca/``.
   514  The private key is a long hash value followed by ``_sk``.  The path for Org2
   515  would be - ``crypto-config/peerOrganizations/org2.example.com/ca/``.
   516  
   517  In the ``docker-compose-e2e.yaml`` update the FABRIC_CA_SERVER_TLS_KEYFILE variable
   518  for ca0 and ca1.  You also need to edit the path that is provided in the command
   519  to start the ca server.  You are providing the same private key twice for each
   520  CA container.
   521  
   522  Manually exercise the commands
   523  ------------------------------
   524  
   525  Exit the currently-running containers:
   526  
   527  .. code:: bash
   528  
   529      docker rm -f $(docker ps -aq)
   530  
   531  Execute a ``docker images`` command in your terminal to view the
   532  chaincode images. They will look similar to the following:
   533  
   534  .. code:: bash
   535  
   536    REPOSITORY                            TAG                              IMAGE ID            CREATED             SIZE
   537    dev-peer1.org2.example.com-mycc-1.0   latest                           4bc5e9b5dd97        5 seconds ago       176 MB
   538    dev-peer0.org1.example.com-mycc-1.0   latest                           6f2aeb032076        22 seconds ago      176 MB
   539    dev-peer0.org2.example.com-mycc-1.0   latest                           509b8e393cc6        39 seconds ago      176 MB
   540  
   541  Remove these images:
   542  
   543  .. code:: bash
   544  
   545      docker rmi <IMAGE ID> <IMAGE ID> <IMAGE ID>
   546  
   547  For example:
   548  
   549  .. code:: bash
   550  
   551      docker rmi -f 4bc 6f2 509
   552  
   553  Ensure you have the configuration artifacts. If you deleted them, run
   554  the shell script again:
   555  
   556  .. code:: bash
   557  
   558      # remember to supply a channel ID
   559      ./generateArtifacts.sh <channel-ID>
   560  
   561  Modify the docker-compose file
   562  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   563  
   564  Open the ``docker-compose-cli.yaml`` file and comment out the command to run
   565  ``script.sh``. Navigate down to the cli container and place a ``#`` to the
   566  left of the command. For example:
   567  
   568  .. code:: bash
   569  
   570          working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
   571        # command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
   572  
   573  Save the file and return to the ``/e2e_cli`` directory.
   574  
   575  Now restart your network:
   576  
   577  .. code:: bash
   578  
   579      # make sure you are in the /e2e_cli directory where your docker-compose script resides
   580      CHANNEL_NAME=<channel-id> TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml up -d
   581  
   582  If you want to see the realtime logs for your network, then do not supply the ``-d`` flag.
   583  If you let the logs stream, then you will need to open a second terminal to execute the CLI calls.
   584  
   585  Command syntax
   586  ^^^^^^^^^^^^^^
   587  
   588  Refer to the create and join commands in the ``script.sh`` for the exact syntax.
   589  
   590  For the following CLI commands against `peer0.org1.example.com` to work, we need
   591  to preface our commands with the four environment variables given below.  These
   592  variables for ``peer0.org1.example.com`` are baked into the CLI container,
   593  therefore we can operate without passing them.  **HOWEVER**, if you want to send
   594  calls to other peers or the orderer, then you will need to provide these
   595  values accordingly.  Inspect the ``docker-compose-base.yaml`` for the specific
   596  paths:
   597  
   598  .. code:: bash
   599  
   600      # Environment variables for PEER0
   601  
   602      CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
   603      CORE_PEER_ADDRESS=peer0.org1.example.com:7051
   604      CORE_PEER_LOCALMSPID="Org1MSP"
   605      CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
   606  
   607  Create channel
   608  ^^^^^^^^^^^^^^
   609  
   610  Exec into the cli container:
   611  
   612  .. code:: bash
   613  
   614      docker exec -it cli bash
   615  
   616  If successful you should see the following:
   617  
   618  .. code:: bash
   619  
   620      root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
   621  
   622  Specify your channel name with the ``-c`` flag. Specify your channel
   623  configuration transaction with the ``-f`` flag. In this case it is
   624  ``channel.tx``, however you can mount your own configuration transaction
   625  with a different name.
   626  
   627  .. code:: bash
   628  
   629      # the channel.tx file is mounted in the channel-artifacts directory within your cli container
   630      # as a result, we pass the full path for the file
   631      # we also pass the path for the orderer ca-cert in order to verify the TLS handshake
   632      # be sure to replace the $CHANNEL_NAME variable appropriately
   633  
   634      peer channel create -o orderer.example.com:7050 -c $CHANNEL_NAME -f ./channel-artifacts/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem
   635  
   636  
   637  .. note:: You will remain in the CLI container for the remainder of
   638            these manual commands. You must also remember to preface all commands
   639            with the corresponding environment variables when targeting a peer other than
   640            ``peer0.org1.example.com``.
   641  
   642  Join channel
   643  ^^^^^^^^^^^^
   644  
   645  Join specific peers to the channel
   646  
   647  .. code:: bash
   648  
   649      # By default, this joins ``peer0.org1.example.com`` only
   650      # the channel.block was returned by the previous command
   651  
   652       peer channel join -b <YOUR_CHANNEL.block>
   653  
   654  You can make other peers join the channel as necessary by making appropriate
   655  changes in the four environment variables.
   656  
   657  Install chaincode onto a remote peer
   658  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   659  
   660  Install the sample go code onto one of the four peer nodes
   661  
   662  .. code:: bash
   663  
   664      peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
   665  
   666  Instantiate chaincode and define the endorsement policy
   667  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   668  
   669  Instantiate the chaincode on a peer. This will launch a chaincode
   670  container for the targeted peer and set the endorsement policy for the
   671  chaincode. In this snippet, we define the policy as requiring an
   672  endorsement from one peer node that is a part of either ``Org1`` or ``Org2``.
   673  The command is:
   674  
   675  .. code:: bash
   676  
   677      # be sure to replace the $CHANNEL_NAME environment variable
   678      # if you did not install your chaincode with a name of mycc, then modify that argument as well
   679  
   680      peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
   681  
   682  See the `endorsement
   683  policies <http://hyperledger-fabric.readthedocs.io/en/latest/endorsement-policies.html>`__
   684  documentation for more details on policy implementation.
   685  
   686  Invoke chaincode
   687  ^^^^^^^^^^^^^^^^
   688  
   689  .. code:: bash
   690  
   691      # be sure to set the -C and -n flags appropriately
   692      peer chaincode invoke -o orderer.example.com:7050  --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem  -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'
   693  
   694  Make sure to wait a few seconds for the operation to complete.
   695  
   696  Query chaincode
   697  ^^^^^^^^^^^^^^^
   698  
   699  .. code:: bash
   700  
   701      # be sure to set the -C and -n flags appropriately
   702      peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
   703  
   704  The result of the above command should be the following:
   705  
   706  .. code:: bash
   707  
   708      Query Result: 90
   709  
   710  Feel free to start over and manipulate the key value pairs and subsequent
   711  invocations.
   712  
   713  Using CouchDB
   714  -------------
   715  
   716  The state database can be switched from the default (goleveldb) to CouchDB.
   717  The same chaincode functions are available with CouchDB, however, there is the
   718  added ability to perform rich and complex queries against the state database
   719  data content contingent upon the chaincode data being modeled as JSON.
   720  
   721  To use CouchDB instead of the default database (goleveldb), follow the same
   722  procedure in the **Manually exercise the commands** section, except when starting
   723  the network pass the couchdb docker-compose as well:
   724  
   725  .. code:: bash
   726  
   727      # make sure you are in the /e2e_cli directory where your docker-compose script resides
   728      CHANNEL_NAME=<channel-id> TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d
   729  
   730  **chaincode_example02** should now work using CouchDB underneath.
   731  
   732  .. note::  If you choose to implement mapping of the fabric-couchdb container
   733             port to a host port, please make sure you are aware of the security
   734             implications. Mapping of the port in a development environment makes the
   735             CouchDB REST API available, and allows the
   736             visualization of the database via the CouchDB web interface (Fauxton).
   737             Production environments would likely refrain from implementing port mapping in
   738             order to restrict outside access to the CouchDB containers.
   739  
   740  You can use **chaincode_example02** chaincode against the CouchDB state database
   741  using the steps outlined above, however in order to exercise the CouchDB query
   742  capabilities you will need to use a chaincode that has data modeled as JSON,
   743  (e.g. **marbles02**). You can locate the **marbles02** chaincode in the
   744  ``fabric/examples/chaincode/go`` directory.
   745  
   746  We will follow the same process to create and join the channel as outlined in the
   747  **Manually exercise the commands** section above.  Once you have joined your
   748  peer(s) to the channel, use the following steps to interact with the **marbles02**
   749  chaincode:
   750  
   751  -  Install and instantiate the chaincode on ``peer0.org1.example.com``:
   752  
   753  .. code:: bash
   754  
   755         # be sure to modify the $CHANNEL_NAME variable accordingly for the instantiate command
   756  
   757         peer chaincode install -o orderer.example.com:7050 -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02
   758         peer chaincode instantiate -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02 -c '{"Args":["init"]}' -P "OR ('Org0MSP.member','Org1MSP.member')"
   759  
   760  -  Create some marbles and move them around:
   761  
   762  .. code:: bash
   763  
   764          # be sure to modify the $CHANNEL_NAME variable accordingly
   765  
   766          peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
   767          peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
   768          peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
   769          peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
   770          peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'
   771          peer chaincode invoke -o orderer.example.com:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/cacerts/ca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["delete","marble1"]}'
   772  
   773  
   774  -  If you chose to map the CouchDB ports in docker-compose, you can now view
   775     the state database through the CouchDB web interface (Fauxton) by opening
   776     a browser and navigating to the following URL:
   777  
   778     ``http://localhost:5984/_utils``
   779  
   780  You should see a database named ``mychannel`` (or your unique channel name) and
   781  the documents inside it.
   782  
   783  .. note:: For the below commands, be sure to update the $CHANNEL_NAME variable appropriately.
   784  
   785  You can run regular queries from the CLI (e.g. reading ``marble2``):
   786  
   787  .. code:: bash
   788  
   789        peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["readMarble","marble2"]}'
   790  
   791  The output should display the details of ``marble2``:
   792  
   793  .. code:: bash
   794  
   795         Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}
   796  
   797  You can retrieve the history of a specific marble - e.g. ``marble1``:
   798  
   799  .. code:: bash
   800  
   801        peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'
   802  
   803  The output should display the transactions on ``marble1``:
   804  
   805  .. code:: bash
   806  
   807        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":}]
   808  
   809  You can also perform rich queries on the data content, such as querying marble fields by owner ``jerry``:
   810  
   811  .. code:: bash
   812  
   813        peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}'
   814  
   815  The output should display the two marbles owned by ``jerry``:
   816  
   817  .. code:: bash
   818  
   819         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}}]
   820  
   821  A Note on Data Persistence
   822  --------------------------
   823  
   824  If data persistence is desired on the peer container or the CouchDB container,
   825  one option is to mount a directory in the docker-host into a relevant directory
   826  in the container. For example, you may add the following two lines in
   827  the peer container specification in the ``docker-compose-base.yaml`` file:
   828  
   829  .. code:: bash
   830  
   831         volumes:
   832          - /var/hyperledger/peer0:/var/hyperledger/production
   833  
   834  
   835  For the CouchDB container, you may add the following two lines in the CouchDB
   836  container specification:
   837  
   838  .. code:: bash
   839  
   840         volumes:
   841          - /var/hyperledger/couchdb0:/opt/couchdb/data
   842  
   843  Troubleshooting
   844  ---------------
   845  
   846  -  It's recommended to start your network fresh.  Use the following command
   847     to remove artifacts, crypto, containers and chaincode images:
   848  
   849  .. code:: bash
   850  
   851        ./network_setup.sh down
   852  
   853  -  If you see docker errors, first check your version (should be 1.12 or above),
   854     and then try restarting your docker process.  Problems with Docker are
   855     oftentimes not immediately recognizable.  For example, you may see errors
   856     resulting from an inability to access crypto material mounted within a
   857     container.
   858  
   859  -  If they persist remove your images and start from scratch:
   860  
   861  .. code:: bash
   862  
   863         make clean
   864         make docker
   865  
   866  -  If you see the below error:
   867  
   868  .. code:: bash
   869  
   870         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)
   871  
   872  You likely have chaincode images (e.g. ``dev-peer1.org2.example.com-mycc-1.0`` or
   873  ``dev-peer0.org1.example.com-mycc-1.0``) from prior runs. Remove them and try
   874  again.
   875  
   876  .. code:: bash
   877  
   878      docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}')
   879  
   880  - If you see something similar to the following:
   881  
   882  .. code:: bash
   883  
   884        Error connecting: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure
   885        Error: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure
   886  
   887  Make sure you pointed to the correct binaries in the release folder when
   888  generating the artifacts, and that your backend is running against "beta" images
   889  or compiled images from the current master branch.
   890  
   891  If you see the below error:
   892  
   893  .. code:: bash
   894  
   895    [configtx/tool/localconfig] Load -> CRIT 002 Error reading configuration: Unsupported Config Type ""
   896    panic: Error reading configuration: Unsupported Config Type ""
   897  
   898  Then you did not set the ``FABRIC_CFG_PATH`` environment variable properly.  The
   899  configtxgen tool needs this variable in order to locate the configtx.yaml.  Go
   900  back and recreate your channel artifacts.
   901  
   902  -  To cleanup the network, use the ``down`` option:
   903  
   904  .. code:: bash
   905  
   906         ./network_setup.sh down
   907  
   908  - If you continue to see errors, share your logs on the **# fabric-questions**
   909    channel on `Hyperledger Rocket Chat <https://chat.hyperledger.org/home>`__.
   910  
   911  .. Licensed under Creative Commons Attribution 4.0 International License
   912     https://creativecommons.org/licenses/by/4.0/
   913