This commit is contained in:
Bob Dill 2017-08-15 14:20:16 +00:00 committed by GitHub
commit dd209f8341
23 changed files with 321 additions and 194 deletions

View file

@ -11,7 +11,7 @@ A sample Node.js app to demonstrate **__fabric-client__** & **__fabric-ca-client
* Download docker images * Download docker images
``` ```
cd fabric-sdk-node/examples/balance-transfer/ cd fabric-samples/balance-transfer/
docker-compose -f artifacts/docker-compose.yaml pull docker-compose -f artifacts/docker-compose.yaml pull
``` ```
@ -40,7 +40,21 @@ docker-compose -f artifacts/docker-compose.yaml up
``` ```
##### Terminal Window 2 ##### Terminal Window 2
* Execute the REST APIs from the section [Sample REST APIs Requests](https://github.com/hyperledger/fabric-sdk-node/tree/master/examples/balance-transfer#running-the-sample-program) * Install the fabric-client and fabric-ca-client node modules
```
npm install
```
* Start the node app on PORT 4000
```
PORT=4000 node app
```
##### Terminal Window 3
* Execute the REST APIs from the section [Sample REST APIs Requests](https://github.com/hyperledger/fabric-samples/tree/master/balance-transfer#sample-rest-apis-requests)
### Option 2: ### Option 2:
@ -48,7 +62,7 @@ docker-compose -f artifacts/docker-compose.yaml up
##### Terminal Window 1 ##### Terminal Window 1
``` ```
cd fabric-sdk-node/examples/balance-transfer cd fabric-samples/balance-transfer
./runApp.sh ./runApp.sh
@ -67,7 +81,7 @@ instructions [https://stedolan.github.io/jq/](https://stedolan.github.io/jq/)
With the application started in terminal 1, next, test the APIs by executing the script - **testAPIs.sh**: With the application started in terminal 1, next, test the APIs by executing the script - **testAPIs.sh**:
``` ```
cd fabric-sdk-node/examples/balance-transfer cd fabric-samples/balance-transfer
./testAPIs.sh ./testAPIs.sh
@ -117,7 +131,7 @@ curl -s -X POST \
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:7051","localhost:7056"] "peers": ["peer1","peer2"]
}' }'
``` ```
### Install chaincode ### Install chaincode
@ -128,7 +142,7 @@ curl -s -X POST \
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:7051","localhost:7056"], "peers": ["peer1","peer2"],
"chaincodeName":"mycc", "chaincodeName":"mycc",
"chaincodePath":"github.com/example_cc", "chaincodePath":"github.com/example_cc",
"chaincodeVersion":"v0" "chaincodeVersion":"v0"
@ -143,10 +157,8 @@ curl -s -X POST \
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:7051"],
"chaincodeName":"mycc", "chaincodeName":"mycc",
"chaincodeVersion":"v0", "chaincodeVersion":"v0",
"functionName":"init",
"args":["a","100","b","200"] "args":["a","100","b","200"]
}' }'
``` ```
@ -159,7 +171,6 @@ curl -s -X POST \
-H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:7051", "localhost:7056"],
"fcn":"move", "fcn":"move",
"args":["a","b","10"] "args":["a","b","10"]
}' }'
@ -232,7 +243,7 @@ curl -s -X GET \
### Network configuration considerations ### Network configuration considerations
You have the ability to change configuration parameters by editing the network-config.json file. You have the ability to change configuration parameters by either directly editing the network-config.json file or provide an additional file for an alternative target network. The app uses an optional environment variable "TARGET_NETWORK" to control the configuration files to use. For example, if you deployed the target network on Amazon Web Services EC2, you can add a file "network-config-aws.json", and set the "TARGET_NETWORK" environment to 'aws'. The app will pick up the settings inside the "network-config-aws.json" file.
#### IP Address** and PORT information #### IP Address** and PORT information

View file

@ -27,7 +27,10 @@ var expressJWT = require('express-jwt');
var jwt = require('jsonwebtoken'); var jwt = require('jsonwebtoken');
var bearerToken = require('express-bearer-token'); var bearerToken = require('express-bearer-token');
var cors = require('cors'); var cors = require('cors');
var config = require('./config.json');
require('./config.js');
var hfc = require('fabric-client');
var helper = require('./app/helper.js'); var helper = require('./app/helper.js');
var channels = require('./app/create-channel.js'); var channels = require('./app/create-channel.js');
var join = require('./app/join-channel.js'); var join = require('./app/join-channel.js');
@ -35,8 +38,8 @@ var install = require('./app/install-chaincode.js');
var instantiate = require('./app/instantiate-chaincode.js'); var instantiate = require('./app/instantiate-chaincode.js');
var invoke = require('./app/invoke-transaction.js'); var invoke = require('./app/invoke-transaction.js');
var query = require('./app/query.js'); var query = require('./app/query.js');
var host = process.env.HOST || config.host; var host = process.env.HOST || hfc.getConfigSetting('host');
var port = process.env.PORT || config.port; var port = process.env.PORT || hfc.getConfigSetting('port');
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
//////////////////////////////// SET CONFIGURATONS //////////////////////////// //////////////////////////////// SET CONFIGURATONS ////////////////////////////
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -118,7 +121,7 @@ app.post('/users', function(req, res) {
return; return;
} }
var token = jwt.sign({ var token = jwt.sign({
exp: Math.floor(Date.now() / 1000) + parseInt(config.jwt_expiretime), exp: Math.floor(Date.now() / 1000) + parseInt(hfc.getConfigSetting('jwt_expiretime')),
username: username, username: username,
orgName: orgName orgName: orgName
}, app.get('secret')); }, app.get('secret'));
@ -216,12 +219,12 @@ app.post('/channels/:channelName/chaincodes', function(req, res) {
var chaincodeName = req.body.chaincodeName; var chaincodeName = req.body.chaincodeName;
var chaincodeVersion = req.body.chaincodeVersion; var chaincodeVersion = req.body.chaincodeVersion;
var channelName = req.params.channelName; var channelName = req.params.channelName;
var functionName = req.body.functionName; var fcn = req.body.fcn;
var args = req.body.args; var args = req.body.args;
logger.debug('channelName : ' + channelName); logger.debug('channelName : ' + channelName);
logger.debug('chaincodeName : ' + chaincodeName); logger.debug('chaincodeName : ' + chaincodeName);
logger.debug('chaincodeVersion : ' + chaincodeVersion); logger.debug('chaincodeVersion : ' + chaincodeVersion);
logger.debug('functionName : ' + functionName); logger.debug('fcn : ' + fcn);
logger.debug('args : ' + args); logger.debug('args : ' + args);
if (!chaincodeName) { if (!chaincodeName) {
res.json(getErrorMessage('\'chaincodeName\'')); res.json(getErrorMessage('\'chaincodeName\''));
@ -235,15 +238,11 @@ app.post('/channels/:channelName/chaincodes', function(req, res) {
res.json(getErrorMessage('\'channelName\'')); res.json(getErrorMessage('\'channelName\''));
return; return;
} }
if (!functionName) {
res.json(getErrorMessage('\'functionName\''));
return;
}
if (!args) { if (!args) {
res.json(getErrorMessage('\'args\'')); res.json(getErrorMessage('\'args\''));
return; return;
} }
instantiate.instantiateChaincode(channelName, chaincodeName, chaincodeVersion, functionName, args, req.username, req.orgname) instantiate.instantiateChaincode(channelName, chaincodeName, chaincodeVersion, fcn, args, req.username, req.orgname)
.then(function(message) { .then(function(message) {
res.send(message); res.send(message);
}); });
@ -260,10 +259,6 @@ app.post('/channels/:channelName/chaincodes/:chaincodeName', function(req, res)
logger.debug('chaincodeName : ' + chaincodeName); logger.debug('chaincodeName : ' + chaincodeName);
logger.debug('fcn : ' + fcn); logger.debug('fcn : ' + fcn);
logger.debug('args : ' + args); logger.debug('args : ' + args);
if (!peers || peers.length == 0) {
res.json(getErrorMessage('\'peers\''));
return;
}
if (!chaincodeName) { if (!chaincodeName) {
res.json(getErrorMessage('\'chaincodeName\'')); res.json(getErrorMessage('\'chaincodeName\''));
return; return;

View file

@ -24,10 +24,8 @@ var fs = require('fs-extra');
var User = require('fabric-client/lib/User.js'); var User = require('fabric-client/lib/User.js');
var crypto = require('crypto'); var crypto = require('crypto');
var copService = require('fabric-ca-client'); var copService = require('fabric-ca-client');
var config = require('../config.json');
var hfc = require('fabric-client'); var hfc = require('fabric-client');
hfc.addConfigFile(path.join(__dirname, 'network-config.json'));
hfc.setLogger(logger); hfc.setLogger(logger);
var ORGS = hfc.getConfigSetting('network-config'); var ORGS = hfc.getConfigSetting('network-config');
@ -44,7 +42,7 @@ for (let key in ORGS) {
cryptoSuite.setCryptoKeyStore(hfc.newCryptoKeyStore({path: getKeyStoreForOrg(ORGS[key].name)})); cryptoSuite.setCryptoKeyStore(hfc.newCryptoKeyStore({path: getKeyStoreForOrg(ORGS[key].name)}));
client.setCryptoSuite(cryptoSuite); client.setCryptoSuite(cryptoSuite);
let channel = client.newChannel(config.channelName); let channel = client.newChannel(hfc.getConfigSetting('channelName'));
channel.addOrderer(newOrderer(client)); channel.addOrderer(newOrderer(client));
clients[key] = client; clients[key] = client;
@ -58,27 +56,26 @@ for (let key in ORGS) {
} }
function setupPeers(channel, org, client) { function setupPeers(channel, org, client) {
for (let key in ORGS[org]) { for (let key in ORGS[org].peers) {
if (key.indexOf('peer') === 0) { let data = fs.readFileSync(path.join(__dirname, ORGS[org].peers[key]['tls_cacerts']));
let data = fs.readFileSync(path.join(__dirname, ORGS[org][key]['tls_cacerts']));
let peer = client.newPeer( let peer = client.newPeer(
ORGS[org][key].requests, ORGS[org].peers[key].requests,
{ {
pem: Buffer.from(data).toString(), pem: Buffer.from(data).toString(),
'ssl-target-name-override': ORGS[org][key]['server-hostname'] 'ssl-target-name-override': ORGS[org].peers[key]['server-hostname']
} }
); );
peer.setName(key);
channel.addPeer(peer); channel.addPeer(peer);
} }
} }
}
function newOrderer(client) { function newOrderer(client) {
var caRootsPath = ORGS.orderer.tls_cacerts; var caRootsPath = ORGS.orderer.tls_cacerts;
let data = fs.readFileSync(path.join(__dirname, caRootsPath)); let data = fs.readFileSync(path.join(__dirname, caRootsPath));
let caroots = Buffer.from(data).toString(); let caroots = Buffer.from(data).toString();
return client.newOrderer(config.orderer, { return client.newOrderer(ORGS.orderer.url, {
'pem': caroots, 'pem': caroots,
'ssl-target-name-override': ORGS.orderer['server-hostname'] 'ssl-target-name-override': ORGS.orderer['server-hostname']
}); });
@ -100,60 +97,36 @@ function getOrgName(org) {
} }
function getKeyStoreForOrg(org) { function getKeyStoreForOrg(org) {
return config.keyValueStore + '_' + org; return hfc.getConfigSetting('keyValueStore') + '_' + org;
} }
function newRemotes(urls, forPeers, userOrg) { function newRemotes(names, forPeers, userOrg) {
var targets = []; let client = getClientForOrg(userOrg);
// find the peer that match the urls
outer:
for (let index in urls) {
let peerUrl = urls[index];
let found = false; let targets = [];
for (let key in ORGS) { // find the peer that match the names
if (key.indexOf('org') === 0) { for (let idx in names) {
// if looking for event hubs, an app can only connect to let peerName = names[idx];
// event hubs in its own org if (ORGS[userOrg].peers[peerName]) {
if (!forPeers && key !== userOrg) { // found a peer matching the name
continue; let data = fs.readFileSync(path.join(__dirname, ORGS[userOrg].peers[peerName]['tls_cacerts']));
} let grpcOpts = {
let org = ORGS[key];
let client = getClientForOrg(key);
for (let prop in org) {
if (prop.indexOf('peer') === 0) {
if (org[prop]['requests'].indexOf(peerUrl) >= 0) {
// found a peer matching the subject url
if (forPeers) {
let data = fs.readFileSync(path.join(__dirname, org[prop]['tls_cacerts']));
targets.push(client.newPeer('grpcs://' + peerUrl, {
pem: Buffer.from(data).toString(), pem: Buffer.from(data).toString(),
'ssl-target-name-override': org[prop]['server-hostname'] 'ssl-target-name-override': ORGS[userOrg].peers[peerName]['server-hostname']
})); };
continue outer; if (forPeers) {
targets.push(client.newPeer(ORGS[userOrg].peers[peerName].requests, grpcOpts));
} else { } else {
let eh = client.newEventHub(); let eh = client.newEventHub();
let data = fs.readFileSync(path.join(__dirname, org[prop]['tls_cacerts'])); eh.setPeerAddr(ORGS[userOrg].peers[peerName].events, grpcOpts);
eh.setPeerAddr(org[prop]['events'], {
pem: Buffer.from(data).toString(),
'ssl-target-name-override': org[prop]['server-hostname']
});
targets.push(eh); targets.push(eh);
continue outer;
}
}
}
} }
} }
} }
if (!found) { if (targets.length === 0) {
logger.error(util.format('Failed to find a peer matching the url %s', peerUrl)); logger.error(util.format('Failed to find peers matching the names %s', names));
}
} }
return targets; return targets;
@ -170,12 +143,12 @@ var getClientForOrg = function(org) {
return clients[org]; return clients[org];
}; };
var newPeers = function(urls) { var newPeers = function(names, org) {
return newRemotes(urls, true); return newRemotes(names, true, org);
}; };
var newEventHubs = function(urls, org) { var newEventHubs = function(names, org) {
return newRemotes(urls, false, org); return newRemotes(names, false, org);
}; };
var getMspID = function(org) { var getMspID = function(org) {
@ -184,7 +157,7 @@ var getMspID = function(org) {
}; };
var getAdminUser = function(userOrg) { var getAdminUser = function(userOrg) {
var users = config.users; var users = hfc.getConfigSetting('admins');
var username = users[0].username; var username = users[0].username;
var password = users[0].secret; var password = users[0].secret;
var member; var member;
@ -325,7 +298,7 @@ var getOrgAdmin = function(userOrg) {
}; };
var setupChaincodeDeploy = function() { var setupChaincodeDeploy = function() {
process.env.GOPATH = path.join(__dirname, config.GOPATH); process.env.GOPATH = path.join(__dirname, hfc.getConfigSetting('CC_SRC_PATH'));
}; };
var getLogger = function(moduleName) { var getLogger = function(moduleName) {
@ -334,11 +307,6 @@ var getLogger = function(moduleName) {
return logger; return logger;
}; };
var getPeerAddressByName = function(org, peer) {
var address = ORGS[org][peer].requests;
return address.split('grpcs://')[1];
};
exports.getChannelForOrg = getChannelForOrg; exports.getChannelForOrg = getChannelForOrg;
exports.getClientForOrg = getClientForOrg; exports.getClientForOrg = getClientForOrg;
exports.getLogger = getLogger; exports.getLogger = getLogger;
@ -347,6 +315,5 @@ exports.getMspID = getMspID;
exports.ORGS = ORGS; exports.ORGS = ORGS;
exports.newPeers = newPeers; exports.newPeers = newPeers;
exports.newEventHubs = newEventHubs; exports.newEventHubs = newEventHubs;
exports.getPeerAddressByName = getPeerAddressByName;
exports.getRegisteredUsers = getRegisteredUsers; exports.getRegisteredUsers = getRegisteredUsers;
exports.getOrgAdmin = getOrgAdmin; exports.getOrgAdmin = getOrgAdmin;

View file

@ -32,7 +32,7 @@ var installChaincode = function(peers, chaincodeName, chaincodePath,
return helper.getOrgAdmin(org).then((user) => { return helper.getOrgAdmin(org).then((user) => {
var request = { var request = {
targets: helper.newPeers(peers), targets: helper.newPeers(peers, org),
chaincodePath: chaincodePath, chaincodePath: chaincodePath,
chaincodeId: chaincodeName, chaincodeId: chaincodeName,
chaincodeVersion: chaincodeVersion chaincodeVersion: chaincodeVersion
@ -47,8 +47,8 @@ var installChaincode = function(peers, chaincodeName, chaincodePath,
var all_good = true; var all_good = true;
for (var i in proposalResponses) { for (var i in proposalResponses) {
let one_good = false; let one_good = false;
if (proposalResponses && proposalResponses[0].response && if (proposalResponses && proposalResponses[i].response &&
proposalResponses[0].response.status === 200) { proposalResponses[i].response.status === 200) {
one_good = true; one_good = true;
logger.info('install proposal was good'); logger.info('install proposal was good');
} else { } else {

View file

@ -20,10 +20,8 @@ var util = require('util');
var hfc = require('fabric-client'); var hfc = require('fabric-client');
var Peer = require('fabric-client/lib/Peer.js'); var Peer = require('fabric-client/lib/Peer.js');
var EventHub = require('fabric-client/lib/EventHub.js'); var EventHub = require('fabric-client/lib/EventHub.js');
var config = require('../config.json');
var helper = require('./helper.js'); var helper = require('./helper.js');
var logger = helper.getLogger('instantiate-chaincode'); var logger = helper.getLogger('instantiate-chaincode');
hfc.addConfigFile(path.join(__dirname, 'network-config.json'));
var ORGS = hfc.getConfigSetting('network-config'); var ORGS = hfc.getConfigSetting('network-config');
var tx_id = null; var tx_id = null;
var eh = null; var eh = null;
@ -49,10 +47,13 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion
var request = { var request = {
chaincodeId: chaincodeName, chaincodeId: chaincodeName,
chaincodeVersion: chaincodeVersion, chaincodeVersion: chaincodeVersion,
fcn: functionName,
args: args, args: args,
txId: tx_id txId: tx_id
}; };
if (functionName)
request.fcn = functionName;
return channel.sendInstantiateProposal(request); return channel.sendInstantiateProposal(request);
}, (err) => { }, (err) => {
logger.error('Failed to initialize the channel'); logger.error('Failed to initialize the channel');
@ -63,8 +64,8 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion
var all_good = true; var all_good = true;
for (var i in proposalResponses) { for (var i in proposalResponses) {
let one_good = false; let one_good = false;
if (proposalResponses && proposalResponses[0].response && if (proposalResponses && proposalResponses[i].response &&
proposalResponses[0].response.status === 200) { proposalResponses[i].response.status === 200) {
one_good = true; one_good = true;
logger.info('instantiate proposal was good'); logger.info('instantiate proposal was good');
} else { } else {
@ -88,12 +89,12 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion
var deployId = tx_id.getTransactionID(); var deployId = tx_id.getTransactionID();
eh = client.newEventHub(); eh = client.newEventHub();
let data = fs.readFileSync(path.join(__dirname, ORGS[org]['peer1'][ let data = fs.readFileSync(path.join(__dirname, ORGS[org].peers['peer1'][
'tls_cacerts' 'tls_cacerts'
])); ]));
eh.setPeerAddr(ORGS[org]['peer1']['events'], { eh.setPeerAddr(ORGS[org].peers['peer1']['events'], {
pem: Buffer.from(data).toString(), pem: Buffer.from(data).toString(),
'ssl-target-name-override': ORGS[org]['peer1']['server-hostname'] 'ssl-target-name-override': ORGS[org].peers['peer1']['server-hostname']
}); });
eh.connect(); eh.connect();
@ -145,7 +146,7 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion
}).then((response) => { }).then((response) => {
if (response.status === 'SUCCESS') { if (response.status === 'SUCCESS') {
logger.info('Successfully sent transaction to the orderer.'); logger.info('Successfully sent transaction to the orderer.');
return 'Chaincode Instantiateion is SUCCESS'; return 'Chaincode Instantiation is SUCCESS';
} else { } else {
logger.error('Failed to order the transaction. Error code: ' + response.status); logger.error('Failed to order the transaction. Error code: ' + response.status);
return 'Failed to order the transaction. Error code: ' + response.status; return 'Failed to order the transaction. Error code: ' + response.status;

View file

@ -19,18 +19,16 @@ var fs = require('fs');
var util = require('util'); var util = require('util');
var hfc = require('fabric-client'); var hfc = require('fabric-client');
var Peer = require('fabric-client/lib/Peer.js'); var Peer = require('fabric-client/lib/Peer.js');
var config = require('../config.json');
var helper = require('./helper.js'); var helper = require('./helper.js');
var logger = helper.getLogger('invoke-chaincode'); var logger = helper.getLogger('invoke-chaincode');
var EventHub = require('fabric-client/lib/EventHub.js'); var EventHub = require('fabric-client/lib/EventHub.js');
hfc.addConfigFile(path.join(__dirname, 'network-config.json'));
var ORGS = hfc.getConfigSetting('network-config'); var ORGS = hfc.getConfigSetting('network-config');
var invokeChaincode = function(peersUrls, channelName, chaincodeName, fcn, args, username, org) { var invokeChaincode = function(peerNames, channelName, chaincodeName, fcn, args, username, org) {
logger.debug(util.format('\n============ invoke transaction on organization %s ============\n', org)); logger.debug(util.format('\n============ invoke transaction on organization %s ============\n', org));
var client = helper.getClientForOrg(org); var client = helper.getClientForOrg(org);
var channel = helper.getChannelForOrg(org); var channel = helper.getChannelForOrg(org);
var targets = helper.newPeers(peersUrls); var targets = (peerNames) ? helper.newPeers(peerNames, org) : undefined;
var tx_id = null; var tx_id = null;
return helper.getRegisteredUsers(username, org).then((user) => { return helper.getRegisteredUsers(username, org).then((user) => {
@ -38,13 +36,16 @@ var invokeChaincode = function(peersUrls, channelName, chaincodeName, fcn, args,
logger.debug(util.format('Sending transaction "%j"', tx_id)); logger.debug(util.format('Sending transaction "%j"', tx_id));
// send proposal to endorser // send proposal to endorser
var request = { var request = {
targets: targets,
chaincodeId: chaincodeName, chaincodeId: chaincodeName,
fcn: fcn, fcn: fcn,
args: args, args: args,
chainId: channelName, chainId: channelName,
txId: tx_id txId: tx_id
}; };
if (targets)
request.targets = targets;
return channel.sendTransactionProposal(request); return channel.sendTransactionProposal(request);
}, (err) => { }, (err) => {
logger.error('Failed to enroll user \'' + username + '\'. ' + err); logger.error('Failed to enroll user \'' + username + '\'. ' + err);
@ -55,8 +56,8 @@ var invokeChaincode = function(peersUrls, channelName, chaincodeName, fcn, args,
var all_good = true; var all_good = true;
for (var i in proposalResponses) { for (var i in proposalResponses) {
let one_good = false; let one_good = false;
if (proposalResponses && proposalResponses[0].response && if (proposalResponses && proposalResponses[i].response &&
proposalResponses[0].response.status === 200) { proposalResponses[i].response.status === 200) {
one_good = true; one_good = true;
logger.info('transaction proposal was good'); logger.info('transaction proposal was good');
} else { } else {
@ -80,7 +81,13 @@ var invokeChaincode = function(peersUrls, channelName, chaincodeName, fcn, args,
var transactionID = tx_id.getTransactionID(); var transactionID = tx_id.getTransactionID();
var eventPromises = []; var eventPromises = [];
var eventhubs = helper.newEventHubs(peersUrls, org); if (!peerNames) {
peerNames = channel.getPeers().map(function(peer) {
return peer.getName();
});
}
var eventhubs = helper.newEventHubs(peerNames, org);
for (let key in eventhubs) { for (let key in eventhubs) {
let eh = eventhubs[key]; let eh = eventhubs[key];
eh.connect(); eh.connect();

View file

@ -67,28 +67,17 @@ var joinChannel = function(channelName, peers, username, org) {
}).then((genesis_block) => { }).then((genesis_block) => {
tx_id = client.newTransactionID(); tx_id = client.newTransactionID();
var request = { var request = {
targets: helper.newPeers(peers), targets: helper.newPeers(peers, org),
txId: tx_id, txId: tx_id,
block: genesis_block block: genesis_block
}; };
for (let key in ORGS[org]) { eventhubs = helper.newEventHubs(peers, org);
if (ORGS[org].hasOwnProperty(key)) { for (let key in eventhubs) {
if (key.indexOf('peer') === 0) { let eh = eventhubs[key];
let data = fs.readFileSync(path.join(__dirname, ORGS[org][key][
'tls_cacerts'
]));
let eh = client.newEventHub();
eh.setPeerAddr(ORGS[org][key].events, {
pem: Buffer.from(data).toString(),
'ssl-target-name-override': ORGS[org][key]['server-hostname']
});
eh.connect(); eh.connect();
eventhubs.push(eh);
allEventhubs.push(eh); allEventhubs.push(eh);
} }
}
}
var eventPromises = []; var eventPromises = [];
eventhubs.forEach((eh) => { eventhubs.forEach((eh) => {

View file

@ -0,0 +1,55 @@
{
"network-config": {
"orderer": {
"url": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7050",
"server-hostname": "orderer.example.com",
"tls_cacerts": "../artifacts/channel/crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/ca.crt"
},
"org1": {
"name": "peerOrg1",
"mspid": "Org1MSP",
"ca": "https://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7054",
"peers": {
"peer1": {
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7051",
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7053",
"server-hostname": "peer0.org1.example.com",
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt"
},
"peer2": {
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7056",
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:7058",
"server-hostname": "peer1.org1.example.com",
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt"
}
},
"admin": {
"key": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore",
"cert": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/signcerts"
}
},
"org2": {
"name": "peerOrg2",
"mspid": "Org2MSP",
"ca": "https://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8054",
"peers": {
"peer1": {
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8051",
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8053",
"server-hostname": "peer0.org2.example.com",
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt"
},
"peer2": {
"requests": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8056",
"events": "grpc://ec2-13-59-99-140.us-east-2.compute.amazonaws.com:8058",
"server-hostname": "peer1.org2.example.com",
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt"
}
},
"admin": {
"key": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore",
"cert": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/signcerts"
}
}
}
}

View file

@ -9,6 +9,7 @@
"name": "peerOrg1", "name": "peerOrg1",
"mspid": "Org1MSP", "mspid": "Org1MSP",
"ca": "https://localhost:7054", "ca": "https://localhost:7054",
"peers": {
"peer1": { "peer1": {
"requests": "grpcs://localhost:7051", "requests": "grpcs://localhost:7051",
"events": "grpcs://localhost:7053", "events": "grpcs://localhost:7053",
@ -20,6 +21,7 @@
"events": "grpcs://localhost:7058", "events": "grpcs://localhost:7058",
"server-hostname": "peer1.org1.example.com", "server-hostname": "peer1.org1.example.com",
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt" "tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt"
}
}, },
"admin": { "admin": {
"key": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore", "key": "../artifacts/channel/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore",
@ -30,6 +32,7 @@
"name": "peerOrg2", "name": "peerOrg2",
"mspid": "Org2MSP", "mspid": "Org2MSP",
"ca": "https://localhost:8054", "ca": "https://localhost:8054",
"peers": {
"peer1": { "peer1": {
"requests": "grpcs://localhost:8051", "requests": "grpcs://localhost:8051",
"events": "grpcs://localhost:8053", "events": "grpcs://localhost:8053",
@ -41,6 +44,7 @@
"events": "grpcs://localhost:8058", "events": "grpcs://localhost:8058",
"server-hostname": "peer1.org2.example.com", "server-hostname": "peer1.org2.example.com",
"tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt" "tls_cacerts": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt"
}
}, },
"admin": { "admin": {
"key": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore", "key": "../artifacts/channel/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore",

View file

@ -261,7 +261,7 @@ var getChannels = function(peer, username, org) {
function buildTarget(peer, org) { function buildTarget(peer, org) {
var target = null; var target = null;
if (typeof peer !== 'undefined') { if (typeof peer !== 'undefined') {
let targets = helper.newPeers([helper.getPeerAddressByName(org, peer)]); let targets = helper.newPeers([peer], org);
if (targets && targets.length > 0) target = targets[0]; if (targets && targets.length > 0) target = targets[0];
} }

View file

@ -0,0 +1,14 @@
var util = require('util');
var path = require('path');
var hfc = require('fabric-client');
var file = 'network-config%s.json';
var env = process.env.TARGET_NETWORK;
if (env)
file = util.format(file, '-' + env);
else
file = util.format(file, '');
hfc.addConfigFile(path.join(__dirname, 'app', file));
hfc.addConfigFile(path.join(__dirname, 'config.json'));

View file

@ -3,11 +3,10 @@
"port":"4000", "port":"4000",
"jwt_expiretime": "36000", "jwt_expiretime": "36000",
"channelName":"mychannel", "channelName":"mychannel",
"GOPATH":"../artifacts", "CC_SRC_PATH":"../artifacts",
"keyValueStore":"/tmp/fabric-client-kvs", "keyValueStore":"/tmp/fabric-client-kvs",
"eventWaitTime":"30000", "eventWaitTime":"30000",
"orderer":"grpcs://localhost:7050", "admins":[
"users":[
{ {
"username":"admin", "username":"admin",
"secret":"adminpw" "secret":"adminpw"

View file

@ -2,15 +2,18 @@
"name": "balance-transfer", "name": "balance-transfer",
"version": "1.0.0", "version": "1.0.0",
"description": "A balance-transfer example node program to demonstrate using node.js SDK APIs", "description": "A balance-transfer example node program to demonstrate using node.js SDK APIs",
"main": "app/app.js", "main": "app.js",
"scripts": {
"start": "node app.js"
},
"keywords": [ "keywords": [
"fabric-client sample app", "fabric-client sample app",
"balance-transfer node sample", "balance-transfer node sample",
"v1.0 fabric nodesdk sample" "v1.0 fabric nodesdk sample"
], ],
"engines": { "engines": {
"node": ">=6.9.5", "node": ">=6.9.5 <7.0",
"npm": ">=3.10.10" "npm": ">=3.10.10 <4.0"
}, },
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {

View file

@ -56,7 +56,7 @@ curl -s -X POST \
-H "authorization: Bearer $ORG1_TOKEN" \ -H "authorization: Bearer $ORG1_TOKEN" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:7051","localhost:7056"] "peers": ["peer1","peer2"]
}' }'
echo echo
echo echo
@ -68,7 +68,7 @@ curl -s -X POST \
-H "authorization: Bearer $ORG2_TOKEN" \ -H "authorization: Bearer $ORG2_TOKEN" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:8051","localhost:8056"] "peers": ["peer1","peer2"]
}' }'
echo echo
echo echo
@ -80,7 +80,7 @@ curl -s -X POST \
-H "authorization: Bearer $ORG1_TOKEN" \ -H "authorization: Bearer $ORG1_TOKEN" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:7051","localhost:7056"], "peers": ["peer1", "peer2"],
"chaincodeName":"mycc", "chaincodeName":"mycc",
"chaincodePath":"github.com/example_cc", "chaincodePath":"github.com/example_cc",
"chaincodeVersion":"v0" "chaincodeVersion":"v0"
@ -96,7 +96,7 @@ curl -s -X POST \
-H "authorization: Bearer $ORG2_TOKEN" \ -H "authorization: Bearer $ORG2_TOKEN" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:8051","localhost:8056"], "peers": ["peer1","peer2"],
"chaincodeName":"mycc", "chaincodeName":"mycc",
"chaincodePath":"github.com/example_cc", "chaincodePath":"github.com/example_cc",
"chaincodeVersion":"v0" "chaincodeVersion":"v0"
@ -113,7 +113,6 @@ curl -s -X POST \
-d '{ -d '{
"chaincodeName":"mycc", "chaincodeName":"mycc",
"chaincodeVersion":"v0", "chaincodeVersion":"v0",
"functionName":"init",
"args":["a","100","b","200"] "args":["a","100","b","200"]
}' }'
echo echo
@ -126,7 +125,6 @@ TRX_ID=$(curl -s -X POST \
-H "authorization: Bearer $ORG1_TOKEN" \ -H "authorization: Bearer $ORG1_TOKEN" \
-H "content-type: application/json" \ -H "content-type: application/json" \
-d '{ -d '{
"peers": ["localhost:7051", "localhost:8051"],
"fcn":"move", "fcn":"move",
"args":["a","b","10"] "args":["a","b","10"]
}') }')

View file

@ -1,14 +1,14 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIICFzCCAb2gAwIBAgIUTtBERRtj53mS3poZ2N1Enigcf3wwCgYIKoZIzj0EAwIw MIICFjCCAb2gAwIBAgIUK7b5iTNHRYriNccrvzxXjYvXENkwCgYIKoZIzj0EAwIw
aDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK aDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMt EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMt
Y2Etc2VydmVyMB4XDTE3MDYyOTE5MzIwMFoXDTMyMDYyNTE5MzIwMFowaDELMAkG Y2Etc2VydmVyMB4XDTE3MDgwNjA5NDMwMFoXDTMyMDgwMjA5NDMwMFowaDELMAkG
A1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKEwtIeXBl A1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKEwtIeXBl
cmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMtY2Etc2Vy cmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMtY2Etc2Vy
dmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEH8fsI6vVIVn2j3jXpwKkM79/ dmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvbZZ9gSMveMg6dQ2f3hGRE4Q
LGy0Z9UeHA0JQcbAhOMaf5w+arqXgw+ZQkASAfaoRjozYZA39jSS/EE1XZI6HqNF JE++GbwJXYCjiwqDt9xJ4s/wuLhOEqKzYkhntdvLaUH5zJWFRyy/5LQ5BV2/AKNF
MEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE MEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE
FBo/MF+TauY0epUtCphNSvUDTX1EMAoGCCqGSM49BAMCA0gAMEUCIQCM21QC+8ru FPDCv6nfcXF2u42xfz/l4bKjjWrkMAoGCCqGSM49BAMCA0cAMEQCIAOrX7gTfZF5
8M4LwF8aTMyzpoYm1UqX8ndhrwYpcglATgIgd67Lr3baI+NQoM1G8hNpTe2+OUoS 5s0jhv/niBAgCFrZqNcmVqLI2ycPyZ1QAiBeguVoBfUfZ6saQDNqyzm55rwoUNhl
H/fG3eOymx90eOE= 1jnpnbjkbup3wA==
-----END CERTIFICATE----- -----END CERTIFICATE-----

View file

@ -74,6 +74,7 @@ services:
- ./config:/etc/hyperledger/configtx - ./config:/etc/hyperledger/configtx
depends_on: depends_on:
- orderer.example.com - orderer.example.com
- couchdb
networks: networks:
- basic - basic
@ -82,8 +83,6 @@ services:
image: hyperledger/fabric-couchdb:x86_64-1.0.0 image: hyperledger/fabric-couchdb:x86_64-1.0.0
ports: ports:
- 5984:5984 - 5984:5984
environment:
DB_URL: http://localhost:5984/member_db
networks: networks:
- basic - basic

View file

@ -7,6 +7,9 @@
# Exit on first error, print all commands. # Exit on first error, print all commands.
set -ev set -ev
# don't rewrite paths for Windows Git Bash users
export MSYS_NO_PATHCONV=1
docker-compose -f docker-compose.yml down docker-compose -f docker-compose.yml down
docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb docker-compose -f docker-compose.yml up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb

View file

@ -7,6 +7,9 @@
# Exit on first error # Exit on first error
set -e set -e
# don't rewrite paths for Windows Git Bash users
export MSYS_NO_PATHCONV=1
starttime=$(date +%s) starttime=$(date +%s)
if [ ! -d ~/.hfc-key-store/ ]; then if [ ! -d ~/.hfc-key-store/ ]; then

View file

@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# #
# Copyright IBM Corp All Rights Reserved # Copyright IBM Corp All Rights Reserved
# #
@ -34,7 +35,7 @@ export FABRIC_CFG_PATH=${PWD}
# Print the usage message # Print the usage message
function printHelp () { function printHelp () {
echo "Usage: " echo "Usage: "
echo " byfn.sh -m up|down|restart|generate [-c <channel name>] [-t <timeout>]" echo " byfn.sh -m up|down|restart|generate [-c <channel name>] [-t <timeout>] [-d <delay>] [-f <docker-compose-file>] [-s <dbtype>]"
echo " byfn.sh -h|--help (print this message)" echo " byfn.sh -h|--help (print this message)"
echo " -m <mode> - one of 'up', 'down', 'restart' or 'generate'" echo " -m <mode> - one of 'up', 'down', 'restart' or 'generate'"
echo " - 'up' - bring up the network with docker-compose up" echo " - 'up' - bring up the network with docker-compose up"
@ -43,13 +44,16 @@ function printHelp () {
echo " - 'generate' - generate required certificates and genesis block" echo " - 'generate' - generate required certificates and genesis block"
echo " -c <channel name> - channel name to use (defaults to \"mychannel\")" echo " -c <channel name> - channel name to use (defaults to \"mychannel\")"
echo " -t <timeout> - CLI timeout duration in microseconds (defaults to 10000)" echo " -t <timeout> - CLI timeout duration in microseconds (defaults to 10000)"
echo " -d <delay> - delay duration in seconds (defaults to 3)"
echo " -f <docker-compose-file> - specify which docker-compose file use (defaults to docker-compose-cli.yaml)"
echo " -s <dbtype> - the database backend to use: goleveldb (default) or couchdb"
echo echo
echo "Typically, one would first generate the required certificates and " echo "Typically, one would first generate the required certificates and "
echo "genesis block, then bring up the network. e.g.:" echo "genesis block, then bring up the network. e.g.:"
echo echo
echo " byfn.sh -m generate -c <channelname>" echo " byfn.sh -m generate -c mychannel"
echo " byfn.sh -m up -c <channelname>" echo " byfn.sh -m up -c mychannel -s couchdb"
echo " byfn.sh -m down -c <channelname>" echo " byfn.sh -m down -c mychannel"
echo echo
echo "Taking all defaults:" echo "Taking all defaults:"
echo " byfn.sh -m generate" echo " byfn.sh -m generate"
@ -106,7 +110,12 @@ function networkUp () {
replacePrivateKey replacePrivateKey
generateChannelArtifacts generateChannelArtifacts
fi fi
CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=$CLI_TIMEOUT docker-compose -f $COMPOSE_FILE up -d 2>&1 # CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=$CLI_TIMEOUT DELAY=$CLI_DELAY docker-compose -f $COMPOSE_FILE up -d 2>&1
if [ "${IF_COUCHDB}" == "couchdb" ]; then
CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=$CLI_TIMEOUT DELAY=$CLI_DELAY docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH up -d 2>&1
else
CHANNEL_NAME=$CHANNEL_NAME TIMEOUT=$CLI_TIMEOUT DELAY=$CLI_DELAY docker-compose -f $COMPOSE_FILE up -d 2>&1
fi
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "ERROR !!!! Unable to start network" echo "ERROR !!!! Unable to start network"
docker logs -f cli docker logs -f cli
@ -118,6 +127,7 @@ function networkUp () {
# Tear down running network # Tear down running network
function networkDown () { function networkDown () {
docker-compose -f $COMPOSE_FILE down docker-compose -f $COMPOSE_FILE down
docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH down
# Don't remove containers, images, etc if restarting # Don't remove containers, images, etc if restarting
if [ "$MODE" != "restart" ]; then if [ "$MODE" != "restart" ]; then
#Cleanup the chaincode containers #Cleanup the chaincode containers
@ -295,13 +305,17 @@ OS_ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/window
# timeout duration - the duration the CLI should wait for a response from # timeout duration - the duration the CLI should wait for a response from
# another container before giving up # another container before giving up
CLI_TIMEOUT=10000 CLI_TIMEOUT=10000
#default for delay
CLI_DELAY=3
# channel name defaults to "mychannel" # channel name defaults to "mychannel"
CHANNEL_NAME="mychannel" CHANNEL_NAME="mychannel"
# use this as the default docker-compose yaml definition # use this as the default docker-compose yaml definition
COMPOSE_FILE=docker-compose-cli.yaml COMPOSE_FILE=docker-compose-cli.yaml
#
COMPOSE_FILE_COUCH=docker-compose-couch.yaml
# Parse commandline args # Parse commandline args
while getopts "h?m:c:t:" opt; do while getopts "h?m:c:t:d:f:s:" opt; do
case "$opt" in case "$opt" in
h|\?) h|\?)
printHelp printHelp
@ -313,6 +327,12 @@ while getopts "h?m:c:t:" opt; do
;; ;;
t) CLI_TIMEOUT=$OPTARG t) CLI_TIMEOUT=$OPTARG
;; ;;
d) CLI_DELAY=$OPTARG
;;
f) COMPOSE_FILE=$OPTARG
;;
s) IF_COUCHDB=$OPTARG
;;
esac esac
done done
@ -331,8 +351,13 @@ else
fi fi
# Announce what was requested # Announce what was requested
echo "${EXPMODE} with channel '${CHANNEL_NAME}' and CLI timeout of '${CLI_TIMEOUT}'"
if [ "${IF_COUCHDB}" == "couchdb" ]; then
echo
echo "${EXPMODE} with channel '${CHANNEL_NAME}' and CLI timeout of '${CLI_TIMEOUT}' using database '${IF_COUCHDB}'"
else
echo "${EXPMODE} with channel '${CHANNEL_NAME}' and CLI timeout of '${CLI_TIMEOUT}'"
fi
# ask for confirmation to proceed # ask for confirmation to proceed
askProceed askProceed

View file

@ -67,7 +67,7 @@ services:
- 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 - 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
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp - CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT' command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME} ${DELAY}; sleep $TIMEOUT'
volumes: volumes:
- /var/run/:/host/var/run/ - /var/run/:/host/var/run/
- ./../chaincode/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go - ./../chaincode/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go

View file

@ -10,6 +10,7 @@ echo
echo "Build your first network (BYFN) end-to-end test" echo "Build your first network (BYFN) end-to-end test"
echo echo
CHANNEL_NAME="$1" CHANNEL_NAME="$1"
DELAY="$2"
: ${CHANNEL_NAME:="mychannel"} : ${CHANNEL_NAME:="mychannel"}
: ${TIMEOUT:="60"} : ${TIMEOUT:="60"}
COUNTER=1 COUNTER=1
@ -82,6 +83,7 @@ updateAnchorPeers() {
cat log.txt cat log.txt
verifyResult $res "Anchor peer update failed" verifyResult $res "Anchor peer update failed"
echo "===================== Anchor peers for org \"$CORE_PEER_LOCALMSPID\" on \"$CHANNEL_NAME\" is updated successfully ===================== " echo "===================== Anchor peers for org \"$CORE_PEER_LOCALMSPID\" on \"$CHANNEL_NAME\" is updated successfully ===================== "
sleep $DELAY
echo echo
} }
@ -93,7 +95,7 @@ joinWithRetry () {
if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then
COUNTER=` expr $COUNTER + 1` COUNTER=` expr $COUNTER + 1`
echo "PEER$1 failed to join the channel, Retry after 2 seconds" echo "PEER$1 failed to join the channel, Retry after 2 seconds"
sleep 2 sleep $DELAY
joinWithRetry $1 joinWithRetry $1
else else
COUNTER=1 COUNTER=1
@ -106,7 +108,7 @@ joinChannel () {
setGlobals $ch setGlobals $ch
joinWithRetry $ch joinWithRetry $ch
echo "===================== PEER$ch joined on the channel \"$CHANNEL_NAME\" ===================== " echo "===================== PEER$ch joined on the channel \"$CHANNEL_NAME\" ===================== "
sleep 2 sleep $DELAY
echo echo
done done
} }
@ -150,7 +152,7 @@ chaincodeQuery () {
# we either get a successful response, or reach TIMEOUT # we either get a successful response, or reach TIMEOUT
while test "$(($(date +%s)-starttime))" -lt "$TIMEOUT" -a $rc -ne 0 while test "$(($(date +%s)-starttime))" -lt "$TIMEOUT" -a $rc -ne 0
do do
sleep 3 sleep $DELAY
echo "Attempting to Query PEER$PEER ...$(($(date +%s)-starttime)) secs" echo "Attempting to Query PEER$PEER ...$(($(date +%s)-starttime)) secs"
peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >&log.txt peer chaincode query -C $CHANNEL_NAME -n mycc -c '{"Args":["query","a"]}' >&log.txt
test $? -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}') test $? -eq 0 && VALUE=$(cat log.txt | awk '/Query Result/ {print $NF}')

10
scripts/README.md Normal file
View file

@ -0,0 +1,10 @@
## Hyperledger Fabric Samples
fabric-preload.sh will preload all of the requisite docker images for Hyperledger Fabric and tag them
with the 'latest' tag. Optionally, specify a specific version (e.g. 1.0.1). Default version is 1.0.0.
```bash
./fabric-preload.sh [version]
```
<a rel="license" href="http://creativecommons.org/licenses/by/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>

42
scripts/fabric-preload.sh Executable file
View file

@ -0,0 +1,42 @@
#!/bin/bash
#
# Copyright IBM Corp. All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
export VERSION=${1:-1.0.0}
export ARCH=$(echo "$(uname -s|tr '[:upper:]' '[:lower:]'|sed 's/mingw64_nt.*/windows/')-$(uname -m | sed 's/x86_64/amd64/g')" | awk '{print tolower($0)}')
#Set MARCH variable i.e ppc64le,s390x,x86_64,i386
MARCH=`uname -m`
dockerFabricPull() {
local FABRIC_TAG=$1
for IMAGES in peer orderer couchdb ccenv javaenv kafka zookeeper tools; do
echo "==> FABRIC IMAGE: $IMAGES"
echo
docker pull hyperledger/fabric-$IMAGES:$FABRIC_TAG
docker tag hyperledger/fabric-$IMAGES:$FABRIC_TAG hyperledger/fabric-$IMAGES
done
}
dockerCaPull() {
local CA_TAG=$1
echo "==> FABRIC CA IMAGE"
echo
docker pull hyperledger/fabric-ca:$CA_TAG
docker tag hyperledger/fabric-ca:$CA_TAG hyperledger/fabric-ca
}
: ${CA_TAG:="$MARCH-$VERSION"}
: ${FABRIC_TAG:="$MARCH-$VERSION"}
echo "===> Pulling fabric Images"
dockerFabricPull ${FABRIC_TAG}
echo "===> Pulling fabric ca Image"
dockerCaPull ${CA_TAG}
echo
echo "===> List out hyperledger docker images"
docker images | grep hyperledger*