This directory contains an implementation of the chaincode application called "example02" as found in the hyperledger fabric distribution. The application has been ported to chaintool to demonstrate the features, capabilities, and techniques for working with chaintool based development.
├── README.md
├── app
│ ├── app.iml
│ ├── chaincode.yaml
│ └── src
│ ├── chaincode
│ │ └── chaincode_example02.go
│ └── interfaces
│ ├── appinit.cci
│ └── org.hyperledger.chaincode.example02.cci
└── client
├── rest
│ ├── cljs
│ │ ├── Makefile
│ │ ├── appinit.proto
│ │ ├── org.hyperledger.chaincode.example02.proto
│ │ ├── project.clj
│ │ └── src
│ │ └── example02
│ │ ├── core.cljs
│ │ ├── main.cljs
│ │ └── rpc.cljs
│ └── nodejs
│ ├── appinit.proto
│ ├── index.js
│ ├── org.hyperledger.chaincode.example02.proto
│ └── package.json
└── sdk
├── Makefile
├── appinit.proto
├── org.hyperledger.chaincode.example02.proto
├── project.clj
└── src
└── example02
├── core.cljs
├── hlc
│ ├── core.cljs
│ └── user.cljs
├── main.cljs
├── rpc.cljs
└── util.cljs
- app - contains a org.hyperledger.chaincode.golang platform based chaincode application.
- This is the code deployed to the blockchain
- client - client applications for interacting with the chaincode application
- rest - REST api based clients
- nodejs - A simple demonstration of using nodejs+REST.
- cljs - A complete client for example02 over REST written in ClojureScript
- sdk - SDK based client, written in ClojureScript
- rest - REST api based clients
You will need a functioning peer that has chaintool v0.7 or higher available in the $PATH. You may check the version of chaintool you have with 'chaintool -h'. Once confirmed, start the peer with peer node start as you normally would. It is advised to keep the configuration as simple as possible (1 VP, no security, noops consensus)
Run 'chaintool package' from the app folder, noting the CAR output path
$ cd app
$ chaintool package
Writing CAR to: /Users/ghaskins/sandbox/git/chaintool/examples/example02/app/build/org.hyperledger.chaincode.example02-0.1-SNAPSHOT.car
Using path ./ ["src" "chaincode.yaml"]
|------+------------------------------------------+--------------------------------------------------------|
| Size | SHA1 | Path |
|------+------------------------------------------+--------------------------------------------------------|
| 438 | d28b22c7c30506af926dcb5bc8b946ac35ddac7f | chaincode.yaml |
| 3856 | 542d088197e1a46bc21326e67e5d84d2d2807283 | src/chaincode/chaincode_example02.go |
| 143 | 7305f65e18e4aab860b201d40916bb7adf97544f | src/interfaces/appinit.cci |
| 375 | 9492a1e96f380a97bba1f16f085fc70140154c65 | src/interfaces/org.hyperledger.chaincode.example02.cci |
|------+------------------------------------------+--------------------------------------------------------|
Platform: org.hyperledger.chaincode.golang version 1
Digital Signature: none
Raw Data Size: 4812 bytes
Archive Size: 2371 bytes
Compression Alg: gzip
Chaincode SHA3: f7026e0675b22a9d78b9f7f0cb97c93165bdefedc86de97f00e76b506c707b4ddbdfe97ad702ad600eae518891b9f0f1c8cb9a8b29b83908c2f6d46a6bcf4ecd
The chaintool package command is designed to package for deployment, not development. If you started your node with peer node start --peer-chaincodedev, run chaintool build instead. This is analogous to building non-chaintool chaincode using go build. The output will be placed in the app/build/bin/ directory.
Run 'make' from the client/rest/cljs folder
$ make
lein npm install
[email protected] /Users/ghaskins/sandbox/git/chaintool/examples/example02/client/rest/cljs
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ └─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ └─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ └── [email protected]
└─┬ [email protected]
└─┬ [email protected]
└── [email protected]
lein cljsbuild once
Compiling ClojureScript...
Compiling "out/example02.js" from ["src"]...
Successfully compiled "out/example02.js" in 3.075 seconds.
Compilation complete: use "node out/example02.js --help" for execution instructions
This will generate a nodejs application in out/example02.js. You may run it with --help to get a command summary.
$ node out/example02.js --help
Usage: example02 [options]
Options Summary:
--host HOST localhost Host name
--port PORT 3000 Port number
-p, --path PATH Path/URL to the chaincode (deploy only, mutually exclsive with -n)
-n, --name NAME Name of the chaincode (mutually exclusive with -p)
-c, --command CMD check-balance One of [deploy make-payment delete-account check-balance]
-a, --args ARGS JSON formatted arguments to submit
-h, --help
We can deploy the CAR we packaged in Step 2 using the "-c deploy" feature of the client. We specify the path the CAR with -p and args with -a.
$ node ./out/example02.js -c deploy -p /fqp/to/app.car --port 5000 --args '{"partyA":{"entity":"a", "value":100}, "partyB":{"entity":"b", "value":100}}'
This will return something that looks like:
Response: {:result {:status OK, :message a9114852d11579bb6000abd7b2d3b25403aa7ff4f365a80ab2382a1616a066cddacefd3422c62337ba1b5eda2b2f4f04f5a2e3dbd411159db188d6946e83a95b}}
Note the hash that is returned in the {:result {:message}}, as this is your chaincode instance ID or "name".
-p must be a fully qualified path since it is passed to the VP as is. Future versions of the tool/peer may allow inline data, TBD.
-a is expected to be a JSON structure that matches the protobuf definition for the request in particular. In this case, we are deploying so we are interested in the Init message within the appinit.proto.
#####If you started your node with peer node start --peer-chaincodedev, deploy your chaintool build like you would with non-chaintool chaincode.
$ CORE_CHAINCODE_ID_NAME=org.hyperledger.chaincode.example02 CORE_PEER_ADDRESS=0.0.0.0:30303 ./app/build/bin/org.hyperledger.chaincode.example02-0.1-SNAPSHOT
$ node ./out/example02.js -c deploy -n org.hyperledger.chaincode.example02 --port 5000 --args '{"partyA":{"entity":"a", "value":100}, "partyB":{"entity":"b", "value":100}}'
chaintool proto was used to generate .proto files from the .cci files defined in ./app/src/interfaces
We can use "-n $hash -c check-balance" to check the balance of one of our accounts
$ node ./out/example02.js -n a9114....946e83a95b --port 5000 -c check-balance --args '{"id":"a"}'
This should return with
Success: Balance = 100
We can repeat the process with id "b". Likewise, we can confirm that the system should return an error for any ids besides "a" or "b".
If you started your node with peer node start --peer-chaincodedev, change the hash (a9114....946e83a95b) to the name you chose in Step 4.
$ node ./out/example02.js -n org.hyperledger.chaincode.example02 --port 5000 -c check-balance --args '{"id":"a"}'
Now lets transfer 10 tokens from a to b.
$ node ./out/example02.js -n a9114....946e83a95b --port 5000 -c make-payment --args '{ "partySrc": "a", "partyDst": "b", "amount": 10}'
You should be able to repeat the query in Step 5 and confirm that a now holds 90 tokens while b holds 110.