From fd623d18ad5ed1611939ea1b98c8a06534fc4c11 Mon Sep 17 00:00:00 2001 From: Nick Gaski Date: Tue, 25 Apr 2017 13:00:19 -0400 Subject: [PATCH] [FAB-3324] - Upgrade Getting Started No more clone expose cryptogen TLS-enabled & Non TLS networks Fix paths Add explanation on channel creation, signing certs, and policies [ci-skip] Change-Id: I56162951f1149a8e961ecced0fdd65c809ebe1b2 Signed-off-by: Nick Gaski --- docs/source/getting_startedv2.rst | 699 ++++++++++++++++++++++++++++++ docs/source/index.rst | 2 +- 2 files changed, 700 insertions(+), 1 deletion(-) create mode 100644 docs/source/getting_startedv2.rst diff --git a/docs/source/getting_startedv2.rst b/docs/source/getting_startedv2.rst new file mode 100644 index 00000000000..2e6dcb7d195 --- /dev/null +++ b/docs/source/getting_startedv2.rst @@ -0,0 +1,699 @@ +Getting Started +=============== + +The getting started scenario provisions a sample Fabric network consisting of +two organizations, each maintaining two peers, and a "solo" ordering service. + +Prior to launching the network, we will demonstrate the usage of two fundamental tools: + +- cryptogen - generates the x509 certificates used to identify and authenticate + the various components in the network. +- configtxgen - generates the requisite configuration artifacts for orderer + bootstrap and channel creation. + +In no time we'll have a fully-functioning transactional network with a shared +ledger and digital signature verification. Let's get going... + +Prerequisites and setup +----------------------- + +- `Docker `__ - v1.12 or higher +- `Docker Compose `__ - v1.8 or higher +- `Docker Toolbox `__ - Windows users only +- `Go `__ - 1.7 or higher +- `Git Bash `__ - Windows users only; provides a better alternative to the Windows command prompt + +Curl the artifacts and binaries +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. note:: If you are running on Windows you will want to make use of your Git + Bash shell for the upcoming terminal commands. + +- Download the `cURL `__ tool if not already installed. +- Determine a location on your machine where you want to place the artifacts and binaries. + +.. code:: bash + + mkdir fabric-sample + cd fabric-sample + +Next, execute the following command: + +.. code:: bash + + curl -L https://logs.hyperledger.org/sandbox/vex-yul-hyp-jenkins-2/fabric-verify-x86_64_1/5/release.tar.gz -o release.tar.gz 2> /dev/null; tar -xvf release.tar.gz + +This command pulls and extracts all of the necessary artifacts to set up your +network and places them into a folder titled ``release``. It also retrieves the +two binaries - cryptogen and configtxgen - which are briefly described at the top +of this page. + +Pulling the docker images +^^^^^^^^^^^^^^^^^^^^^^^^^ + +Change directories into ``release``. You should see the following: + +.. code:: bash + + jdoe-mbp:release johndoe$ ls + darwin-amd64 linux-amd64 linux-ppc64le linux-s390x samples templates windows-amd64 + +You will notice that there are platform-specific folders. Each folder contains the +corresponding binaries for that platform, along with a script that we will use +to download the Fabric images. Right now we're only interested in the script. +Navigate into the folder matching your machine's OS and then into ``install``. +For example, if you were running on OSX: + +.. code:: bash + + cd darwin-amd64/install + +Now run the shell script to download the docker images. This will take a few +minutes so remember that patience is a virtue: + +.. code:: bash + + ./get-docker-images.sh + +Execute a ``docker images`` command to view your images. Assuming you had no +images on your machine prior to running the script, you should see the following: + +.. code:: bash + + jdoe-mbp:install johndoe$ docker images + REPOSITORY TAG IMAGE ID CREATED SIZE + hyperledger/fabric-couchdb x86_64-1.0.0-alpha f3ce31e25872 5 weeks ago 1.51 GB + hyperledger/fabric-kafka x86_64-1.0.0-alpha 589dad0b93fc 5 weeks ago 1.3 GB + hyperledger/fabric-zookeeper x86_64-1.0.0-alpha 9a51f5be29c1 5 weeks ago 1.31 GB + hyperledger/fabric-orderer x86_64-1.0.0-alpha 5685fd77ab7c 5 weeks ago 182 MB + hyperledger/fabric-peer x86_64-1.0.0-alpha 784c5d41ac1d 5 weeks ago 184 MB + hyperledger/fabric-javaenv x86_64-1.0.0-alpha a08f85d8f0a9 5 weeks ago 1.42 GB + hyperledger/fabric-ccenv x86_64-1.0.0-alpha 91792014b61f 5 weeks ago 1.29 GB + +Look at the names for each image; these are the components that will ultimately +comprise our Fabric network. + +Using the cryptogen tool +------------------------ + +First, let's set the environment variable for our platform. This command +will detect your OS and use the appropriate binaries for the subsequent steps: + +.. code:: bash + + # for power or z + os_arch=$(echo "$(uname -s)-$(uname -m)" | awk '{print tolower($0)}') + # for linux, osx or windows + os_arch=$(echo "$(uname -s)-amd64" | awk '{print tolower($0)}') + +Ok now for the fun stuff - generating the crypto material. Pop into the ``e2e`` folder: + +.. code:: bash + + cd ../../samples/e2e + +We are going to pass in the ``crypto-config.yaml`` file as an argument for the +upcoming command. This file contains the definition/structure of our network +and lists the components that we are generating certs for. If you open the file +you will see that our network will consist of - one ``OrdererOrg`` and two +``PeerOrgs`` each maintaining two peers. You can easily modify this file to +generate certs for a more elaborate network, however we will leave the sample configuration +for the sake of simplicity. Got it? Let's run the tool now: + +.. code:: bash + + # this syntax requires you to be in the e2e directory + # notice that we will pass in the $os_arch variable in order to use the correct binary + ./../../$os_arch/bin/cryptogen generate --config=./crypto-config.yaml + +If the tool runs successfully, you will see the various KeyStores churn out in +your terminal. The certs are then parked into a ``crypto-config`` folder that +is generated when you run the tool. + +Using the configtxgen tool +-------------------------- + +We will now use our second tool - configtxgen - to create our ordering service +genesis block and a channel configuration artifact. As the abbreviation suggests, +this tool is a configuration transaction generator. More info on the configtxgen +tool can be found `here `__ +However, at this stage (and for the sake of brevity) we will simply make use of +the tool to generate our two artifacts. + +.. note:: The ``configtx.yaml`` file contains the definitions for our sample + network and presents the topology of the network components - three members + (OrdererOrg, Org0 & Org1), and the anchor peers for each PeerOrg + (peer0 and peer2). You will notice + that it is structured similarly to the ``crypto-config.yaml`` that we + just passed to generate our certs. The main difference is that we can + now point to the locations of those certs. You'll recall that in the + previous step we created a new folder called ``crypto-config`` and parked + the certs there. The ``configtx.yaml`` points to that directory and + allows us to bundle the root certs for the Orgs constituting our + network into the genesis block. This is a critical concept. Now any + network entity communicating with the ordering service can have its + digital signature verified. + +Generate the orderer genesis block +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +From your ``e2e`` folder first execute the following: + +.. code:: bash + + # this command will not return a response + export ORDERER_CFG_PATH=$PWD + +Then use the tool: + +.. code:: bash + + # notice at the top of configtx.yaml we define the profile as TwoOrgs + ./../../$os_arch/bin/configtxgen -profile TwoOrgs -outputBlock orderer.block + # for example, if you are running OSX then the binary from darwin-amd64 would have been used + +The orderer genesis block - ``orderer.block`` - is output into the ``e2e`` directory. + +Generate the channel configuration artifact +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +When we call the ``createChannel`` API, and send the proposal to the ordering +service, we need to pass a channel configuration artifact along with this call. +We will once again leverage the ``configtx.yaml`` and use the same profile +definition - TwoOrgs - that we used to create the orderer genesis block. In +other words, this channel we are creating is a network-wide channel. All Orgs +are included. + +Still in your ``e2e`` folder execute the following: + +.. code:: bash + + # replace the parm with a name of your choosing + ./../../$os_arch/bin/configtxgen -profile TwoOrgs -outputCreateChannelTx channel.tx -channelID + +The channel configuration artifact - ``channel.tx`` - is output into the ``e2e`` directory. + +Start the network (No TLS) +-------------------------- + +We will leverage a docker-compose script to spin up our network. The docker-compose +points to the images that we have already downloaded, and bootstraps the orderer +with our previously generated ``orderer.block``. Before launching the network, +open the docker-compose file and comment out the script.sh in the CLI container. +Your docker-compose should look like this: + +.. code:: bash + + working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer + #command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; ' + volumes: + +If left uncommented, the script will exercise all of the CLI commands when the +network is started. However, we want to go through the commands manually in order to +expose the syntax and functionality of each call. + +Start your network: + +.. code:: bash + + # this sets our OS + export ARCH_TAG=$(uname -m) + # this starts the network in "detached" mode; enter the appropriate value for the CHANNEL_NAME parm + CHANNEL_NAME= docker-compose -f docker-compose-no-tls.yaml up -d + +If you'd like to see the realtime logs for the components, then remove the ``-d`` flag: + +.. code:: bash + + CHANNEL_NAME= docker-compose -f docker-compose-no-tls.yaml up + +Now open another terminal and navigate back to ``release/samples/e2e``. + +Create & Join Channel +--------------------- + +Go into the cli container: + +.. code:: bash + + docker exec -it cli bash + +You should see the following: + +.. code:: bash + + root@bb5e894d9668:/opt/gopath/src/github.com/hyperledger/fabric/peer# + +Create Channel +^^^^^^^^^^^^^^ + +Recall that we used the configtxgen tool to generate a channel configuration +artifact - ``channel.tx``. We are going to pass in this artifact to the +orderer as part of the create channel request. + +.. note:: For this to work, we must pass in the path of the orderer's local MSP in order to sign + this create channel call. Recall that we bootstrapped the orderer + with the root certificates (ca certs) for all the member's of our + network. As a result, the orderer can verify the digital signature + of the submitting client. This call will also work if we pass in the + local MSP for Org0 or Org1. + +The following environment variables for the orderer must be passed: + +.. code:: bash + + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com + CORE_PEER_LOCALMSPID="OrdererMSP" + CHANNEL_NAME= + +The syntax is as follows: + +.. code:: bash + + peer channel create -o :7050 -c -f channel.tx + +So our command in its entirety would be: + +.. code:: bash + + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com CORE_PEER_LOCALMSPID="OrdererMSP" peer channel create -o orderer.example.com:7050 -c mychannel -f channel.tx + +This command returns a genesis block - ``mychannel.block`` - which we will use +to join the channel. + +Environment variables +~~~~~~~~~~~~~~~~~~~~~ + +You can see the syntax for all commands by inspecting the ``script.sh`` file in the ``scripts`` directory. + +For the following cli commands against ``PEER0`` to work, we need to set the +values for the four global environment variables given below. Please make sure to override +the values accordingly when calling commands against other peers and the orderer. + +.. code:: bash + + # Environment variables for PEER0 + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com + CORE_PEER_ADDRESS=peer0.org1.example.com:7051 + CORE_PEER_LOCALMSPID="Org0MSP" + CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem + +These environment variables for each peer are defined in the supplied docker-compose file. + +.. note:: In these examples, we are using the default ``mychannel`` for all CHANNEL_NAME arguments. + If you elect to create a uniquely named channel, be conscious to modify + your strings accordingly. + +Join channel +^^^^^^^^^^^^ + +Now let's join ``PEER0`` to the channel by passing in the genesis block that was +just returned to us upon the create channel command. + +The syntax is as follows: + +.. code:: bash + + peer channel join -b .block + +Remember, we need to pass the four global variables. So this command in its +entirety would be: + +.. code:: bash + + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer channel join -b mychannel.block + +Install +^^^^^^^ + +Now we will install the chaincode source onto the peer's filesystem. The syntax +is as follows: + +.. code:: bash + + peer chaincode install -n -v -p + +This command in its entirety would be: + +.. code:: bash + + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 >&log.txt + +Instantiate +^^^^^^^^^^^ + +Now we start the chaincode container and initialize our key value pairs. The +syntax for instantiate is as follows: + +.. code:: bash + + peer chaincode instantiate -o :7050 -C -n -v -c '{"Args":["init","key","value"]}' -P "OR/AND (CHAINCODE_POLICY)" + +Take note of the ``-P`` argument. This is our policy where we specify the +required level of endorsement for a transaction against this chaincode to be +validated. In the command below you'll notice that we specify our policy as +``-P "OR ('Org0MSP.member','Org1MSP.member')"``. This means that we need +"endorsement" from a peer belonging to Org0 **OR** Org1 (i.e. only one endorsement). +If we changed the syntax to ``AND`` then we would need two endorsements. + +This command in its entirety would be: + +.. code:: bash + + # we instantiate with the following key value pairs: "a","100","b","200" + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n mycc -v 1.0 -c '{"Args":["init","a","100","b","200"]}' -P "OR ('Org0MSP.member','Org1MSP.member')" + +.. note:: The above command will only start a single chaincode container. If + you want to interact with different peers, you must first install + the source code onto that peer's filesystem. You can then send + an invoke or query to the peer. You needn't instantiate twice, this + command will propagate to the entire channel. + +Query +^^^^^ + +Lets query for the value of "a" to make sure the chaincode was properly instantiated +and the state DB was populated. The syntax for query is as follows: + +.. code:: bash + + peer chaincode query -C -n -c '{"Args":["query","key"]}' + +This command in its entirety would be: + +.. code:: bash + + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}' + +Invoke +^^^^^^ + +Lastly we will move "10" from "a" to "b". This transaction will cut a new block +and update the state DB. The syntax for invoke is as follows: + +.. code:: bash + + peer chaincode invoke -o :7050 -C -n -c '{"Args":["invoke","key","key","value"]}' + +This command in its entirety would be: + +.. code:: bash + + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}' + +Query +^^^^^ + +Lets confirm that our previous invocation executed properly. We initialized the +key "a" with a value of "100". Therefore, removing "10" should return a value +of "90" when we query "a". The syntax for query is outlined above. + +.. code:: bash + +This query command in its entirety would be: + + CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com CORE_PEER_ADDRESS=peer0.org1.example.com:7051 CORE_PEER_LOCALMSPID="Org0MSP" CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/cacerts/org1.example.com-cert.pem peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}' + +Start the network (TLS enabled) +------------------------------ + +Use the ``script.sh`` to see the exact syntax for TLS-enabled CLI commands. + +Before starting, we need to modify our docker-compose file to reflect the appropriate private keys for +the orderer and peers. + +From your ``e2e`` directory execute the following: + +.. code:: bash + + PRIV_KEY=$(ls crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/keystore/) sed -i "s/ORDERER_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml + PRIV_KEY=$(ls crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/keystore/) sed -i "s/PEER0_ORG1_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml + PRIV_KEY=$(ls crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/keystore/) sed -i "s/PEER0_ORG2_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml + PRIV_KEY=$(ls crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/keystore/) sed -i "s/PEER1_ORG1_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml + PRIV_KEY=$(ls crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/keystore/) sed -i "s/PEER1_ORG2_PRIVATE_KEY/${PRIV_KEY}/g" docker-compose.yaml + +These commands will modify the TLS_KEY_FILE variables in your docker-compose. +Once you have executed all five commands, spin the network back up and begin +by creating your channel. + +Scripts +------- + +We exposed the verbosity of the commands in order to provide some edification +on the underlying flow and the appropriate syntax. Entering the commands manually +through the CLI is quite onerous, therefore we provide a few scripts to do the +entirety of the heavy lifting. + +Clean up +^^^^^^^^ + +Let's clean things up before continuing. First, kill your containers: + +.. code:: bash + + docker rm -f $(docker ps -aq) + +Next, execute a ``docker images`` command in your terminal to view the +**chaincode** images. They will look similar to the following: + +.. code:: bash + + REPOSITORY TAG IMAGE ID CREATED SIZE + dev-peer3-mycc-1.0 latest 13f6c8b042c6 5 minutes ago 176 MB + dev-peer0-mycc-1.0 latest e27456b2bd92 5 minutes ago 176 MB + dev-peer2-mycc-1.0 latest 111098a7c98c 5 minutes ago 176 MB + +Remove these images: + +.. code:: bash + + docker rmi + +For example: + +.. code:: bash + + docker rmi -f 13f e27 111 + +Lastly, remove the `crypto-config`` folder and the two artifacts - ``channel.tx`` +& ``orderer.block``. + +.. code:: bash + + # from the e2e directory + rm -rf channel.tx orderer.block crypto-config + +All in one +^^^^^^^^^^ + +This script will do it all for you! From the ``e2e`` directory: + +.. code:: bash + + ./network_setup.sh up + +.. note:: If you choose not to pass a channel_name value, then the default + ``mychannel`` will be used. + +APIs only +^^^^^^^^^ + +The other option is to manually generate your crypto material and configuration +artifacts, and then use the embedded ``script.sh`` in the docker-compose files +to drive your network. Make sure this script is not commented out in your +CLI container. + +When the scripts complete successfully, you should see the following message +in your terminal: + +.. code:: bash + + ===================== Query on PEER3 on channel 'mychannel' is successful ===================== + + ===================== All GOOD, End-2-End execution completed ===================== + +Using CouchDB +------------- + +The state database can be switched from the default (goleveldb) to CouchDB. +The same chaincode functions are available with CouchDB, however, there is the +added ability to perform rich and complex queries against the state database +data content contingent upon the chaincode data being modeled as JSON. + +To use CouchDB instead of the default database (goleveldb), follow the same +procedure in the **Prerequisites** section, and additionally perform the +following two steps to enable the CouchDB containers and associate each peer +container with a CouchDB container: + +- Make the CouchDB image. + +.. code:: bash + + # make sure you are in the fabric directory + make couchdb + +- Open the ``release/samples/e2e/docker-compose.yaml`` and un-comment + all commented statements relating to CouchDB containers and peer container + use of CouchDB. These instructions are are also outlined in the + same ``docker-compose.yaml`` file. Search the file for 'couchdb' (case insensitive) references. + +**chaincode_example02** should now work using CouchDB underneath. + +.. note:: If you choose to implement mapping of the fabric-couchdb container + port to a host port, please make sure you are aware of the security + implications. Mapping of the port in a development environment allows the + visualization of the database via the CouchDB web interface (Fauxton). + Production environments would likely refrain from implementing port mapping in + order to restrict outside access to the CouchDB containers. + +You can use **chaincode_example02** chaincode against the CouchDB state database +using the steps outlined above, however in order to exercise the query +capabilities you will need to use a chaincode that has data modeled as JSON, +(e.g. **marbles02**). You can locate the **marbles02** chaincode in the +``release/samples/chaincodes/go`` directory. + +Install, instantiate, invoke, and query **marbles02** chaincode by following the +same general steps outlined above for **chaincode_example02** in the +**Manually execute transactions** section. After the **Join channel** step, use the +following commands to interact with the **marbles02** chaincode: + +- Install and instantiate the chaincode on ``PEER0``: + +.. code:: bash + + peer chaincode install -o orderer0:7050 -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02 + peer chaincode instantiate -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/marbles02 -c '{"Args":["init"]}' -P "OR ('Org0MSP.member','Org1MSP.member')" + +- Create some marbles and move them around: + +.. code:: bash + + peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble1","blue","35","tom"]}' + peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble2","red","50","tom"]}' + peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["initMarble","marble3","blue","70","tom"]}' + peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarble","marble2","jerry"]}' + peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["transferMarblesBasedOnColor","blue","jerry"]}' + peer chaincode invoke -o orderer0:7050 --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem -C mychannel -n marbles -c '{"Args":["delete","marble1"]}' + + +- If you chose to activate port mapping, you can now view the state database + through the CouchDB web interface (Fauxton) by opening a browser and + navigating to one of the two URLs below. + + For containers running in a vagrant environment: + + ``http://localhost:15984/_utils`` + + For non-vagrant environment, use the port address that was mapped in CouchDB + container specification: + + ``http://localhost:5984/_utils`` + + You should see a database named ``mychannel`` and the documents + inside it. + +- You can run regular queries from the cli (e.g. reading ``marble2``): + +.. code:: bash + + peer chaincode query -C mychannel -n marbles -c '{"Args":["readMarble","marble2"]}' + +You should see the details of ``marble2``: + +.. code:: bash + + Query Result: {"color":"red","docType":"marble","name":"marble2","owner":"jerry","size":50} + +Retrieve the history of ``marble1``: + +.. code:: bash + + peer chaincode query -C mychannel -n marbles -c '{"Args":["getHistoryForMarble","marble1"]}' + +You should see the transactions on ``marble1``: + +.. code:: bash + + 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":}] + +You can also perform rich queries on the data content, such as querying marble fields by owner ``jerry``: + +.. code:: bash + + peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarblesByOwner","jerry"]}' + +The output should display the two marbles owned by ``jerry``: + +.. code:: bash + + 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}}] + +Query by field ``owner`` where the value is ``jerry``: + +.. code:: bash + + peer chaincode query -C mychannel -n marbles -c '{"Args":["queryMarbles","{\"selector\":{\"owner\":\"jerry\"}}"]}' + +The output should display: + +.. code:: bash + + 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}}] + +A Note on Data Persistence +-------------------------- + +If data persistence is desired on the peer container or the CouchDB container, +one option is to mount a directory in the docker-host into a relevant directory +in the container. For example, you may add the following two lines in +the peer container specification in the ``docker-compose.yaml`` file: + +.. code:: bash + + volumes: + - /var/hyperledger/peer0:/var/hyperledger/production + + +For the CouchDB container, you may add the following two lines in the CouchDB +container specification: + +.. code:: bash + + volumes: + - /var/hyperledger/couchdb0:/opt/couchdb/data + + +Troubleshooting +--------------- + +- Ensure you clear the file system after each run + +- If you see docker errors, remove your containers and start again. + +.. code:: bash + + docker rm -f $(docker ps -aq) + +- If you elect to run the "All in one" option, be sure you have deleted your + crypto directory and the two artifacts. + +- If you see the below error: + +.. code:: bash + + 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) + +You likely have chaincode images (e.g. ``dev-peer0-mycc-1.0`` or ``dev-peer1-mycc-1.0``) +from prior runs. Remove them and try again. + +.. code:: bash + + docker rmi -f $(docker images | grep peer[0-9]-peer[0-9] | awk '{print $3}') + +- To cleanup the network, use the ``down`` option: + +.. code:: bash + + ./network_setup.sh down + +------------------------------------------------------------------------------- diff --git a/docs/source/index.rst b/docs/source/index.rst index 9cde5cff0ad..b52776c4ebe 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -33,7 +33,7 @@ Before diving in, watch how Fabric is `Building a Blockchain for Business