Skip to content

Commit

Permalink
[FAB-5898] porting samples to node.js chaincode
Browse files Browse the repository at this point in the history
Fabric 1.1 supports javascript chaincode. This changeset
addresses porting of the golang chaincode to node.js
chiancode and the corresponding README files

Change-Id: Iae24e713f16ab3508fe0cc18ee062ffa412b8ba6
Signed-off-by: ratnakar <asara.ratnakar@gmail.com>
  • Loading branch information
asararatnakar committed Oct 16, 2017
1 parent 38ad278 commit 44c204d
Show file tree
Hide file tree
Showing 25 changed files with 1,081 additions and 155 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ chaincode-docker-devmode/chaincode/chaincode_example02/chaincode_example02

# fabric sdk node modules
fabcar/node_modules/
fabcar/package-lock.json

# balance transfer sample
balance-transfer/.DS_Store
balance-transfer/node_modules/*
balance-transfer/package-lock.json
27 changes: 26 additions & 1 deletion balance-transfer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ Once you have completed the above setup, you will have provisioned a local netwo
## Running the sample program

There are two options available for running the balance-transfer sample
For each of these options, you may choose to run with chaincode written in golang or in node.js.

### Option 1:

Expand Down Expand Up @@ -82,10 +83,16 @@ With the application started in terminal 1, next, test the APIs by executing the
```
cd fabric-samples/balance-transfer
./testAPIs.sh
## To use golang chaincode execute the following command
./testAPIs.sh -l golang
## OR use node.js chaincode
./testAPIs.sh -l node
```


## Sample REST APIs Requests

### Login Request
Expand Down Expand Up @@ -144,9 +151,25 @@ curl -s -X POST \
"peers": ["peer1","peer2"],
"chaincodeName":"mycc",
"chaincodePath":"github.com/example_cc",
"chaincodeType": "golang",
"chaincodeVersion":"v0"
}'
```
**NOTE:** *chaincodeType* must be set to **node** when node.js chaincode is used and *chaincodePath* must be set to the location of the node.js chaincode.
```
ex:
curl -s -X POST \
http://localhost:4000/chaincodes \
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
-H "content-type: application/json" \
-d "{
\"peers\": [\"peer1\",\"peer2\"],
\"chaincodeName\":\"mycc\",
\"chaincodePath\":\"$PWD/artifacts/src/github.com/example_cc/node\",
\"chaincodeType\": \"node\",
\"chaincodeVersion\":\"v0\"
}"
```

### Instantiate chaincode

Expand All @@ -158,9 +181,11 @@ curl -s -X POST \
-d '{
"chaincodeName":"mycc",
"chaincodeVersion":"v0",
"chaincodeType": "golang",
"args":["a","100","b","200"]
}'
```
**NOTE:** *chaincodeType* must be set to **node** when node.js chaincode is used

### Invoke request

Expand Down
17 changes: 14 additions & 3 deletions balance-transfer/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,12 @@ app.post('/chaincodes', function(req, res) {
var chaincodeName = req.body.chaincodeName;
var chaincodePath = req.body.chaincodePath;
var chaincodeVersion = req.body.chaincodeVersion;
var chaincodeType = req.body.chaincodeType;
logger.debug('peers : ' + peers); // target peers list
logger.debug('chaincodeName : ' + chaincodeName);
logger.debug('chaincodePath : ' + chaincodePath);
logger.debug('chaincodeVersion : ' + chaincodeVersion);
logger.debug('chaincodeType : ' + chaincodeType);
if (!peers || peers.length == 0) {
res.json(getErrorMessage('\'peers\''));
return;
Expand All @@ -207,8 +209,11 @@ app.post('/chaincodes', function(req, res) {
res.json(getErrorMessage('\'chaincodeVersion\''));
return;
}

install.installChaincode(peers, chaincodeName, chaincodePath, chaincodeVersion, req.username, req.orgname)
if (!chaincodeType) {
res.json(getErrorMessage('\'chaincodeType\''));
return;
}
install.installChaincode(peers, chaincodeName, chaincodePath, chaincodeVersion, chaincodeType, req.username, req.orgname)
.then(function(message) {
res.send(message);
});
Expand All @@ -219,11 +224,13 @@ app.post('/channels/:channelName/chaincodes', function(req, res) {
var chaincodeName = req.body.chaincodeName;
var chaincodeVersion = req.body.chaincodeVersion;
var channelName = req.params.channelName;
var chaincodeType = req.body.chaincodeType;
var fcn = req.body.fcn;
var args = req.body.args;
logger.debug('channelName : ' + channelName);
logger.debug('chaincodeName : ' + chaincodeName);
logger.debug('chaincodeVersion : ' + chaincodeVersion);
logger.debug('chaincodeType : ' + chaincodeType);
logger.debug('fcn : ' + fcn);
logger.debug('args : ' + args);
if (!chaincodeName) {
Expand All @@ -238,11 +245,15 @@ app.post('/channels/:channelName/chaincodes', function(req, res) {
res.json(getErrorMessage('\'channelName\''));
return;
}
if (!chaincodeType) {
res.json(getErrorMessage('\'chaincodeType\''));
return;
}
if (!args) {
res.json(getErrorMessage('\'args\''));
return;
}
instantiate.instantiateChaincode(channelName, chaincodeName, chaincodeVersion, fcn, args, req.username, req.orgname)
instantiate.instantiateChaincode(channelName, chaincodeName, chaincodeVersion, chaincodeType, fcn, args, req.username, req.orgname)
.then(function(message) {
res.send(message);
});
Expand Down
7 changes: 4 additions & 3 deletions balance-transfer/app/install-chaincode.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ var config = require('../config.json');
var helper = require('./helper.js');
var logger = helper.getLogger('install-chaincode');
var tx_id = null;
//function installChaincode(org) {

var installChaincode = function(peers, chaincodeName, chaincodePath,
chaincodeVersion, username, org) {
chaincodeVersion, chaincodeType, username, org) {
logger.debug(
'\n============ Install chaincode on organizations ============\n');
helper.setupChaincodeDeploy();
Expand All @@ -35,7 +35,8 @@ var installChaincode = function(peers, chaincodeName, chaincodePath,
targets: helper.newPeers(peers, org),
chaincodePath: chaincodePath,
chaincodeId: chaincodeName,
chaincodeVersion: chaincodeVersion
chaincodeVersion: chaincodeVersion,
chaincodeType: chaincodeType
};
return client.installChaincode(request);
}, (err) => {
Expand Down
4 changes: 3 additions & 1 deletion balance-transfer/app/instantiate-chaincode.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ var ORGS = hfc.getConfigSetting('network-config');
var tx_id = null;
var eh = null;

var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion, functionName, args, username, org) {
var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion, functionName, chaincodeType,
args, username, org) {
logger.debug('\n============ Instantiate chaincode on organization ' + org +
' ============\n');

Expand All @@ -46,6 +47,7 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion
// send proposal to endorser
var request = {
chaincodeId: chaincodeName,
chaincodeType: chaincodeType,
chaincodeVersion: chaincodeVersion,
args: args,
txId: tx_id
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
*/

const shim = require('fabric-shim');
const util = require('util');

var Chaincode = class {

// Initialize the chaincode
async Init(stub) {
console.info('========= example_cc Init =========');
let ret = stub.getFunctionAndParameters();
console.info(ret);
let args = ret.params;
// initialise only if 4 parameters passed.
if (args.length != 4) {
return shim.error('Incorrect number of arguments. Expecting 4');
}

let A = args[0];
let B = args[2];
let Aval = args[1];
let Bval = args[3];

if (typeof parseInt(Aval) !== 'number' || typeof parseInt(Bval) !== 'number') {
return shim.error('Expecting integer value for asset holding');
}

try {
await stub.putState(A, Buffer.from(Aval));
try {
await stub.putState(B, Buffer.from(Bval));
return shim.success();
} catch (err) {
return shim.error(err);
}
} catch (err) {
return shim.error(err);
}
}

async Invoke(stub) {
let ret = stub.getFunctionAndParameters();
console.info(ret);
let method = this[ret.fcn];
if (!method) {
console.error('no method of name:' + ret.fcn + ' found');
return shim.error('no method of name:' + ret.fcn + ' found');
}

console.info('\nCalling method : ' + ret.fcn);
try {
let payload = await method(stub, ret.params);
return shim.success(payload);
} catch (err) {
console.log(err);
return shim.error(err);
}
}

async move(stub, args) {
if (args.length != 3) {
throw new Error('Incorrect number of arguments. Expecting 3');
}

let A = args[0];
let B = args[1];
if (!A || !B) {
throw new Error('asset holding must not be empty');
}

// Get the state from the ledger
let Avalbytes = await stub.getState(A);
if (!Avalbytes) {
throw new Error('Failed to get state of asset holder A');
}
let Aval = parseInt(Avalbytes.toString());

let Bvalbytes = await stub.getState(B);
if (!Bvalbytes) {
throw new Error('Failed to get state of asset holder B');
}

let Bval = parseInt(Bvalbytes.toString());
// Perform the execution
let amount = parseInt(args[2]);
if (typeof amount !== 'number') {
throw new Error('Expecting integer value for amount to be transaferred');
}

Aval = Aval - amount;
Bval = Bval + amount;
console.info(util.format('Aval = %d, Bval = %d\n', Aval, Bval));

// Write the states back to the ledger
await stub.putState(A, Buffer.from(Aval.toString()));
await stub.putState(B, Buffer.from(Bval.toString()));

}

// Deletes an entity from state
async delete(stub, args) {
if (args.length != 1) {
throw new Error('Incorrect number of arguments. Expecting 1');
}

let A = args[0];

// Delete the key from the state in ledger
await stub.deleteState(A);
}

// query callback representing the query of a chaincode
async query(stub, args) {
if (args.length != 1) {
throw new Error('Incorrect number of arguments. Expecting name of the person to query')
}

let jsonResp = {};
let A = args[0];

// Get the state from the ledger
let Avalbytes = await stub.getState(A);
if (!Avalbytes) {
jsonResp.error = 'Failed to get state for ' + A;
throw new Error(JSON.stringify(jsonResp));
}

jsonResp.name = A;
jsonResp.amount = Avalbytes.toString();
console.info('Query Response:');
console.info(jsonResp);
return Avalbytes;
}
};

shim.start(new Chaincode());
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "example_cc",
"version": "1.0.0",
"description": "node-js version of example_02.go chaincode",
"engines": {
"node": ">=8.4.0",
"npm": ">=5.3.0"
},
"scripts": { "start" : "node example_cc.js" },
"engine-strict": true,
"license": "Apache-2.0",
"dependencies": {
"fabric-shim": "unstable"
}
}
4 changes: 2 additions & 2 deletions balance-transfer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"express-bearer-token": "^2.1.0",
"express-jwt": "^5.1.0",
"express-session": "^1.15.2",
"fabric-ca-client": "^1.0.0",
"fabric-client": "^1.0.0",
"fabric-ca-client": "unstable",
"fabric-client": "unstable",
"fs-extra": "^2.0.0",
"jsonwebtoken": "^7.3.0",
"log4js": "^0.6.38"
Expand Down
Loading

0 comments on commit 44c204d

Please sign in to comment.