diff --git a/balance-transfer/README.md b/balance-transfer/README.md index 6fcf23ab..5db95e4d 100644 --- a/balance-transfer/README.md +++ b/balance-transfer/README.md @@ -11,7 +11,7 @@ A sample Node.js app to demonstrate **__fabric-client__** & **__fabric-ca-client * Download docker images ``` -cd fabric-sdk-node/examples/balance-transfer/ +cd fabric-samples/balance-transfer/ docker-compose -f artifacts/docker-compose.yaml pull ``` @@ -40,7 +40,21 @@ docker-compose -f artifacts/docker-compose.yaml up ``` ##### 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: @@ -48,7 +62,7 @@ docker-compose -f artifacts/docker-compose.yaml up ##### Terminal Window 1 ``` -cd fabric-sdk-node/examples/balance-transfer +cd fabric-samples/balance-transfer ./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**: ``` -cd fabric-sdk-node/examples/balance-transfer +cd fabric-samples/balance-transfer ./testAPIs.sh @@ -117,7 +131,7 @@ curl -s -X POST \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:7051","localhost:7056"] + "peers": ["peer1","peer2"] }' ``` ### Install chaincode @@ -128,7 +142,7 @@ curl -s -X POST \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:7051","localhost:7056"], + "peers": ["peer1","peer2"], "chaincodeName":"mycc", "chaincodePath":"github.com/example_cc", "chaincodeVersion":"v0" @@ -143,10 +157,8 @@ curl -s -X POST \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:7051"], "chaincodeName":"mycc", "chaincodeVersion":"v0", - "functionName":"init", "args":["a","100","b","200"] }' ``` @@ -159,7 +171,6 @@ curl -s -X POST \ -H "authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0OTQ4NjU1OTEsInVzZXJuYW1lIjoiSmltIiwib3JnTmFtZSI6Im9yZzEiLCJpYXQiOjE0OTQ4NjE5OTF9.yWaJhFDuTvMQRaZIqg20Is5t-JJ_1BP58yrNLOKxtNI" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:7051", "localhost:7056"], "fcn":"move", "args":["a","b","10"] }' @@ -232,7 +243,7 @@ curl -s -X GET \ ### 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 diff --git a/balance-transfer/app.js b/balance-transfer/app.js index 52224f74..db936b8a 100644 --- a/balance-transfer/app.js +++ b/balance-transfer/app.js @@ -27,7 +27,10 @@ var expressJWT = require('express-jwt'); var jwt = require('jsonwebtoken'); var bearerToken = require('express-bearer-token'); var cors = require('cors'); -var config = require('./config.json'); + +require('./config.js'); +var hfc = require('fabric-client'); + var helper = require('./app/helper.js'); var channels = require('./app/create-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 invoke = require('./app/invoke-transaction.js'); var query = require('./app/query.js'); -var host = process.env.HOST || config.host; -var port = process.env.PORT || config.port; +var host = process.env.HOST || hfc.getConfigSetting('host'); +var port = process.env.PORT || hfc.getConfigSetting('port'); /////////////////////////////////////////////////////////////////////////////// //////////////////////////////// SET CONFIGURATONS //////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -118,7 +121,7 @@ app.post('/users', function(req, res) { return; } 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, orgName: orgName }, app.get('secret')); @@ -216,12 +219,12 @@ app.post('/channels/:channelName/chaincodes', function(req, res) { var chaincodeName = req.body.chaincodeName; var chaincodeVersion = req.body.chaincodeVersion; var channelName = req.params.channelName; - var functionName = req.body.functionName; + var fcn = req.body.fcn; var args = req.body.args; logger.debug('channelName : ' + channelName); logger.debug('chaincodeName : ' + chaincodeName); logger.debug('chaincodeVersion : ' + chaincodeVersion); - logger.debug('functionName : ' + functionName); + logger.debug('fcn : ' + fcn); logger.debug('args : ' + args); if (!chaincodeName) { res.json(getErrorMessage('\'chaincodeName\'')); @@ -235,15 +238,11 @@ app.post('/channels/:channelName/chaincodes', function(req, res) { res.json(getErrorMessage('\'channelName\'')); return; } - if (!functionName) { - res.json(getErrorMessage('\'functionName\'')); - return; - } if (!args) { res.json(getErrorMessage('\'args\'')); 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) { res.send(message); }); @@ -260,10 +259,6 @@ app.post('/channels/:channelName/chaincodes/:chaincodeName', function(req, res) logger.debug('chaincodeName : ' + chaincodeName); logger.debug('fcn : ' + fcn); logger.debug('args : ' + args); - if (!peers || peers.length == 0) { - res.json(getErrorMessage('\'peers\'')); - return; - } if (!chaincodeName) { res.json(getErrorMessage('\'chaincodeName\'')); return; diff --git a/balance-transfer/app/helper.js b/balance-transfer/app/helper.js index 5cda95a9..8a227f74 100644 --- a/balance-transfer/app/helper.js +++ b/balance-transfer/app/helper.js @@ -24,10 +24,8 @@ var fs = require('fs-extra'); var User = require('fabric-client/lib/User.js'); var crypto = require('crypto'); var copService = require('fabric-ca-client'); -var config = require('../config.json'); var hfc = require('fabric-client'); -hfc.addConfigFile(path.join(__dirname, 'network-config.json')); hfc.setLogger(logger); var ORGS = hfc.getConfigSetting('network-config'); @@ -44,7 +42,7 @@ for (let key in ORGS) { cryptoSuite.setCryptoKeyStore(hfc.newCryptoKeyStore({path: getKeyStoreForOrg(ORGS[key].name)})); client.setCryptoSuite(cryptoSuite); - let channel = client.newChannel(config.channelName); + let channel = client.newChannel(hfc.getConfigSetting('channelName')); channel.addOrderer(newOrderer(client)); clients[key] = client; @@ -58,19 +56,18 @@ for (let key in ORGS) { } function setupPeers(channel, org, client) { - for (let key in ORGS[org]) { - if (key.indexOf('peer') === 0) { - let data = fs.readFileSync(path.join(__dirname, ORGS[org][key]['tls_cacerts'])); - let peer = client.newPeer( - ORGS[org][key].requests, - { - pem: Buffer.from(data).toString(), - 'ssl-target-name-override': ORGS[org][key]['server-hostname'] - } - ); + for (let key in ORGS[org].peers) { + let data = fs.readFileSync(path.join(__dirname, ORGS[org].peers[key]['tls_cacerts'])); + let peer = client.newPeer( + ORGS[org].peers[key].requests, + { + pem: Buffer.from(data).toString(), + 'ssl-target-name-override': ORGS[org].peers[key]['server-hostname'] + } + ); + peer.setName(key); - channel.addPeer(peer); - } + channel.addPeer(peer); } } @@ -78,7 +75,7 @@ function newOrderer(client) { var caRootsPath = ORGS.orderer.tls_cacerts; let data = fs.readFileSync(path.join(__dirname, caRootsPath)); let caroots = Buffer.from(data).toString(); - return client.newOrderer(config.orderer, { + return client.newOrderer(ORGS.orderer.url, { 'pem': caroots, 'ssl-target-name-override': ORGS.orderer['server-hostname'] }); @@ -100,60 +97,36 @@ function getOrgName(org) { } function getKeyStoreForOrg(org) { - return config.keyValueStore + '_' + org; + return hfc.getConfigSetting('keyValueStore') + '_' + org; } -function newRemotes(urls, forPeers, userOrg) { - var targets = []; - // find the peer that match the urls - outer: - for (let index in urls) { - let peerUrl = urls[index]; +function newRemotes(names, forPeers, userOrg) { + let client = getClientForOrg(userOrg); - let found = false; - for (let key in ORGS) { - if (key.indexOf('org') === 0) { - // if looking for event hubs, an app can only connect to - // event hubs in its own org - if (!forPeers && key !== userOrg) { - continue; - } + let targets = []; + // find the peer that match the names + for (let idx in names) { + let peerName = names[idx]; + if (ORGS[userOrg].peers[peerName]) { + // found a peer matching the name + let data = fs.readFileSync(path.join(__dirname, ORGS[userOrg].peers[peerName]['tls_cacerts'])); + let grpcOpts = { + pem: Buffer.from(data).toString(), + 'ssl-target-name-override': ORGS[userOrg].peers[peerName]['server-hostname'] + }; - 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(), - 'ssl-target-name-override': org[prop]['server-hostname'] - })); - - continue outer; - } else { - let eh = client.newEventHub(); - let data = fs.readFileSync(path.join(__dirname, org[prop]['tls_cacerts'])); - eh.setPeerAddr(org[prop]['events'], { - pem: Buffer.from(data).toString(), - 'ssl-target-name-override': org[prop]['server-hostname'] - }); - targets.push(eh); - - continue outer; - } - } - } - } + if (forPeers) { + targets.push(client.newPeer(ORGS[userOrg].peers[peerName].requests, grpcOpts)); + } else { + let eh = client.newEventHub(); + eh.setPeerAddr(ORGS[userOrg].peers[peerName].events, grpcOpts); + targets.push(eh); } } + } - if (!found) { - logger.error(util.format('Failed to find a peer matching the url %s', peerUrl)); - } + if (targets.length === 0) { + logger.error(util.format('Failed to find peers matching the names %s', names)); } return targets; @@ -170,12 +143,12 @@ var getClientForOrg = function(org) { return clients[org]; }; -var newPeers = function(urls) { - return newRemotes(urls, true); +var newPeers = function(names, org) { + return newRemotes(names, true, org); }; -var newEventHubs = function(urls, org) { - return newRemotes(urls, false, org); +var newEventHubs = function(names, org) { + return newRemotes(names, false, org); }; var getMspID = function(org) { @@ -184,7 +157,7 @@ var getMspID = function(org) { }; var getAdminUser = function(userOrg) { - var users = config.users; + var users = hfc.getConfigSetting('admins'); var username = users[0].username; var password = users[0].secret; var member; @@ -325,7 +298,7 @@ var getOrgAdmin = function(userOrg) { }; 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) { @@ -334,11 +307,6 @@ var getLogger = function(moduleName) { return logger; }; -var getPeerAddressByName = function(org, peer) { - var address = ORGS[org][peer].requests; - return address.split('grpcs://')[1]; -}; - exports.getChannelForOrg = getChannelForOrg; exports.getClientForOrg = getClientForOrg; exports.getLogger = getLogger; @@ -347,6 +315,5 @@ exports.getMspID = getMspID; exports.ORGS = ORGS; exports.newPeers = newPeers; exports.newEventHubs = newEventHubs; -exports.getPeerAddressByName = getPeerAddressByName; exports.getRegisteredUsers = getRegisteredUsers; exports.getOrgAdmin = getOrgAdmin; diff --git a/balance-transfer/app/install-chaincode.js b/balance-transfer/app/install-chaincode.js index 591b4c7a..6f72b6d7 100644 --- a/balance-transfer/app/install-chaincode.js +++ b/balance-transfer/app/install-chaincode.js @@ -32,7 +32,7 @@ var installChaincode = function(peers, chaincodeName, chaincodePath, return helper.getOrgAdmin(org).then((user) => { var request = { - targets: helper.newPeers(peers), + targets: helper.newPeers(peers, org), chaincodePath: chaincodePath, chaincodeId: chaincodeName, chaincodeVersion: chaincodeVersion @@ -47,8 +47,8 @@ var installChaincode = function(peers, chaincodeName, chaincodePath, var all_good = true; for (var i in proposalResponses) { let one_good = false; - if (proposalResponses && proposalResponses[0].response && - proposalResponses[0].response.status === 200) { + if (proposalResponses && proposalResponses[i].response && + proposalResponses[i].response.status === 200) { one_good = true; logger.info('install proposal was good'); } else { diff --git a/balance-transfer/app/instantiate-chaincode.js b/balance-transfer/app/instantiate-chaincode.js index 199f139e..437b904f 100644 --- a/balance-transfer/app/instantiate-chaincode.js +++ b/balance-transfer/app/instantiate-chaincode.js @@ -20,10 +20,8 @@ var util = require('util'); var hfc = require('fabric-client'); var Peer = require('fabric-client/lib/Peer.js'); var EventHub = require('fabric-client/lib/EventHub.js'); -var config = require('../config.json'); var helper = require('./helper.js'); var logger = helper.getLogger('instantiate-chaincode'); -hfc.addConfigFile(path.join(__dirname, 'network-config.json')); var ORGS = hfc.getConfigSetting('network-config'); var tx_id = null; var eh = null; @@ -49,10 +47,13 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion var request = { chaincodeId: chaincodeName, chaincodeVersion: chaincodeVersion, - fcn: functionName, args: args, txId: tx_id }; + + if (functionName) + request.fcn = functionName; + return channel.sendInstantiateProposal(request); }, (err) => { logger.error('Failed to initialize the channel'); @@ -63,8 +64,8 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion var all_good = true; for (var i in proposalResponses) { let one_good = false; - if (proposalResponses && proposalResponses[0].response && - proposalResponses[0].response.status === 200) { + if (proposalResponses && proposalResponses[i].response && + proposalResponses[i].response.status === 200) { one_good = true; logger.info('instantiate proposal was good'); } else { @@ -88,12 +89,12 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion var deployId = tx_id.getTransactionID(); 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' ])); - eh.setPeerAddr(ORGS[org]['peer1']['events'], { + eh.setPeerAddr(ORGS[org].peers['peer1']['events'], { 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(); @@ -145,7 +146,7 @@ var instantiateChaincode = function(channelName, chaincodeName, chaincodeVersion }).then((response) => { if (response.status === 'SUCCESS') { logger.info('Successfully sent transaction to the orderer.'); - return 'Chaincode Instantiateion is SUCCESS'; + return 'Chaincode Instantiation is SUCCESS'; } else { logger.error('Failed to order the transaction. Error code: ' + response.status); return 'Failed to order the transaction. Error code: ' + response.status; diff --git a/balance-transfer/app/invoke-transaction.js b/balance-transfer/app/invoke-transaction.js index fa4202dd..2a63d7fb 100644 --- a/balance-transfer/app/invoke-transaction.js +++ b/balance-transfer/app/invoke-transaction.js @@ -19,18 +19,16 @@ var fs = require('fs'); var util = require('util'); var hfc = require('fabric-client'); var Peer = require('fabric-client/lib/Peer.js'); -var config = require('../config.json'); var helper = require('./helper.js'); var logger = helper.getLogger('invoke-chaincode'); var EventHub = require('fabric-client/lib/EventHub.js'); -hfc.addConfigFile(path.join(__dirname, 'network-config.json')); 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)); var client = helper.getClientForOrg(org); var channel = helper.getChannelForOrg(org); - var targets = helper.newPeers(peersUrls); + var targets = (peerNames) ? helper.newPeers(peerNames, org) : undefined; var tx_id = null; 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)); // send proposal to endorser var request = { - targets: targets, chaincodeId: chaincodeName, fcn: fcn, args: args, chainId: channelName, txId: tx_id }; + + if (targets) + request.targets = targets; + return channel.sendTransactionProposal(request); }, (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; for (var i in proposalResponses) { let one_good = false; - if (proposalResponses && proposalResponses[0].response && - proposalResponses[0].response.status === 200) { + if (proposalResponses && proposalResponses[i].response && + proposalResponses[i].response.status === 200) { one_good = true; logger.info('transaction proposal was good'); } else { @@ -80,7 +81,13 @@ var invokeChaincode = function(peersUrls, channelName, chaincodeName, fcn, args, var transactionID = tx_id.getTransactionID(); 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) { let eh = eventhubs[key]; eh.connect(); diff --git a/balance-transfer/app/join-channel.js b/balance-transfer/app/join-channel.js index cb86a8e4..5e174c9a 100644 --- a/balance-transfer/app/join-channel.js +++ b/balance-transfer/app/join-channel.js @@ -67,27 +67,16 @@ var joinChannel = function(channelName, peers, username, org) { }).then((genesis_block) => { tx_id = client.newTransactionID(); var request = { - targets: helper.newPeers(peers), + targets: helper.newPeers(peers, org), txId: tx_id, block: genesis_block }; - for (let key in ORGS[org]) { - if (ORGS[org].hasOwnProperty(key)) { - if (key.indexOf('peer') === 0) { - 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(); - eventhubs.push(eh); - allEventhubs.push(eh); - } - } + eventhubs = helper.newEventHubs(peers, org); + for (let key in eventhubs) { + let eh = eventhubs[key]; + eh.connect(); + allEventhubs.push(eh); } var eventPromises = []; diff --git a/balance-transfer/app/network-config-aws.json b/balance-transfer/app/network-config-aws.json new file mode 100644 index 00000000..310cfbe9 --- /dev/null +++ b/balance-transfer/app/network-config-aws.json @@ -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" + } + } + } +} diff --git a/balance-transfer/app/network-config.json b/balance-transfer/app/network-config.json index b305d20a..80289fa7 100644 --- a/balance-transfer/app/network-config.json +++ b/balance-transfer/app/network-config.json @@ -9,17 +9,19 @@ "name": "peerOrg1", "mspid": "Org1MSP", "ca": "https://localhost:7054", - "peer1": { - "requests": "grpcs://localhost:7051", - "events": "grpcs://localhost: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": "grpcs://localhost:7056", - "events": "grpcs://localhost: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" + "peers": { + "peer1": { + "requests": "grpcs://localhost:7051", + "events": "grpcs://localhost: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": "grpcs://localhost:7056", + "events": "grpcs://localhost: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", @@ -30,17 +32,19 @@ "name": "peerOrg2", "mspid": "Org2MSP", "ca": "https://localhost:8054", - "peer1": { - "requests": "grpcs://localhost:8051", - "events": "grpcs://localhost: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": "grpcs://localhost:8056", - "events": "grpcs://localhost: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" + "peers": { + "peer1": { + "requests": "grpcs://localhost:8051", + "events": "grpcs://localhost: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": "grpcs://localhost:8056", + "events": "grpcs://localhost: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", diff --git a/balance-transfer/app/query.js b/balance-transfer/app/query.js index ddf2eddf..ef8676b1 100644 --- a/balance-transfer/app/query.js +++ b/balance-transfer/app/query.js @@ -261,7 +261,7 @@ var getChannels = function(peer, username, org) { function buildTarget(peer, org) { var target = null; 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]; } diff --git a/balance-transfer/config.js b/balance-transfer/config.js new file mode 100644 index 00000000..3ff928f7 --- /dev/null +++ b/balance-transfer/config.js @@ -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')); \ No newline at end of file diff --git a/balance-transfer/config.json b/balance-transfer/config.json index e490a04f..d2fe9c0b 100644 --- a/balance-transfer/config.json +++ b/balance-transfer/config.json @@ -3,11 +3,10 @@ "port":"4000", "jwt_expiretime": "36000", "channelName":"mychannel", - "GOPATH":"../artifacts", + "CC_SRC_PATH":"../artifacts", "keyValueStore":"/tmp/fabric-client-kvs", "eventWaitTime":"30000", - "orderer":"grpcs://localhost:7050", - "users":[ + "admins":[ { "username":"admin", "secret":"adminpw" diff --git a/balance-transfer/package.json b/balance-transfer/package.json index 555cfc34..f95a80be 100644 --- a/balance-transfer/package.json +++ b/balance-transfer/package.json @@ -2,15 +2,18 @@ "name": "balance-transfer", "version": "1.0.0", "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": [ "fabric-client sample app", "balance-transfer node sample", "v1.0 fabric nodesdk sample" ], "engines": { - "node": ">=6.9.5", - "npm": ">=3.10.10" + "node": ">=6.9.5 <7.0", + "npm": ">=3.10.10 <4.0" }, "license": "Apache-2.0", "dependencies": { diff --git a/balance-transfer/testAPIs.sh b/balance-transfer/testAPIs.sh index 737238f0..ab0d7eb8 100755 --- a/balance-transfer/testAPIs.sh +++ b/balance-transfer/testAPIs.sh @@ -56,7 +56,7 @@ curl -s -X POST \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:7051","localhost:7056"] + "peers": ["peer1","peer2"] }' echo echo @@ -68,7 +68,7 @@ curl -s -X POST \ -H "authorization: Bearer $ORG2_TOKEN" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:8051","localhost:8056"] + "peers": ["peer1","peer2"] }' echo echo @@ -80,7 +80,7 @@ curl -s -X POST \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:7051","localhost:7056"], + "peers": ["peer1", "peer2"], "chaincodeName":"mycc", "chaincodePath":"github.com/example_cc", "chaincodeVersion":"v0" @@ -96,7 +96,7 @@ curl -s -X POST \ -H "authorization: Bearer $ORG2_TOKEN" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:8051","localhost:8056"], + "peers": ["peer1","peer2"], "chaincodeName":"mycc", "chaincodePath":"github.com/example_cc", "chaincodeVersion":"v0" @@ -113,7 +113,6 @@ curl -s -X POST \ -d '{ "chaincodeName":"mycc", "chaincodeVersion":"v0", - "functionName":"init", "args":["a","100","b","200"] }' echo @@ -126,7 +125,6 @@ TRX_ID=$(curl -s -X POST \ -H "authorization: Bearer $ORG1_TOKEN" \ -H "content-type: application/json" \ -d '{ - "peers": ["localhost:7051", "localhost:8051"], "fcn":"move", "args":["a","b","10"] }') diff --git a/basic-network/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem b/basic-network/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem index 35b927ae..91cc85e8 100644 --- a/basic-network/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem +++ b/basic-network/crypto-config/peerOrganizations/org1.example.com/ca/org1.example.com-cert.pem @@ -1,14 +1,14 @@ -----BEGIN CERTIFICATE----- -MIICFzCCAb2gAwIBAgIUTtBERRtj53mS3poZ2N1Enigcf3wwCgYIKoZIzj0EAwIw +MIICFjCCAb2gAwIBAgIUK7b5iTNHRYriNccrvzxXjYvXENkwCgYIKoZIzj0EAwIw aDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMt -Y2Etc2VydmVyMB4XDTE3MDYyOTE5MzIwMFoXDTMyMDYyNTE5MzIwMFowaDELMAkG +Y2Etc2VydmVyMB4XDTE3MDgwNjA5NDMwMFoXDTMyMDgwMjA5NDMwMFowaDELMAkG A1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQKEwtIeXBl cmxlZGdlcjEPMA0GA1UECxMGRmFicmljMRkwFwYDVQQDExBmYWJyaWMtY2Etc2Vy -dmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEH8fsI6vVIVn2j3jXpwKkM79/ -LGy0Z9UeHA0JQcbAhOMaf5w+arqXgw+ZQkASAfaoRjozYZA39jSS/EE1XZI6HqNF +dmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvbZZ9gSMveMg6dQ2f3hGRE4Q +JE++GbwJXYCjiwqDt9xJ4s/wuLhOEqKzYkhntdvLaUH5zJWFRyy/5LQ5BV2/AKNF MEMwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYE -FBo/MF+TauY0epUtCphNSvUDTX1EMAoGCCqGSM49BAMCA0gAMEUCIQCM21QC+8ru -8M4LwF8aTMyzpoYm1UqX8ndhrwYpcglATgIgd67Lr3baI+NQoM1G8hNpTe2+OUoS -H/fG3eOymx90eOE= +FPDCv6nfcXF2u42xfz/l4bKjjWrkMAoGCCqGSM49BAMCA0cAMEQCIAOrX7gTfZF5 +5s0jhv/niBAgCFrZqNcmVqLI2ycPyZ1QAiBeguVoBfUfZ6saQDNqyzm55rwoUNhl +1jnpnbjkbup3wA== -----END CERTIFICATE----- diff --git a/basic-network/docker-compose.yml b/basic-network/docker-compose.yml index 407e1e9f..b15b14e9 100644 --- a/basic-network/docker-compose.yml +++ b/basic-network/docker-compose.yml @@ -74,6 +74,7 @@ services: - ./config:/etc/hyperledger/configtx depends_on: - orderer.example.com + - couchdb networks: - basic @@ -82,8 +83,6 @@ services: image: hyperledger/fabric-couchdb:x86_64-1.0.0 ports: - 5984:5984 - environment: - DB_URL: http://localhost:5984/member_db networks: - basic diff --git a/basic-network/start.sh b/basic-network/start.sh index 88aea6df..246605bd 100755 --- a/basic-network/start.sh +++ b/basic-network/start.sh @@ -7,6 +7,9 @@ # Exit on first error, print all commands. 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 up -d ca.example.com orderer.example.com peer0.org1.example.com couchdb diff --git a/fabcar/startFabric.sh b/fabcar/startFabric.sh index f7680168..fd763367 100755 --- a/fabcar/startFabric.sh +++ b/fabcar/startFabric.sh @@ -7,6 +7,9 @@ # Exit on first error set -e +# don't rewrite paths for Windows Git Bash users +export MSYS_NO_PATHCONV=1 + starttime=$(date +%s) if [ ! -d ~/.hfc-key-store/ ]; then diff --git a/first-network/byfn.sh b/first-network/byfn.sh index 04436ed9..aa8c988f 100755 --- a/first-network/byfn.sh +++ b/first-network/byfn.sh @@ -1,5 +1,6 @@ #!/bin/bash -# + +# # Copyright IBM Corp All Rights Reserved # # SPDX-License-Identifier: Apache-2.0 @@ -34,7 +35,7 @@ export FABRIC_CFG_PATH=${PWD} # Print the usage message function printHelp () { echo "Usage: " - echo " byfn.sh -m up|down|restart|generate [-c ] [-t ]" + echo " byfn.sh -m up|down|restart|generate [-c ] [-t ] [-d ] [-f ] [-s ]" echo " byfn.sh -h|--help (print this message)" echo " -m - one of 'up', 'down', 'restart' or 'generate'" 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 " -c - channel name to use (defaults to \"mychannel\")" echo " -t - CLI timeout duration in microseconds (defaults to 10000)" + echo " -d - delay duration in seconds (defaults to 3)" + echo " -f - specify which docker-compose file use (defaults to docker-compose-cli.yaml)" + echo " -s - the database backend to use: goleveldb (default) or couchdb" echo echo "Typically, one would first generate the required certificates and " echo "genesis block, then bring up the network. e.g.:" echo - echo " byfn.sh -m generate -c " - echo " byfn.sh -m up -c " - echo " byfn.sh -m down -c " + echo " byfn.sh -m generate -c mychannel" + echo " byfn.sh -m up -c mychannel -s couchdb" + echo " byfn.sh -m down -c mychannel" echo echo "Taking all defaults:" echo " byfn.sh -m generate" @@ -106,7 +110,12 @@ function networkUp () { replacePrivateKey generateChannelArtifacts 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 echo "ERROR !!!! Unable to start network" docker logs -f cli @@ -118,6 +127,7 @@ function networkUp () { # Tear down running network function networkDown () { docker-compose -f $COMPOSE_FILE down + docker-compose -f $COMPOSE_FILE -f $COMPOSE_FILE_COUCH down # Don't remove containers, images, etc if restarting if [ "$MODE" != "restart" ]; then #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 # another container before giving up CLI_TIMEOUT=10000 +#default for delay +CLI_DELAY=3 # channel name defaults to "mychannel" CHANNEL_NAME="mychannel" # use this as the default docker-compose yaml definition COMPOSE_FILE=docker-compose-cli.yaml +# +COMPOSE_FILE_COUCH=docker-compose-couch.yaml # 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 h|\?) printHelp @@ -313,6 +327,12 @@ while getopts "h?m:c:t:" opt; do ;; t) CLI_TIMEOUT=$OPTARG ;; + d) CLI_DELAY=$OPTARG + ;; + f) COMPOSE_FILE=$OPTARG + ;; + s) IF_COUCHDB=$OPTARG + ;; esac done @@ -331,8 +351,13 @@ else fi # 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 askProceed @@ -341,7 +366,7 @@ if [ "${MODE}" == "up" ]; then networkUp elif [ "${MODE}" == "down" ]; then ## Clear the network networkDown -elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts + elif [ "${MODE}" == "generate" ]; then ## Generate Artifacts generateCerts replacePrivateKey generateChannelArtifacts diff --git a/first-network/docker-compose-cli.yaml b/first-network/docker-compose-cli.yaml index 28e4b66e..25e64800 100644 --- a/first-network/docker-compose-cli.yaml +++ b/first-network/docker-compose-cli.yaml @@ -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_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 - command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME}; sleep $TIMEOUT' + command: /bin/bash -c './scripts/script.sh ${CHANNEL_NAME} ${DELAY}; sleep $TIMEOUT' volumes: - /var/run/:/host/var/run/ - ./../chaincode/:/opt/gopath/src/github.com/hyperledger/fabric/examples/chaincode/go diff --git a/first-network/scripts/script.sh b/first-network/scripts/script.sh index a49fbb73..43a308ed 100755 --- a/first-network/scripts/script.sh +++ b/first-network/scripts/script.sh @@ -10,6 +10,7 @@ echo echo "Build your first network (BYFN) end-to-end test" echo CHANNEL_NAME="$1" +DELAY="$2" : ${CHANNEL_NAME:="mychannel"} : ${TIMEOUT:="60"} COUNTER=1 @@ -82,6 +83,7 @@ updateAnchorPeers() { cat log.txt verifyResult $res "Anchor peer update failed" echo "===================== Anchor peers for org \"$CORE_PEER_LOCALMSPID\" on \"$CHANNEL_NAME\" is updated successfully ===================== " + sleep $DELAY echo } @@ -93,7 +95,7 @@ joinWithRetry () { if [ $res -ne 0 -a $COUNTER -lt $MAX_RETRY ]; then COUNTER=` expr $COUNTER + 1` echo "PEER$1 failed to join the channel, Retry after 2 seconds" - sleep 2 + sleep $DELAY joinWithRetry $1 else COUNTER=1 @@ -106,7 +108,7 @@ joinChannel () { setGlobals $ch joinWithRetry $ch echo "===================== PEER$ch joined on the channel \"$CHANNEL_NAME\" ===================== " - sleep 2 + sleep $DELAY echo done } @@ -150,7 +152,7 @@ chaincodeQuery () { # we either get a successful response, or reach TIMEOUT while test "$(($(date +%s)-starttime))" -lt "$TIMEOUT" -a $rc -ne 0 do - sleep 3 + sleep $DELAY echo "Attempting to Query PEER$PEER ...$(($(date +%s)-starttime)) secs" 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}') diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 00000000..4dce8de6 --- /dev/null +++ b/scripts/README.md @@ -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] +``` + +Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License diff --git a/scripts/fabric-preload.sh b/scripts/fabric-preload.sh new file mode 100755 index 00000000..a88963ed --- /dev/null +++ b/scripts/fabric-preload.sh @@ -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* +