123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841 |
- End-to-End Flow
- ===============
- The end-to-end verification demonstrates usage of the configuration
- transaction tool for orderer bootstrap and channel creation. The tool
- consumes a configuration transaction yaml file, which defines the
- cryptographic material (certs) used for member identity and network
- authentication. In other words, the MSP information for each member and
- its corresponding network entities.
- *Currently the crypto material is baked into the directory. However,
- there will be a tool in the near future to organically generate the
- certificates*
- Prerequisites
- -------------
- - Follow the steps for setting up a `development
- environment <http://hyperledger-fabric.readthedocs.io/en/latest/dev-setup/devenv.html>`__
- - Clone the Fabric code base.
- .. code:: bash
- git clone http://gerrit.hyperledger.org/r/fabric
- or though a mirrored repository in github:
- ::
- git clone https://github.com/hyperledger/fabric.git
- - Make the ``configtxgen`` tool.
- .. code:: bash
- cd $GOPATH/src/github.com/hyperledger/fabric/devenv
- vagrant up
- vagrant ssh
- # ensure sure you are in the /fabric directory where the Makefile resides
- make configtxgen
- - Make the peer and orderer images.
- .. code:: bash
- # make sure you are in vagrant and in the /fabric directory
- make peer-docker orderer-docker
- Execute a ``docker images`` command in your terminal. If the images
- compiled successfully, you should see an output similar to the
- following:
- .. code:: bash
- vagrant@hyperledger-devenv:v0.3.0-4eec836:/opt/gopath/src/github.com/hyperledger/fabric$ docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- hyperledger/fabric-orderer latest 264e45897bfb 10 minutes ago 180 MB
- hyperledger/fabric-orderer x86_64-0.7.0-snapshot-a0d032b 264e45897bfb 10 minutes ago 180 MB
- hyperledger/fabric-peer latest b3d44cff07c6 10 minutes ago 184 MB
- hyperledger/fabric-peer x86_64-0.7.0-snapshot-a0d032b b3d44cff07c6 10 minutes ago 184 MB
- hyperledger/fabric-javaenv latest 6e2a2adb998a 10 minutes ago 1.42 GB
- hyperledger/fabric-javaenv x86_64-0.7.0-snapshot-a0d032b 6e2a2adb998a 10 minutes ago 1.42 GB
- hyperledger/fabric-ccenv latest 0ce0e7dc043f 12 minutes ago 1.29 GB
- hyperledger/fabric-ccenv x86_64-0.7.0-snapshot-a0d032b 0ce0e7dc043f 12 minutes ago 1.29 GB
- hyperledger/fabric-baseimage x86_64-0.3.0 f4751a503f02 4 weeks ago 1.27 GB
- hyperledger/fabric-baseos x86_64-0.3.0 c3a4cf3b3350 4 weeks ago 161 MB
- Configuration Transaction Generator
- -----------------------------------
- The `configtxgen
- tool <https://github.com/hyperledger/fabric/blob/master/docs/source/configtxgen.rst>`__
- is used to create two artifacts: - orderer **bootstrap block** - fabric
- **channel configuration transaction**
- The orderer block is the genesis block for the ordering service, and the
- channel transaction file is broadcast to the orderer at channel creation
- time.
- The ``configtx.yaml`` contains the definitions for the sample network.
- There are two members, each managing and maintaining two peer nodes.
- Inspect this file to better understand the corresponding cryptographic
- material tied to the member components. The ``/crypto`` directory
- contains the admin certs, ca certs, private keys for each entity, and
- the signing certs for each entity.
- For ease of use, a script - ``generateCfgTrx.sh`` - is provided. The
- script will generate the two configuration artifacts.
- Run the shell script
- ^^^^^^^^^^^^^^^^^^^^
- Make sure you are in the ``examples/e2e_cli`` directory and in your
- vagrant environment. You can elect to pass in a unique name for your
- channel or simply execute the script without the ``channel-ID``
- parameter. If you choose not to pass in a unique name, then a channel
- with the default name of ``mychannel`` will be generated.
- .. code:: bash
- cd examples/e2e_cli
- # note the <channel-ID> parm is optional
- ./generateCfgTrx.sh <channel-ID>
- After you run the shell script, you should see an output in your
- terminal similar to the following:
- .. code:: bash
- 2017/02/28 17:01:52 Generating new channel configtx
- 2017/02/28 17:01:52 Creating no-op MSP instance
- 2017/02/28 17:01:52 Obtaining default signing identity
- 2017/02/28 17:01:52 Creating no-op signing identity instance
- 2017/02/28 17:01:52 Serializing identity
- 2017/02/28 17:01:52 signing message
- 2017/02/28 17:01:52 signing message
- 2017/02/28 17:01:52 Writing new channel tx
- These configuration transactions will bundle the crypto material for the
- participating members and their network components and output an orderer
- genesis block and channel transaction artifact. These two artifacts are
- required for a functioning transactional network with
- sign/verify/authenticate capabilities.
- Manually generate the artifacts (optional)
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- In your vagrant environment, navigate to the ``/common/configtx/tool``
- directory and replace the ``configtx.yaml`` file with the supplied yaml
- file in the ``/e2e_cli`` directory. Then return to the ``/e2e_cli``
- directory.
- .. code:: bash
- # Generate orderer bootstrap block
- configtxgen -profile TwoOrgs -outputBlock <block-name>
- # example: configtxgen -profile TwoOrgs -outputBlock orderer.block
- # Generate channel configuration transaction
- configtxgen -profile TwoOrgs -outputCreateChannelTx <cfg txn name> -channelID <channel-id>
- # example: configtxgen -profile TwoOrgs -outputCreateChannelTx channel.tx -channelID mychannel
- Run the end-to-end test with Docker
- -----------------------------------
- Make sure you are in the ``/e2e_cli`` directory. Then use docker-compose
- to spawn the network entities and drive the tests.
- .. code:: bash
- [CHANNEL_NAME=<channel-id>] docker-compose up -d
- If you created a unique channel name, be sure to pass in that parameter.
- For example,
- .. code:: bash
- CHANNEL_NAME=abc docker-compose up -d
- Wait, 30 seconds. Behind the scenes, there are transactions being sent
- to the peers. Execute a ``docker ps`` to view your active containers.
- You should see an output identical to the following:
- .. code:: bash
- vagrant@hyperledger-devenv:v0.3.0-4eec836:/opt/gopath/src/github.com/hyperledger/fabric/examples/e2e_cli$ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 45e3e114f7a2 dev-peer3-mycc-1.0 "chaincode -peer.a..." 4 seconds ago Up 4 seconds dev-peer3-mycc-1.0
- 5970f740ad2b dev-peer0-mycc-1.0 "chaincode -peer.a..." 24 seconds ago Up 23 seconds dev-peer0-mycc-1.0
- b84808d66e99 dev-peer2-mycc-1.0 "chaincode -peer.a..." 48 seconds ago Up 47 seconds dev-peer2-mycc-1.0
- 16d7d94c8773 hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:10051->7051/tcp, 0.0.0.0:10053->7053/tcp peer3
- 3561a99e35e6 hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:9051->7051/tcp, 0.0.0.0:9053->7053/tcp peer2
- 0baad3047d92 hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:8051->7051/tcp, 0.0.0.0:8053->7053/tcp peer1
- 1216896b7b4f hyperledger/fabric-peer "peer node start -..." About a minute ago Up About a minute 0.0.0.0:7051->7051/tcp, 0.0.0.0:7053->7053/tcp peer0
- 155ff8747b4d hyperledger/fabric-orderer "orderer" About a minute ago Up About a minute 0.0.0.0:7050->7050/tcp orderer
- All in one
- ^^^^^^^^^^
- You can also generate the artifacts and drive the tests using a single
- shell script. The ``configtxgen`` and ``docker-compose`` commands are
- embedded in the script.
- .. code:: bash
- ./network_setup.sh up <channel-ID>
- Once again, if you choose not to pass the ``channel-ID`` parameter, then
- your channel will default to ``mychannel``.
- What's happening behind the scenes?
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- - A script - ``script.sh`` - is baked inside the CLI container. The
- script drives the ``createChannel`` command against the default
- ``mychannel`` name.
- - The output of ``createChannel`` is a genesis block -
- ``mychannel.block`` - which is stored on the file system.
- - the ``joinChannel`` command is exercised for all four peers who will
- pass in the genesis block.
- - Now we have a channel consisting of four peers, and two
- organizations.
- - ``PEER0`` and ``PEER1`` belong to Org0; ``PEER2`` and ``PEER3``
- belong to Org1
- - Recall that these relationships are defined in the ``configtx.yaml``
- - A chaincode - *chaincode\_example02* is installed on ``PEER0`` and
- ``PEER2``
- - The chaincode is then "instantiated" on ``PEER2``. Instantiate simply
- refers to starting the container and initializing the key value pairs
- associated with the chaincode. The initial values for this example
- are "a","100" "b","200". This "instantiation" results in a container
- by the name of ``dev-peer2-mycc-1.0`` starting.
- - The instantiation also passes in an argument for the endorsement
- policy. The policy is defined as
- ``-P "OR ('Org0MSP.member','Org1MSP.member')"``, meaning that any
- transaction must be endorsed by a peer tied to Org0 or Org1.
- - A query against the value of "a" is issued to ``PEER0``. The
- chaincode was previously installed on ``PEER0``, so this will start
- another container by the name of ``dev-peer0-mycc-1.0``. The result
- of the query is also returned. No write operations have occurred, so
- a query against "a" will still return a value of "100"
- - An invoke is sent to ``PEER0`` to move "10" from "a" to "b"
- - The chaincode is installed on ``PEER3``
- - A query is sent to ``PEER3`` for the value of "a". This starts a
- third chaincode container by the name of ``dev-peer3-mycc-1.0``. A
- value of 90 is returned, correctly reflecting the previous
- transaction during which the value for key "a" was modified by 10.
- What does this demonstrate?
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Chaincode **MUST** be installed on a peer in order for it to
- successfully perform read/write operations against the ledger.
- Furthermore, a chaincode container is not started for a peer until a
- read/write operation is performed against that chaincode (e.g. query for
- the value of "a"). The transaction causes the container to start. Also,
- all peers in a channel maintain an exact copy of the ledger which
- comprises the blockchain to store the immutable, sequenced record in
- blocks, as well as a state database to maintain current fabric state.
- This includes those peers that do not have chaincode installed on them
- (like ``Peer3`` in the above example) . Finally, the chaincode is accessible
- after it is installed (like ``Peer3`` in the above example) because it
- already has been instantiated.
- How do I see these transactions?
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Check the logs for the CLI docker container.
- ::
- docker logs -f cli
- You should see the following output:
- .. code:: bash
- 2017-02-28 04:31:20.841 UTC [logging] InitFromViper -> DEBU 001 Setting default logging level to DEBUG for command 'chaincode'
- 2017-02-28 04:31:20.842 UTC [msp] GetLocalMSP -> DEBU 002 Returning existing local MSP
- 2017-02-28 04:31:20.842 UTC [msp] GetDefaultSigningIdentity -> DEBU 003 Obtaining default signing identity
- 2017-02-28 04:31:20.843 UTC [msp] Sign -> DEBU 004 Sign: plaintext: 0A8F050A59080322096D796368616E6E...6D7963631A0A0A0571756572790A0161
- 2017-02-28 04:31:20.843 UTC [msp] Sign -> DEBU 005 Sign: digest: 52F1A41B7B0B08CF3FC94D9D7E916AC4C01C54399E71BC81D551B97F5619AB54
- Query Result: 90
- 2017-02-28 04:31:30.425 UTC [main] main -> INFO 006 Exiting.....
- ===================== Query on chaincode on PEER3 on channel 'mychannel' is successful =====================
- ===================== All GOOD, End-2-End execution completed =====================
- How can I see the chaincode logs?
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Inspect the individual chaincode containers to see the separate
- transactions executed against each container. Here is the combined
- output from each container:
- .. code:: bash
- $ docker logs dev-peer2-mycc-1.0
- 04:30:45.947 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
- ex02 Init
- Aval = 100, Bval = 200
- $ docker logs dev-peer0-mycc-1.0
- 04:31:10.569 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
- ex02 Invoke
- Query Response:{"Name":"a","Amount":"100"}
- ex02 Invoke
- Aval = 90, Bval = 210
- $ docker logs dev-peer3-mycc-1.0
- 04:31:30.420 [BCCSP_FACTORY] DEBU : Initialize BCCSP [SW]
- ex02 Invoke
- Query Response:{"Name":"a","Amount":"90"}
- Run the end-to-end test manually with Docker
- --------------------------------------------
- From your vagrant environment exit the currently running containers:
- .. code:: bash
- docker rm -f $(docker ps -aq)
- 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 3415bc2e146c 5 hours ago 176 MB
- dev-peer0-mycc-1.0 latest 140d7ee3e911 5 hours ago 176 MB
- dev-peer2-mycc-1.0 latest 6e4fc412969e 5 hours ago 176 MB
- Remove these images:
- .. code:: bash
- docker rmi <IMAGE ID> <IMAGE ID> <IMAGE ID>
- For example:
- .. code:: bash
- docker rmi -f 341 140 6e4
- Ensure you have the configuration artifacts. If you deleted them, run
- the shell script again:
- .. code:: bash
- ./generateCfgTrx.sh <channel-ID>
- Modify the docker-compose file
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Open the docker-compose file and comment out the command to run
- ``script.sh``. Navigate down to the cli image and place a ``#`` to the
- left of the command. For example:
- .. code:: bash
- working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
- # command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}'
- Save the file and return to the ``/e2e_cli`` directory.
- Now restart your network:
- .. code:: bash
- # make sure you are in the /e2e_cli directory where you docker-compose script resides
- docker-compose up -d
- Command syntax
- ^^^^^^^^^^^^^^
- Refer to the create and join commands in the ``script.sh``.
- For the following CLI commands against `peer0` to work, you need to set the
- values for four 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/peer/peer0/localMspConfig
- CORE_PEER_ADDRESS=peer0:7051
- CORE_PEER_LOCALMSPID="Org0MSP"
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peer/peer0/localMspConfig/cacerts/peerOrg0.pem
- These environment variables for each peer are defined in the supplied
- docker-compose file.
- Create channel
- ^^^^^^^^^^^^^^
- Exec into the cli container:
- .. code:: bash
- docker exec -it cli bash
- If successful you should see the following:
- .. code:: bash
- root@0d78bb69300d:/opt/gopath/src/github.com/hyperledger/fabric/peer#
- Specify your channel name with the ``-c`` flag. Specify your channel
- configuration transaction with the ``-f`` flag. In this case it is
- ``channeltx``, however you can mount your own configuration transaction
- with a different name.
- .. code:: bash
- # the channel.tx and orderer.block are mounted in the crypto/orderer folder within your cli container
- # as a result, we pass the full path for the file
- peer channel create -o orderer0:7050 -c mychannel -f crypto/orderer/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem
- Since the `channel create` runs against the orderer, we need to override the
- four environment variables set before. So the above command in its entirety would be:
- .. code:: bash
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig CORE_PEER_LOCALMSPID="OrdererMSP" peer channel create -o orderer0:7050 -c mychannel -f crypto/orderer/channel.tx --tls $CORE_PEER_TLS_ENABLED --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/orderer/localMspConfig/cacerts/ordererOrg0.pem
- **Note**: You will remain in the CLI container for the remainder of
- these manual commands. You must also remember to preface all commands
- with the corresponding environment variables for targetting a peer other than
- `peer0`.
- Join channel
- ^^^^^^^^^^^^
- Join specific peers to the channel
- .. code:: bash
- # By default, this joins PEER0 only
- # the mychannel.block is also mounted in the crypto/orderer directory
- peer channel join -b mychannel.block
- You can make other peers join the channel as necessary by making appropriate
- changes in the four environment variables.
- Install chaincode onto a remote peer
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Install the sample go code onto one of the four peer nodes
- .. code:: bash
- peer chaincode install -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
- Instantiate chaincode and define the endorsement policy
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Instantiate the chaincode on a peer. This will launch a chaincode
- container for the targeted peer and set the endorsement policy for the
- chaincode. In this snippet, we define the policy as requiring an
- endorsement from one peer node that is a part of either `Org0` or `Org1`.
- The command is:
- .. code:: bash
- 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 mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a", "100", "b","200"]}' -P "OR ('Org0MSP.member','Org1MSP.member')"
- See the `endorsement
- policies <http://hyperledger-fabric.readthedocs.io/en/latest/endorsement-policies/>`__
- documentation for more details on policy implementation.
- Invoke chaincode
- ^^^^^^^^^^^^^^^^
- .. 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 mycc -c '{"Args":["invoke","a","b","10"]}'
- **NOTE**: Make sure to wait a few seconds for the operation to complete.
- Query chaincode
- ^^^^^^^^^^^^^^^
- .. code:: bash
- peer chaincode query -C mychannel -n mycc -c '{"Args":["query","a"]}'
- The result of the above command should be as below:
- .. code:: bash
- Query Result: 90
- Run the end-to-end test using the native binaries
- -------------------------------------------------
- Open your vagrant environment:
- .. code:: bash
- cd $GOPATH/src/github.com/hyperledger/fabric/devenv
- .. code:: bash
- # you may have to first start your VM with vagrant up
- vagrant ssh
- From the ``fabric`` directory build the issue the following commands to
- build the peer and orderer executables:
- .. code:: bash
- make clean
- make native
- You will also need the ``ccenv`` image. From the ``fabric`` directory:
- .. code:: bash
- make peer-docker
- Next, open two more terminals and start your vagrant environment in
- each. You should now have a total of three terminals, all within
- vagrant.
- Before starting, make sure to clear your ledger folder
- ``/var/hyperledger/``. You will want to do this after each run to avoid
- errors and duplication.
- ::
- rm -rf /var/hyperledger/*
- **Vagrant window 1**
- Use the ``configtxgen`` tool to create the orderer genesis block:
- .. code:: bash
- configtxgen -profile SampleSingleMSPSolo -outputBlock orderer.block
- **Vagrant window 2**
- Start the orderer with the genesis block you just generated:
- .. code:: bash
- ORDERER_GENERAL_GENESISMETHOD=file ORDERER_GENERAL_GENESISFILE=./orderer.block orderer
- **Vagrant window 1**
- Create the channel configuration transaction:
- .. code:: bash
- configtxgen -profile SampleSingleMSPSolo -outputCreateChannelTx channel.tx -channelID <channel-ID>
- This will generate a ``channel.tx`` file in your current directory
- **Vagrant window 3**
- Start the peer in *"chainless"* mode
- .. code:: bash
- peer node start --peer-defaultchain=false
- **Note**: Use Vagrant window 1 for the remainder of commands
- Create channel
- ^^^^^^^^^^^^^^
- Ask peer to create a channel with the configuration parameters in
- ``channel.tx``
- .. code:: bash
- peer channel create -o 127.0.0.1:7050 -c mychannel -f channel.tx
- This will return a channel genesis block - ``mychannel.block`` - in your
- current directory.
- Join channel
- ^^^^^^^^^^^^
- Ask peer to join the channel by passing in the channel genesis block:
- .. code:: bash
- peer channel join -b mychannel.block
- Install
- ^^^^^^^
- Install chaincode on the peer:
- .. code:: bash
- peer chaincode install -o 127.0.0.1:7050 -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02
- Make sure the chaincode is in the filesystem:
- .. code:: bash
- ls /var/hyperledger/production/chaincodes
- You should see ``mycc.1.0``
- Instantiate
- ^^^^^^^^^^^
- Instantiate the chaincode:
- .. code:: bash
- peer chaincode instantiate -o 127.0.0.1:7050 -C mychannel -n mycc -v 1.0 -p github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02 -c '{"Args":["init","a", "100", "b","200"]}'
- Check your active containers:
- .. code:: bash
- docker ps
- If the chaincode container started successfully, you should see:
- .. code:: bash
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- bd9c6bda7560 dev-jdoe-mycc-1.0 "chaincode -peer.a..." 5 seconds ago Up 5 seconds dev-jdoe-mycc-1.0
- Invoke
- ^^^^^^
- Issue an invoke to move "10" from "a" to "b":
- .. code:: bash
- peer chaincode invoke -o 127.0.0.1:7050 -C mychannel -n mycc -c '{"Args":["invoke","a","b","10"]}'
- Wait a few seconds for the operation to complete
- Query
- ^^^^^
- Query for the value of "a":
- .. code:: bash
- # this should return 90
- peer chaincode query -o 127.0.0.1:7050 -C mychannel -n mycc -c '{"Args":["query","a"]}'
- Don't forget to clear ledger folder ``/var/hyperledger/`` after each
- run!
- ::
- rm -rf /var/hyperledger/*
- 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 ``fabric/examples/e2e_cli/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
- ``fabric/examples/chaincode/go`` directory.
- Install, instantiate, invoke, and query *marbles02* chaincode by following the
- same general steps outlined above for *chaincode_example02* in the **Manually
- create the channel and join peers through CLI** section. After the **Join
- channel** step, use the following steps to interact with the *marbles02*
- chaincode:
- - Install and instantiate the chaincode in ``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 images and start from scratch.
- .. code:: bash
- make clean
- make peer-docker orderer-docker
- - 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. ``peer0-peer0-mycc-1.0`` or
- ``peer1-peer0-mycc1-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
|