github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/docs/source/build_network.rst (about)

     1  Building Your First Network
     2  ===========================
     3  
     4  .. note:: These instructions have been verified to work against the
     5            version "1.0.0" tagged Docker images and the pre-compiled
     6            setup utilities within the supplied tar file. If you run
     7            these commands with images or tools from the current master
     8            branch, it is possible that you will see configuration and panic
     9            errors.
    10  
    11  The build your first network (BYFN) scenario provisions a sample Hyperledger
    12  Fabric network consisting of two organizations, each maintaining two peer
    13  nodes, and a "solo" ordering service.
    14  
    15  Install prerequisites
    16  ---------------------
    17  
    18  Before we begin, if you haven't already done so, you may wish to check that
    19  you have all the :doc:`prereqs` installed on the platform(s)
    20  on which you'll be developing blockchain applications and/or operating
    21  Hyperledger Fabric.
    22  
    23  You will also need to download and install the :doc:`samples`. You will notice
    24  that there are a number of samples included in the ``fabric-samples``
    25  repository. We will be using the ``first-network`` sample. Let's open that
    26  sub-directory now.
    27  
    28  .. code:: bash
    29  
    30    cd first-network
    31  
    32  .. note:: The supplied commands in this documentation
    33            **MUST** be run from your ``first-network`` sub-directory
    34            of the ``fabric-samples`` repository clone.  If you elect to run the
    35            commands from a different location, the various provided scripts
    36            will be unable to find the binaries.
    37  
    38  Want to run it now?
    39  -------------------
    40  
    41  We provide a fully annotated script - ``byfn.sh`` - that leverages these Docker
    42  images to quickly bootstrap a Hyperledger Fabric network comprised of 4 peers
    43  representing two different organizations, and an orderer node. It will also
    44  launch a container to run a scripted execution that will join peers to a
    45  channel, deploy and instantiate chaincode and drive execution of transactions
    46  against the deployed chaincode.
    47  
    48  Here's the help text for the ``byfn.sh`` script:
    49  
    50  .. code:: bash
    51  
    52    ./byfn.sh -h
    53    Usage:
    54      byfn.sh -m up|down|restart|generate [-c <channel name>] [-t <timeout>]
    55      byfn.sh -h|--help (print this message)
    56        -m <mode> - one of 'up', 'down', 'restart' or 'generate'
    57          - 'up' - bring up the network with docker-compose up
    58          - 'down' - clear the network with docker-compose down
    59          - 'restart' - restart the network
    60          - 'generate' - generate required certificates and genesis block
    61        -c <channel name> - config name to use (defaults to "mychannel")
    62        -t <timeout> - CLI timeout duration in microseconds (defaults to 10000)
    63  
    64    Typically, one would first generate the required certificates and
    65    genesis block, then bring up the network. e.g.:
    66  
    67      byfn.sh -m generate -c <channelname>
    68      byfn.sh -m up -c <channelname>
    69  
    70  If you choose not to supply a channel name, then the
    71  script will use a default name of ``mychannel``.  The CLI timeout parameter
    72  (specified with the -t flag) is an optional value; if you choose not to set
    73  it, then your CLI container will exit upon conclusion of the script.
    74  
    75  Generate Network Artifacts
    76  ^^^^^^^^^^^^^^^^^^^^^^^^^^
    77  
    78  Ready to give it a go? Okay then! Execute the following command:
    79  
    80  .. code:: bash
    81  
    82    ./byfn.sh -m generate
    83  
    84  You will see a brief description as to what will occur, along with a yes/no command line
    85  prompt. Respond with a ``y`` to execute the described action.
    86  
    87  .. code:: bash
    88  
    89    Generating certs and genesis block for with channel 'mychannel' and CLI timeout of '10000'
    90    Continue (y/n)?y
    91    proceeding ...
    92    /Users/xxx/dev/fabric-samples/bin/cryptogen
    93  
    94    ##########################################################
    95    ##### Generate certificates using cryptogen tool #########
    96    ##########################################################
    97    org1.example.com
    98    2017-06-12 21:01:37.334 EDT [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP.
    99    ...
   100  
   101    /Users/xxx/dev/fabric-samples/bin/configtxgen
   102    ##########################################################
   103    #########  Generating Orderer Genesis block ##############
   104    ##########################################################
   105    2017-06-12 21:01:37.558 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
   106    2017-06-12 21:01:37.562 EDT [msp] getMspConfig -> INFO 002 intermediate certs folder not found at [/Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts]. Skipping.: [stat /Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts: no such file or directory]
   107    ...
   108    2017-06-12 21:01:37.588 EDT [common/configtx/tool] doOutputBlock -> INFO 00b Generating genesis block
   109    2017-06-12 21:01:37.590 EDT [common/configtx/tool] doOutputBlock -> INFO 00c Writing genesis block
   110  
   111    #################################################################
   112    ### Generating channel configuration transaction 'channel.tx' ###
   113    #################################################################
   114    2017-06-12 21:01:37.634 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
   115    2017-06-12 21:01:37.644 EDT [common/configtx/tool] doOutputChannelCreateTx -> INFO 002 Generating new channel configtx
   116    2017-06-12 21:01:37.645 EDT [common/configtx/tool] doOutputChannelCreateTx -> INFO 003 Writing new channel tx
   117  
   118    #################################################################
   119    #######    Generating anchor peer update for Org1MSP   ##########
   120    #################################################################
   121    2017-06-12 21:01:37.674 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
   122    2017-06-12 21:01:37.678 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
   123    2017-06-12 21:01:37.679 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update
   124  
   125    #################################################################
   126    #######    Generating anchor peer update for Org2MSP   ##########
   127    #################################################################
   128    2017-06-12 21:01:37.700 EDT [common/configtx/tool] main -> INFO 001 Loading configuration
   129    2017-06-12 21:01:37.704 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 002 Generating anchor peer update
   130    2017-06-12 21:01:37.704 EDT [common/configtx/tool] doOutputAnchorPeersUpdate -> INFO 003 Writing anchor peer update
   131  
   132  This first step generates all of the certificates and keys for all our various
   133  network entities, the ``genesis block`` used to bootstrap the ordering service,
   134  and a collection of configuration transactions required to configure a
   135  :ref:`Channel`.
   136  
   137  Bring Up the Network
   138  ^^^^^^^^^^^^^^^^^^^^
   139  
   140  Next, you can bring the network up with the following command:
   141  
   142  .. code:: bash
   143  
   144    ./byfn.sh -m up
   145  
   146  Once again, you will be prompted as to whether you wish to continue or abort.
   147  Respond with a ``y``:
   148  
   149  .. code:: bash
   150  
   151    Starting with channel 'mychannel' and CLI timeout of '10000'
   152    Continue (y/n)?y
   153    proceeding ...
   154    Creating network "net_byfn" with the default driver
   155    Creating peer0.org1.example.com
   156    Creating peer1.org1.example.com
   157    Creating peer0.org2.example.com
   158    Creating orderer.example.com
   159    Creating peer1.org2.example.com
   160    Creating cli
   161  
   162  
   163     ____    _____      _      ____    _____
   164    / ___|  |_   _|    / \    |  _ \  |_   _|
   165    \___ \    | |     / _ \   | |_) |   | |
   166     ___) |   | |    / ___ \  |  _ <    | |
   167    |____/    |_|   /_/   \_\ |_| \_\   |_|
   168  
   169    Channel name : mychannel
   170    Creating channel...
   171  
   172  The logs will continue from there. This will launch all of the containers, and
   173  then drive a complete end-to-end application scenario. Upon successful
   174  completion, it should report the following in your terminal window:
   175  
   176  .. code:: bash
   177  
   178      2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP
   179      2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity
   180      2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161
   181      2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54
   182      Query Result: 90
   183      2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
   184      ===================== Query on PEER3 on channel 'mychannel' is successful =====================
   185  
   186      ===================== All GOOD, BYFN execution completed =====================
   187  
   188  
   189       _____   _   _   ____
   190      | ____| | \ | | |  _ \
   191      |  _|   |  \| | | | | |
   192      | |___  | |\  | | |_| |
   193      |_____| |_| \_| |____/
   194  
   195  You can scroll through these logs to see the various transactions. If you don't
   196  get this result, then jump down to the :ref:`Troubleshoot` section and let's see
   197  whether we can help you discover what went wrong.
   198  
   199  Bring Down the Network
   200  ^^^^^^^^^^^^^^^^^^^^^^
   201  
   202  Finally, let's bring it all down so we can explore the network setup one step
   203  at a time. The following will kill your containers, remove the crypto material
   204  and four artifacts, and delete the chaincode images from your Docker Registry:
   205  
   206  .. code:: bash
   207  
   208    ./byfn.sh -m down
   209  
   210  Once again, you will be prompted to continue, respond with a ``y``:
   211  
   212  .. code:: bash
   213  
   214    Stopping with channel 'mychannel' and CLI timeout of '10000'
   215    Continue (y/n)?y
   216    proceeding ...
   217    WARNING: The CHANNEL_NAME variable is not set. Defaulting to a blank string.
   218    WARNING: The TIMEOUT variable is not set. Defaulting to a blank string.
   219    Removing network net_byfn
   220    468aaa6201ed
   221    ...
   222    Untagged: dev-peer1.org2.example.com-mycc-1.0:latest
   223    Deleted: sha256:ed3230614e64e1c83e510c0c282e982d2b06d148b1c498bbdcc429e2b2531e91
   224    ...
   225  
   226  If you'd like to learn more about the underlying tooling and bootstrap mechanics,
   227  continue reading.  In these next sections we'll walk through the various steps
   228  and requirements to build a fully-functional Hyperledger Fabric network.
   229  
   230  Crypto Generator
   231  ----------------
   232  
   233  We will use the ``cryptogen`` tool to generate the cryptographic material
   234  (x509 certs) for our various network entities.  These certificates are
   235  representative of identities, and they allow for sign/verify authentication to
   236  take place as our entities communicate and transact.
   237  
   238  How does it work?
   239  ^^^^^^^^^^^^^^^^^
   240  
   241  Cryptogen consumes a file - ``crypto-config.yaml`` - that contains the network
   242  topology and allows us to generate a set of certificates and keys for both the
   243  Organizations and the components that belong to those Organizations.  Each
   244  Organization is provisioned a unique root certificate (``ca-cert``) that binds
   245  specific components (peers and orderers) to that Org.  By assigning each
   246  Organization a unique CA certificate, we are mimicking a typical network where
   247  a participating :ref:`Member` would use its own Certificate Authority.
   248  Transactions and communications within Hyperledger Fabric are signed by an
   249  entity's private key (``keystore``), and then verified by means of a public
   250  key (``signcerts``).
   251  
   252  You will notice a ``count`` variable within this file.  We use this to specify
   253  the number of peers per Organization; in our case there are two peers per Org.
   254  We won't delve into the minutiae of `x.509 certificates and public key
   255  infrastructure <https://en.wikipedia.org/wiki/Public_key_infrastructure>`__
   256  right now. If you're interested, you can peruse these topics on your own time.
   257  
   258  Before running the tool, let's take a quick look at a snippet from the
   259  ``crypto-config.yaml``. Pay specific attention to the "Name", "Domain"
   260  and "Specs" parameters under the ``OrdererOrgs`` header:
   261  
   262  .. code:: bash
   263  
   264    OrdererOrgs:
   265    #---------------------------------------------------------
   266    # Orderer
   267    # --------------------------------------------------------
   268    - Name: Orderer
   269      Domain: example.com
   270      # ------------------------------------------------------
   271      # "Specs" - See PeerOrgs below for complete description
   272    # -----------------------------------------------------
   273      Specs:
   274        - Hostname: orderer
   275    # -------------------------------------------------------
   276    # "PeerOrgs" - Definition of organizations managing peer nodes
   277    # ------------------------------------------------------
   278    PeerOrgs:
   279    # -----------------------------------------------------
   280    # Org1
   281    # ----------------------------------------------------
   282    - Name: Org1
   283      Domain: org1.example.com
   284  
   285  The naming convention for a network entity is as follows -
   286  "{{.Hostname}}.{{.Domain}}".  So using our ordering node as a
   287  reference point, we are left with an ordering node named -
   288  ``orderer.example.com`` that is tied to an MSP ID of ``Orderer``.  This file
   289  contains extensive documentation on the definitions and syntax.  You can also
   290  refer to the :doc:`msp` documentation for a deeper dive on MSP.
   291  
   292  After we run the ``cryptogen`` tool, the generated certificates and keys will be
   293  saved to a folder titled ``crypto-config``.
   294  
   295  Configuration Transaction Generator
   296  -----------------------------------
   297  
   298  The ``configtxgen tool`` is used to create four configuration artifacts:
   299  
   300    * orderer ``genesis block``,
   301    * channel ``channel configuration transaction``,
   302    * and two ``anchor peer transactions`` - one for each Peer Org.
   303  
   304  Please see :doc:`configtxgen` for a complete description of the use of this
   305  tool.
   306  
   307  The orderer block is the :ref:`Genesis-Block` for the ordering service, and the
   308  channel transaction file is broadcast to the orderer at :ref:`Channel` creation
   309  time.  The anchor peer transactions, as the name might suggest, specify each
   310  Org's :ref:`Anchor-Peer` on this channel.
   311  
   312  How does it work?
   313  ^^^^^^^^^^^^^^^^^
   314  
   315  Configtxgen consumes a file - ``configtx.yaml`` - that contains the definitions
   316  for the sample network. There are three members - one Orderer Org (``OrdererOrg``)
   317  and two Peer Orgs (``Org1`` & ``Org2``) each managing and maintaining two peer nodes.
   318  This file also specifies a consortium - ``SampleConsortium`` - consisting of our
   319  two Peer Orgs.  Pay specific attention to the "Profiles" section at the top of
   320  this file.  You will notice that we have two unique headers. One for the orderer genesis
   321  block - ``TwoOrgsOrdererGenesis`` - and one for our channel - ``TwoOrgsChannel``.
   322  
   323  These headers are important, as we will pass them in as arguments when we create
   324  our artifacts.
   325  
   326  .. note:: Notice that our ``SampleConsortium`` is defined in
   327            the system-level profile and then referenced by
   328            our channel-level profile.  Channels exist within
   329            the purview of a consortium, and all consortia
   330            must be defined in the scope of the network at
   331            large.
   332  
   333  This file also contains two additional specifications that are worth
   334  noting. Firstly, we specify the anchor peers for each Peer Org
   335  (``peer0.org1.example.com`` & ``peer0.org2.example.com``).  Secondly, we point to
   336  the location of the MSP directory for each member, in turn allowing us to store the
   337  root certificates for each Org in the orderer genesis block.  This is a critical
   338  concept. Now any network entity communicating with the ordering service can have
   339  its digital signature verified.
   340  
   341  Run the tools
   342  -------------
   343  
   344  You can manually generate the certificates/keys and the various configuration
   345  artifacts using the ``configtxgen`` and ``cryptogen`` commands. Alternately,
   346  you could try to adapt the byfn.sh script to accomplish your objectives.
   347  
   348  Manually generate the artifacts
   349  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   350  
   351  You can refer to the ``generateCerts`` function in the byfn.sh script for the
   352  commands necessary to generate the certificates that will be used for your
   353  network configuration as defined in the ``crypto-config.yaml`` file. However,
   354  for the sake of convenience, we will also provide a reference here.
   355  
   356  First let's run the ``cryptogen`` tool.  Our binary is in the ``bin``
   357  directory, so we need to provide the relative path to where the tool resides.
   358  
   359  .. code:: bash
   360  
   361      ../bin/cryptogen generate --config=./crypto-config.yaml
   362  
   363  You will likely see the following warning.  It's innocuous, ignore it:
   364  
   365  .. code:: bash
   366  
   367      [bccsp] GetDefault -> WARN 001 Before using BCCSP, please call InitFactories(). Falling back to bootBCCSP.
   368  
   369  Next, we need to tell the ``configtxgen`` tool where to look for the
   370  ``configtx.yaml`` file that it needs to ingest.  We will tell it look in our
   371  present working directory:
   372  
   373  First, we need to set an environment variable to specify where ``configtxgen``
   374  should look for the configtx.yaml configuration file:
   375  
   376  .. code:: bash
   377  
   378      export FABRIC_CFG_PATH=$PWD
   379  
   380  Then, we'll invoke the ``configtxgen`` tool which will create the orderer genesis block:
   381  
   382  .. code:: bash
   383  
   384      ../bin/configtxgen -profile TwoOrgsOrdererGenesis -outputBlock ./channel-artifacts/genesis.block
   385  
   386  You can ignore the log warnings regarding intermediate certificates, certificate
   387  revocation lists (crls) and MSP configurations. We are not using any of those
   388  in this sample network.
   389  
   390  .. code: bash
   391  
   392    2017-06-12 21:01:37.562 EDT [msp] getMspConfig -> INFO 002 intermediate certs folder not found at [/Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts]. Skipping.: [stat /Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts: no such file or directory]
   393    2017-06-12 21:01:37.562 EDT [msp] getMspConfig -> INFO 003 crls folder not found at [/Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/intermediatecerts]. Skipping.: [stat /Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/crls: no such file or directory]
   394    2017-06-12 21:01:37.562 EDT [msp] getMspConfig -> INFO 004 MSP configuration file not found at [/Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/config.yaml]: [stat /Users/xxx/dev/byfn/crypto-config/ordererOrganizations/example.com/msp/config.yaml: no such file or directory]
   395  
   396  Next, we need to create the channel transaction artifact. Be sure to replace $CHANNEL_NAME or
   397  set CHANNEL_NAME as an environment variable that can be used throughout these instructions:
   398  
   399  .. code:: bash
   400  
   401      export CHANNEL_NAME=mychannel
   402  
   403      # this file contains the definitions for our sample channel
   404      ../bin/configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ./channel-artifacts/channel.tx -channelID $CHANNEL_NAME
   405  
   406  Next, we will define the anchor peer for Org1 on the channel that we are
   407  constructing. Again, be sure to replace $CHANNEL_NAME or set the environment variable
   408  for the following commands:
   409  
   410  .. code:: bash
   411  
   412      ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org1MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org1MSP
   413  
   414  Now, we will define the anchor peer for Org2 on the same channel:
   415  
   416  .. code:: bash
   417  
   418      ../bin/configtxgen -profile TwoOrgsChannel -outputAnchorPeersUpdate ./channel-artifacts/Org2MSPanchors.tx -channelID $CHANNEL_NAME -asOrg Org2MSP
   419  
   420  Start the network
   421  -----------------
   422  
   423  We will leverage a docker-compose script to spin up our network. The
   424  docker-compose file references the images that we have previously downloaded,
   425  and bootstraps the orderer with our previously generated ``genesis.block``.
   426  
   427  .. note: Before launching the network, open the ``docker-compose-cli.yaml`` file
   428           and comment out the script.sh in the CLI container. Your docker-compose
   429           should be modified to look like this:
   430  
   431  .. code:: bash
   432  
   433    working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
   434    # command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT'
   435    volumes
   436  
   437  If left uncommented, that script will exercise all of the CLI commands when the
   438  network is started, as we describe in the :ref:`behind-scenes` section.
   439  However, we want to go through the commands manually in order
   440  to expose the syntax and functionality of each call.
   441  
   442  Pass in a moderately high value for the ``TIMEOUT`` variable (specified in seconds);
   443  otherwise the CLI container, by default, will exit after 60 seconds.
   444  
   445  Start your network:
   446  
   447  .. code:: bash
   448  
   449            CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml up -d
   450  
   451  If you want to see the realtime logs for your network, then do not supply the ``-d`` flag.
   452  If you let the logs stream, then you will need to open a second terminal to execute the CLI calls.
   453  
   454  Environment variables
   455  ^^^^^^^^^^^^^^^^^^^^^
   456  
   457  For the following CLI commands against ``peer0.org1.example.com`` to work, we need
   458  to preface our commands with the four environment variables given below.  These
   459  variables for ``peer0.org1.example.com`` are baked into the CLI container,
   460  therefore we can operate without passing them.  **HOWEVER**, if you want to send
   461  calls to other peers or the orderer, then you will need to provide these
   462  values accordingly.  Inspect the ``docker-compose-base.yaml`` for the specific
   463  paths:
   464  
   465  .. code:: bash
   466  
   467      # Environment variables for PEER0
   468  
   469      CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
   470      CORE_PEER_ADDRESS=peer0.org1.example.com:7051
   471      CORE_PEER_LOCALMSPID="Org1MSP"
   472      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
   473  
   474  .. _createandjoin:
   475  
   476  Create & Join Channel
   477  ^^^^^^^^^^^^^^^^^^^^^
   478  
   479  We will enter the CLI container using the ``docker exec`` command:
   480  
   481  .. code:: bash
   482  
   483          docker exec -it cli bash
   484  
   485  If successful you should see the following:
   486  
   487  .. code:: bash
   488  
   489          root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
   490  
   491  Recall that we used the configtxgen tool to generate a channel configuration
   492  artifact - ``channel.tx``. We are going to pass in this artifact to the orderer
   493  as part of the create channel request.
   494  
   495  .. note:: Notice the ``-- cafile`` that we pass as part of this command.  It is
   496            the local path to the orderer's root cert, allowing us to verify the
   497            TLS handshake.
   498  
   499  We specify our channel name with the ``-c`` flag and our channel configuration
   500  transaction with the ``-f`` flag. In this case it is ``channel.tx``, however
   501  you can mount your own configuration transaction with a different name.
   502  
   503  .. code:: bash
   504  
   505          export CHANNEL_NAME=mychannel
   506  
   507          # the channel.tx file is mounted in the channel-artifacts directory within your CLI container
   508          # as a result, we pass the full path for the file
   509          # we also pass the path for the orderer ca-cert in order to verify the TLS handshake
   510          # be sure to replace the $CHANNEL_NAME variable appropriately
   511  
   512          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/tlscacerts/tlsca.example.com-cert.pem
   513  
   514  This command returns a genesis block - ``<channel-ID.block>`` - which we will use to join the channel.
   515  It contains the configuration information specified in ``channel.tx``.
   516  
   517  .. note:: You will remain in the CLI container for the remainder of
   518            these manual commands. You must also remember to preface all commands
   519            with the corresponding environment variables when targeting a peer other than
   520            ``peer0.org1.example.com``.
   521  
   522  Now let's join ``peer0.org1.example.com`` to the channel.
   523  
   524  .. code:: bash
   525  
   526          # By default, this joins ``peer0.org1.example.com`` only
   527          # the <channel-ID.block> was returned by the previous command
   528  
   529           peer channel join -b <channel-ID.block>
   530  
   531  You can make other peers join the channel as necessary by making appropriate
   532  changes in the four environment variables.
   533  
   534  Install & Instantiate Chaincode
   535  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   536  
   537  .. note:: We will utilize a simple existing chaincode. To learn how to write
   538            your own chaincode, see the :doc:`chaincode4ade` tutorial.
   539  
   540  Applications interact with the blockchain ledger through ``chaincode``.  As
   541  such we need to install the chaincode on every peer that will execute and
   542  endorse our transactions, and then instantiate the chaincode on the channel.
   543  
   544  First, install the sample Go code onto one of the four peer nodes.  This command
   545  places the source code onto our peer's filesystem.
   546  
   547  .. code:: bash
   548  
   549      peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
   550  
   551  Next, instantiate the chaincode on the channel. This will initialize the
   552  chaincode on the channel, set the endorsement policy for the chaincode, and
   553  launch a chaincode container for the targeted peer.  Take note of the ``-P``
   554  argument. This is our policy where we specify the required level of endorsement
   555  for a transaction against this chaincode to be validated.
   556  
   557  In the command below you’ll notice that we specify our policy as
   558  ``-P "OR ('Org0MSP.member','Org1MSP.member')"``. This means that we need
   559  “endorsement” from a peer belonging to Org1 **OR** Org2 (i.e. only one endorsement).
   560  If we changed the syntax to ``AND`` then we would need two endorsements.
   561  
   562  .. code:: bash
   563  
   564      # be sure to replace the $CHANNEL_NAME environment variable
   565      # if you did not install your chaincode with a name of mycc, then modify that argument as well
   566  
   567      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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n mycc -v 1.0 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org1MSP.member','Org2MSP.member')"
   568  
   569  See the `endorsement
   570  policies <http://hyperledger-fabric.readthedocs.io/en/latest/endorsement-policies.html>`__
   571  documentation for more details on policy implementation.
   572  
   573  Query
   574  ^^^^^
   575  
   576  Let's query for the value of ``a`` to make sure the chaincode was properly
   577  instantiated and the state DB was populated. The syntax for query is as follows:
   578  
   579  .. code:: bash
   580  
   581    # be sure to set the -C and -n flags appropriately
   582  
   583    peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
   584  
   585  
   586  Invoke
   587  ^^^^^^
   588  
   589  Now let's move ``10`` from ``a`` to ``b``.  This transaction will cut a new block and
   590  update the state DB. The syntax for invoke is as follows:
   591  
   592  .. code:: bash
   593  
   594      # be sure to set the -C and -n flags appropriately
   595  
   596      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/tlscacerts/tlsca.example.com-cert.pem  -C $CHANNEL_NAME -n mycc -c '{"Args":["invoke","a","b","10"]}'
   597  
   598  Query
   599  ^^^^^
   600  
   601  Let's confirm that our previous invocation executed properly. We initialized the
   602  key ``a`` with a value of ``100`` and just removed ``10`` with our previous
   603  invocation. Therefore, a query against ``a`` should reveal ``90``. The syntax
   604  for query is as follows.
   605  
   606  .. code:: bash
   607  
   608    # be sure to set the -C and -n flags appropriately
   609  
   610    peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}'
   611  
   612  We should see the following:
   613  
   614  .. code:: bash
   615  
   616     Query Result: 90
   617  
   618  Feel free to start over and manipulate the key value pairs and subsequent
   619  invocations.
   620  
   621  .. _behind-scenes:
   622  
   623  What's happening behind the scenes?
   624  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   625  
   626  .. note:: These steps describe the scenario in which
   627            ``script.sh`` is not commented out in the
   628            docker-compose-cli.yaml file.  Clean your network
   629            with ``./byfn.sh -m down`` and ensure
   630            this command is active.  Then use the same
   631            docker-compose prompt to launch your network again
   632  
   633  -  A script - ``script.sh`` - is baked inside the CLI container. The
   634     script drives the ``createChannel`` command against the supplied channel name
   635     and uses the channel.tx file for channel configuration.
   636  
   637  -  The output of ``createChannel`` is a genesis block -
   638     ``<your_channel_name>.block`` - which gets stored on the peers' file systems and contains
   639     the channel configuration specified from channel.tx.
   640  
   641  -  The ``joinChannel`` command is exercised for all four peers, which takes as
   642     input the previously generated genesis block.  This command instructs the
   643     peers to join ``<your_channel_name>`` and create a chain starting with ``<your_channel_name>.block``.
   644  
   645  -  Now we have a channel consisting of four peers, and two
   646     organizations.  This is our ``TwoOrgsChannel`` profile.
   647  
   648  -  ``peer0.org1.example.com`` and ``peer1.org1.example.com`` belong to Org1;
   649     ``peer0.org2.example.com`` and ``peer1.org2.example.com`` belong to Org2
   650  
   651  -  These relationships are defined through the ``crypto-config.yaml`` and
   652     the MSP path is specified in our docker compose.
   653  
   654  -  The anchor peers for Org1MSP (``peer0.org1.example.com``) and
   655     Org2MSP (``peer0.org2.example.com``) are then updated.  We do this by passing
   656     the ``Org1MSPanchors.tx`` and ``Org2MSPanchors.tx`` artifacts to the ordering
   657     service along with the name of our channel.
   658  
   659  -  A chaincode - **chaincode_example02** - is installed on ``peer0.org1.example.com`` and
   660     ``peer0.org2.example.com``
   661  
   662  -  The chaincode is then "instantiated" on ``peer0.org2.example.com``. Instantiation
   663     adds the chaincode to the channel, starts the container for the target peer,
   664     and initializes the key value pairs associated with the chaincode.  The initial
   665     values for this example are ["a","100" "b","200"]. This "instantiation" results
   666     in a container by the name of ``dev-peer0.org2.example.com-mycc-1.0`` starting.
   667  
   668  -  The instantiation also passes in an argument for the endorsement
   669     policy. The policy is defined as
   670     ``-P "OR    ('Org1MSP.member','Org2MSP.member')"``, meaning that any
   671     transaction must be endorsed by a peer tied to Org1 or Org2.
   672  
   673  -  A query against the value of "a" is issued to ``peer0.org1.example.com``. The
   674     chaincode was previously installed on ``peer0.org1.example.com``, so this will start
   675     a container for Org1 peer0 by the name of ``dev-peer0.org1.example.com-mycc-1.0``. The result
   676     of the query is also returned. No write operations have occurred, so
   677     a query against "a" will still return a value of "100".
   678  
   679  -  An invoke is sent to ``peer0.org1.example.com`` to move "10" from "a" to "b"
   680  
   681  -  The chaincode is then installed on ``peer1.org2.example.com``
   682  
   683  -  A query is sent to ``peer1.org2.example.com`` for the value of "a". This starts a
   684     third chaincode container by the name of ``dev-peer1.org2.example.com-mycc-1.0``. A
   685     value of 90 is returned, correctly reflecting the previous
   686     transaction during which the value for key "a" was modified by 10.
   687  
   688  What does this demonstrate?
   689  ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   690  
   691  Chaincode **MUST** be installed on a peer in order for it to
   692  successfully perform read/write operations against the ledger.
   693  Furthermore, a chaincode container is not started for a peer until an ``init`` or
   694  traditional transaction - read/write - is performed against that chaincode (e.g. query for
   695  the value of "a"). The transaction causes the container to start. Also,
   696  all peers in a channel maintain an exact copy of the ledger which
   697  comprises the blockchain to store the immutable, sequenced record in
   698  blocks, as well as a state database to maintain a snapshot of the current state.
   699  This includes those peers that do not have chaincode installed on them
   700  (like ``peer1.org1.example.com`` in the above example) . Finally, the chaincode is accessible
   701  after it is installed (like ``peer1.org2.example.com`` in the above example) because it
   702  has already been instantiated.
   703  
   704  How do I see these transactions?
   705  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   706  
   707  Check the logs for the CLI Docker container.
   708  
   709  .. code:: bash
   710  
   711          docker logs -f cli
   712  
   713  You should see the following output:
   714  
   715  .. code:: bash
   716  
   717        2017-05-16 17:08:01.366 UTC [msp] GetLocalMSP -> DEBU 004 Returning existing local MSP
   718        2017-05-16 17:08:01.366 UTC [msp] GetDefaultSigningIdentity -> DEBU 005 Obtaining default signing identity
   719        2017-05-16 17:08:01.366 UTC [msp/identity] Sign -> DEBU 006 Sign: plaintext: 0AB1070A6708031A0C08F1E3ECC80510...6D7963631A0A0A0571756572790A0161
   720        2017-05-16 17:08:01.367 UTC [msp/identity] Sign -> DEBU 007 Sign: digest: E61DB37F4E8B0D32C9FE10E3936BA9B8CD278FAA1F3320B08712164248285C54
   721        Query Result: 90
   722        2017-05-16 17:08:15.158 UTC [main] main -> INFO 008 Exiting.....
   723        ===================== Query on PEER3 on channel 'mychannel' is successful =====================
   724  
   725        ===================== All GOOD, BYFN execution completed =====================
   726  
   727  
   728         _____   _   _   ____
   729        | ____| | \ | | |  _ \
   730        |  _|   |  \| | | | | |
   731        | |___  | |\  | | |_| |
   732        |_____| |_| \_| |____/
   733  
   734  You can scroll through these logs to see the various transactions.
   735  
   736  How can I see the chaincode logs?
   737  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   738  
   739  Inspect the individual chaincode containers to see the separate
   740  transactions executed against each container. Here is the combined
   741  output from each container:
   742  
   743  .. code:: bash
   744  
   745          $ docker logs dev-peer0.org2.example.com-mycc-1.0
   746          04:30:45.947 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
   747          ex02 Init
   748          Aval = 100, Bval = 200
   749  
   750          $ docker logs dev-peer0.org1.example.com-mycc-1.0
   751          04:31:10.569 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
   752          ex02 Invoke
   753          Query Response:{"Name":"a","Amount":"100"}
   754          ex02 Invoke
   755          Aval = 90, Bval = 210
   756  
   757          $ docker logs dev-peer1.org2.example.com-mycc-1.0
   758          04:31:30.420 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
   759          ex02 Invoke
   760          Query Response:{"Name":"a","Amount":"90"}
   761  
   762  Understanding the Docker Compose topology
   763  -----------------------------------------
   764  
   765  The BYFN sample offers us two flavors of Docker Compose files, both of which
   766  are extended from the ``docker-compose-base.yaml`` (located in the ``base``
   767  folder).  Our first flavor, ``docker-compose-cli.yaml``, provides us with a
   768  CLI container, along with an orderer, four peers.  We use this file
   769  for the entirety of the instructions on this page.
   770  
   771  .. note:: the remainder of this section covers a docker-compose file designed for the
   772            SDK.  Refer to the `Node SDK <https://github.com/hyperledger/fabric-sdk-node>`__
   773            repo for details on running these tests.
   774  
   775  The second flavor, ``docker-compose-e2e.yaml``, is constructed to run end-to-end tests
   776  using the Node.js SDK.  Aside from functioning with the SDK, its primary differentiation
   777  is that there are containers for the fabric-ca servers.  As a result, we are able
   778  to send REST calls to the organizational CAs for user registration and enrollment.
   779  
   780  If you want to use the ``docker-compose-e2e.yaml`` without first running the
   781  byfn.sh script, then we will need to make four slight modifications.
   782  We need to point to the private keys for our Organization's CA's.  You can locate
   783  these values in your crypto-config folder.  For example, to locate the private
   784  key for Org1 we would follow this path - ``crypto-config/peerOrganizations/org1.example.com/ca/``.
   785  The private key is a long hash value followed by ``_sk``.  The path for Org2
   786  would be - ``crypto-config/peerOrganizations/org2.example.com/ca/``.
   787  
   788  In the ``docker-compose-e2e.yaml`` update the FABRIC_CA_SERVER_TLS_KEYFILE variable
   789  for ca0 and ca1.  You also need to edit the path that is provided in the command
   790  to start the ca server.  You are providing the same private key twice for each
   791  CA container.
   792  
   793  Using CouchDB
   794  -------------
   795  
   796  The state database can be switched from the default (goleveldb) to CouchDB.
   797  The same chaincode functions are available with CouchDB, however, there is the
   798  added ability to perform rich and complex queries against the state database
   799  data content contingent upon the chaincode data being modeled as JSON.
   800  
   801  To use CouchDB instead of the default database (goleveldb), follow the same
   802  procedures outlined earlier for generating the artifacts, except when starting
   803  the network pass ``docker-compose-couch.yaml`` as well:
   804  
   805  .. code:: bash
   806  
   807      CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=<pick_a_value> docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d
   808  
   809  **chaincode_example02** should now work using CouchDB underneath.
   810  
   811  .. note::  If you choose to implement mapping of the fabric-couchdb container
   812             port to a host port, please make sure you are aware of the security
   813             implications. Mapping of the port in a development environment makes the
   814             CouchDB REST API available, and allows the
   815             visualization of the database via the CouchDB web interface (Fauxton).
   816             Production environments would likely refrain from implementing port mapping in
   817             order to restrict outside access to the CouchDB containers.
   818  
   819  You can use **chaincode_example02** chaincode against the CouchDB state database
   820  using the steps outlined above, however in order to exercise the CouchDB query
   821  capabilities you will need to use a chaincode that has data modeled as JSON,
   822  (e.g. **marbles02**). You can locate the **marbles02** chaincode in the
   823  ``fabric/examples/chaincode/go`` directory.
   824  
   825  We will follow the same process to create and join the channel as outlined in the
   826  :ref:`createandjoin` section above.  Once you have joined your peer(s) to the
   827  channel, use the following steps to interact with the **marbles02** chaincode:
   828  
   829  -  Install and instantiate the chaincode on ``peer0.org1.example.com``:
   830  
   831  .. code:: bash
   832  
   833         # be sure to modify the $CHANNEL_NAME variable accordingly for the instantiate command
   834  
   835         peer chaincode install -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02
   836         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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -v 1.0 -c '{"Args":["init"]}' -P "OR ('Org0MSP.member','Org1MSP.member')"
   837  
   838  -  Create some marbles and move them around:
   839  
   840  .. code:: bash
   841  
   842          # be sure to modify the $CHANNEL_NAME variable accordingly
   843  
   844          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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
   845          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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}'
   846          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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
   847          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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}'
   848          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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}'
   849          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/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["delete","marble1"]}'
   850  
   851  -  If you chose to map the CouchDB ports in docker-compose, you can now view
   852     the state database through the CouchDB web interface (Fauxton) by opening
   853     a browser and navigating to the following URL:
   854  
   855     ``http://localhost:5984/_utils``
   856  
   857  You should see a database named ``mychannel`` (or your unique channel name) and
   858  the documents inside it.
   859  
   860  .. note:: For the below commands, be sure to update the $CHANNEL_NAME variable appropriately.
   861  
   862  You can run regular queries from the CLI (e.g. reading ``marble2``):
   863  
   864  .. code:: bash
   865  
   866        peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["readMarble","marble2"]}'
   867  
   868  The output should display the details of ``marble2``:
   869  
   870  .. code:: bash
   871  
   872         Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50}
   873  
   874  You can retrieve the history of a specific marble - e.g. ``marble1``:
   875  
   876  .. code:: bash
   877  
   878        peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}'
   879  
   880  The output should display the transactions on ``marble1``:
   881  
   882  .. code:: bash
   883  
   884        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":}]
   885  
   886  You can also perform rich queries on the data content, such as querying marble fields by owner ``jerry``:
   887  
   888  .. code:: bash
   889  
   890        peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}'
   891  
   892  The output should display the two marbles owned by ``jerry``:
   893  
   894  .. code:: bash
   895  
   896         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}}]
   897  
   898  A Note on Data Persistence
   899  --------------------------
   900  
   901  If data persistence is desired on the peer container or the CouchDB container,
   902  one option is to mount a directory in the docker-host into a relevant directory
   903  in the container. For example, you may add the following two lines in
   904  the peer container specification in the ``docker-compose-base.yaml`` file:
   905  
   906  .. code:: bash
   907  
   908         volumes:
   909          - /var/hyperledger/peer0:/var/hyperledger/production
   910  
   911  For the CouchDB container, you may add the following two lines in the CouchDB
   912  container specification:
   913  
   914  .. code:: bash
   915  
   916         volumes:
   917          - /var/hyperledger/couchdb0:/opt/couchdb/data
   918  
   919  .. _Troubleshoot:
   920  
   921  Troubleshooting
   922  ---------------
   923  
   924  -  Always start your network fresh.  Use the following command
   925     to remove artifacts, crypto, containers and chaincode images:
   926  
   927  .. code:: bash
   928  
   929        ./byfn.sh -m down
   930  
   931  - **YOU WILL SEE ERRORS IF YOU DO NOT REMOVE CONTAINERS AND IMAGES**
   932  
   933  -  If you see Docker errors, first check your version (should be 17.03.1 or above),
   934     and then try restarting your Docker process.  Problems with Docker are
   935     oftentimes not immediately recognizable.  For example, you may see errors
   936     resulting from an inability to access crypto material mounted within a
   937     container.
   938  
   939  -  If they persist remove your images and start from scratch:
   940  
   941  .. code:: bash
   942  
   943         docker rm -f $(docker ps -aq)
   944         docker rmi -f $(docker images -q)
   945  
   946  -  If you see errors on your create, instantiate, invoke or query commands, make
   947     sure you have properly updated the channel name and chaincode name.  There
   948     are placeholder values in the supplied sample commands.
   949  
   950  -  If you see the below error:
   951  
   952  .. code:: bash
   953  
   954         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)
   955  
   956  You likely have chaincode images (e.g. ``dev-peer1.org2.example.com-mycc-1.0`` or
   957  ``dev-peer0.org1.example.com-mycc-1.0``) from prior runs. Remove them and try
   958  again.
   959  
   960  .. code:: bash
   961  
   962      docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}')
   963  
   964  - If you see something similar to the following:
   965  
   966  .. code:: bash
   967  
   968        Error connecting: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure
   969        Error: rpc error: code = 14 desc = grpc: RPC failed fast due to transport failure
   970  
   971  Make sure you are running your network against the "1.0.0" images that have
   972  been retagged as "latest".
   973  
   974  If you see the below error:
   975  
   976  .. code:: bash
   977  
   978    [configtx/tool/localconfig] Load -> CRIT 002 Error reading configuration: Unsupported Config Type ""
   979    panic: Error reading configuration: Unsupported Config Type ""
   980  
   981  Then you did not set the ``FABRIC_CFG_PATH`` environment variable properly.  The
   982  configtxgen tool needs this variable in order to locate the configtx.yaml.  Go
   983  back and execute an ``export FABRIC_CFG_PATH=$PWD``, then recreate your
   984  channel artifacts.
   985  
   986  -  To cleanup the network, use the ``down`` option:
   987  
   988  .. code:: bash
   989  
   990         ./byfn.sh -m down
   991  
   992  - If you see an error stating that you still have "active endpoints", then prune
   993    your Docker networks.  This will wipe your previous networks and start you with a
   994    fresh environment:
   995  
   996  .. code:: bash
   997  
   998          docker network prune
   999  
  1000  You will see the following message:
  1001  
  1002  .. code:: bash
  1003  
  1004    WARNING! This will remove all networks not used by at least one container.
  1005    Are you sure you want to continue? [y/N]
  1006  
  1007  Select ``y``.
  1008  
  1009  - If you continue to see errors, share your logs on the **# fabric-questions**
  1010    channel on `Hyperledger Rocket Chat <https://chat.hyperledger.org/home>`__.
  1011  
  1012  .. Licensed under Creative Commons Attribution 4.0 International License
  1013     https://creativecommons.org/licenses/by/4.0/