[FAB-6568] Fabric-Samples - update fabcar

Update the fabcar sample with an easier flow
Remove hardcoded fields in the invoke program

Change-Id: I9a06cdd317c2afec80720ac7d728d38fc62c6f63
Signed-off-by: Bret Harrison <beharrison@nc.rr.com>
Signed-off-by: Nick Gaski <ngaski@us.ibm.com>
This commit is contained in:
Bret Harrison 2017-10-19 20:22:03 -04:00
parent cd1b691385
commit 6b2799e620
10 changed files with 369 additions and 211 deletions

View file

@ -14,9 +14,11 @@ services:
environment: environment:
- FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server - FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server
- FABRIC_CA_SERVER_CA_NAME=ca.example.com - FABRIC_CA_SERVER_CA_NAME=ca.example.com
- FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem
- FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/4239aa0dcd76daeeb8ba0cda701851d14504d31aad1b2ddddbac6a57365e497c_sk
ports: ports:
- "7054:7054" - "7054:7054"
command: sh -c 'fabric-ca-server start --ca.certfile /etc/hyperledger/fabric-ca-server-config/org1.example.com-cert.pem --ca.keyfile /etc/hyperledger/fabric-ca-server-config/a22daf356b2aab5792ea53e35f66fccef1d7f1aa2b3a2b92dbfbf96a448ea26a_sk -b admin:adminpw -d' command: sh -c 'fabric-ca-server start -b admin:adminpw -d'
volumes: volumes:
- ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config - ./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config
container_name: ca.example.com container_name: ca.example.com

View file

@ -1 +0,0 @@
{"name":"PeerAdmin","mspid":"Org1MSP","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"signingIdentity":"cd96d5260ad4757551ed4a5a991e62130f8008a0bf996e4e4b84cd097a747fec","identity":{"certificate":"-----BEGIN CERTIFICATE-----\nMIICGDCCAb+gAwIBAgIQFSxnLAGsu04zrFkAEwzn6zAKBggqhkjOPQQDAjBzMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu\nb3JnMS5leGFtcGxlLmNvbTAeFw0xNzA4MzEwOTE0MzJaFw0yNzA4MjkwOTE0MzJa\nMFsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T\nYW4gRnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkw\nEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEV1dfmKxsFKWo7o6DNBIaIVebCCPAM9C/\nsLBt4pJRre9pWE987DjXZoZ3glc4+DoPMtTmBRqbPVwYcUvpbYY8p6NNMEswDgYD\nVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAgQjmqDc122u64\nugzacBhR0UUE0xqtGy3d26xqVzZeSXwwCgYIKoZIzj0EAwIDRwAwRAIgXMy26AEU\n/GUMPfCMs/nQjQME1ZxBHAYZtKEuRR361JsCIEg9BOZdIoioRivJC+ZUzvJUnkXu\no2HkWiuxLsibGxtE\n-----END CERTIFICATE-----\n"}}}

View file

@ -1,5 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgRgQr347ij6cjwX7m
KjzbbD8Tlwdfu6FaubjWJWLGyqahRANCAARXV1+YrGwUpajujoM0EhohV5sII8Az
0L+wsG3iklGt72lYT3zsONdmhneCVzj4Og8y1OYFGps9XBhxS+lthjyn
-----END PRIVATE KEY-----

View file

@ -1,14 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICGDCCAb+gAwIBAgIQFSxnLAGsu04zrFkAEwzn6zAKBggqhkjOPQQDAjBzMQsw
CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy
YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eu
b3JnMS5leGFtcGxlLmNvbTAeFw0xNzA4MzEwOTE0MzJaFw0yNzA4MjkwOTE0MzJa
MFsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1T
YW4gRnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkw
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEV1dfmKxsFKWo7o6DNBIaIVebCCPAM9C/
sLBt4pJRre9pWE987DjXZoZ3glc4+DoPMtTmBRqbPVwYcUvpbYY8p6NNMEswDgYD
VR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwKwYDVR0jBCQwIoAgQjmqDc122u64
ugzacBhR0UUE0xqtGy3d26xqVzZeSXwwCgYIKoZIzj0EAwIDRwAwRAIgXMy26AEU
/GUMPfCMs/nQjQME1ZxBHAYZtKEuRR361JsCIEg9BOZdIoioRivJC+ZUzvJUnkXu
o2HkWiuxLsibGxtE
-----END CERTIFICATE-----

75
fabcar/enrollAdmin.js Normal file
View file

@ -0,0 +1,75 @@
'use strict';
/*
* Copyright IBM Corp All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Enroll the admin user
*/
var Fabric_Client = require('fabric-client');
var Fabric_CA_Client = require('fabric-ca-client');
var path = require('path');
var util = require('util');
var os = require('os');
//
var fabric_client = new Fabric_Client();
var fabric_ca_client = null;
var admin_user = null;
var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store');
console.log(' Store path:'+store_path);
// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
Fabric_Client.newDefaultKeyValueStore({ path: store_path
}).then((state_store) => {
// assign the store to the fabric client
fabric_client.setStateStore(state_store);
var crypto_suite = Fabric_Client.newCryptoSuite();
// use the same location for the state store (where the users' certificate are kept)
// and the crypto store (where the users' keys are kept)
var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);
var tlsOptions = {
trustedRoots: [],
verify: false
};
// be sure to change the http to https when the CA is running TLS enabled
fabric_ca_client = new Fabric_CA_Client('http://localhost:7054', tlsOptions , 'ca.example.com', crypto_suite);
// first check to see if the admin is already enrolled
return fabric_client.getUserContext('admin', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded admin from persistence');
admin_user = user_from_store;
return null;
} else {
// need to enroll it with CA server
return fabric_ca_client.enroll({
enrollmentID: 'admin',
enrollmentSecret: 'adminpw'
}).then((enrollment) => {
console.log('Successfully enrolled admin user "admin"');
return fabric_client.createUser(
{username: 'admin',
mspid: 'Org1MSP',
cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
});
}).then((user) => {
admin_user = user;
return fabric_client.setUserContext(admin_user);
}).catch((err) => {
console.error('Failed to enroll and persist admin. Error: ' + err.stack ? err.stack : err);
throw new Error('Failed to enroll admin');
});
}
}).then(() => {
console.log('Assigned the admin user to the fabric client ::' + admin_user.toString());
}).catch((err) => {
console.error('Failed to enroll admin: ' + err);
});

View file

@ -8,145 +8,154 @@
* Chaincode Invoke * Chaincode Invoke
*/ */
var hfc = require('fabric-client'); var Fabric_Client = require('fabric-client');
var path = require('path'); var path = require('path');
var util = require('util'); var util = require('util');
var os = require('os');
var options = { //
wallet_path: path.join(__dirname, './creds'), var fabric_client = new Fabric_Client();
user_id: 'PeerAdmin',
channel_id: 'mychannel',
chaincode_id: 'fabcar',
peer_url: 'grpc://localhost:7051',
event_url: 'grpc://localhost:7053',
orderer_url: 'grpc://localhost:7050'
};
var channel = {}; // setup the fabric network
var client = null; var channel = fabric_client.newChannel('mychannel');
var targets = []; var peer = fabric_client.newPeer('grpc://localhost:7051');
channel.addPeer(peer);
var order = fabric_client.newOrderer('grpc://localhost:7050')
channel.addOrderer(order);
//
var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store');
console.log('Store path:'+store_path);
var tx_id = null; var tx_id = null;
Promise.resolve().then(() => {
console.log("Create a client and set the wallet location"); // create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
client = new hfc(); Fabric_Client.newDefaultKeyValueStore({ path: store_path
return hfc.newDefaultKeyValueStore({ path: options.wallet_path }); }).then((state_store) => {
}).then((wallet) => { // assign the store to the fabric client
console.log("Set wallet path, and associate user ", options.user_id, " with application"); fabric_client.setStateStore(state_store);
client.setStateStore(wallet); var crypto_suite = Fabric_Client.newCryptoSuite();
return client.getUserContext(options.user_id, true); // use the same location for the state store (where the users' certificate are kept)
}).then((user) => { // and the crypto store (where the users' keys are kept)
console.log("Check user is enrolled, and set a query URL in the network"); var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
if (user === undefined || user.isEnrolled() === false) { crypto_suite.setCryptoKeyStore(crypto_store);
console.error("User not defined, or not enrolled - error"); fabric_client.setCryptoSuite(crypto_suite);
}
channel = client.newChannel(options.channel_id); // get the enrolled user from persistence, this user will sign all requests
var peerObj = client.newPeer(options.peer_url); return fabric_client.getUserContext('user1', true);
channel.addPeer(peerObj); }).then((user_from_store) => {
channel.addOrderer(client.newOrderer(options.orderer_url)); if (user_from_store && user_from_store.isEnrolled()) {
targets.push(peerObj); console.log('Successfully loaded user1 from persistence');
return; member_user = user_from_store;
}).then(() => { } else {
tx_id = client.newTransactionID(); throw new Error('Failed to get user1.... run registerUser.js');
console.log("Assigning transaction_id: ", tx_id._transaction_id); }
// createCar - requires 5 args, ex: args: ['CAR11', 'Honda', 'Accord', 'Black', 'Tom'],
// changeCarOwner - requires 2 args , ex: args: ['CAR10', 'Barry'], // get a transaction id object based on the current user assigned to fabric client
// send proposal to endorser tx_id = fabric_client.newTransactionID();
var request = { console.log("Assigning transaction_id: ", tx_id._transaction_id);
targets: targets,
chaincodeId: options.chaincode_id, // createCar chaincode function - requires 5 args, ex: args: ['CAR12', 'Honda', 'Accord', 'Black', 'Tom'],
fcn: 'createCar', // changeCarOwner chaincode function - requires 2 args , ex: args: ['CAR10', 'Barry'],
args: ['CAR10', 'Chevy', 'Volt', 'Red', 'Nick'], // must send the proposal to endorsing peers
chainId: options.channel_id, var request = {
txId: tx_id //targets: let default to the peer assigned to the client
}; chaincodeId: 'fabcar',
return channel.sendTransactionProposal(request); fcn: '',
args: [''],
chainId: 'mychannel',
txId: tx_id
};
// send the transaction proposal to the peers
return channel.sendTransactionProposal(request);
}).then((results) => { }).then((results) => {
var proposalResponses = results[0]; var proposalResponses = results[0];
var proposal = results[1]; var proposal = results[1];
var header = results[2]; let isProposalGood = false;
let isProposalGood = false; if (proposalResponses && proposalResponses[0].response &&
if (proposalResponses && proposalResponses[0].response && proposalResponses[0].response.status === 200) {
proposalResponses[0].response.status === 200) { isProposalGood = true;
isProposalGood = true; console.log('Transaction proposal was good');
console.log('transaction proposal was good'); } else {
} else { console.error('Transaction proposal was bad');
console.error('transaction proposal was bad'); }
} if (isProposalGood) {
if (isProposalGood) { console.log(util.format(
console.log(util.format( 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s"',
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s', proposalResponses[0].response.status, proposalResponses[0].response.message));
proposalResponses[0].response.status, proposalResponses[0].response.message,
proposalResponses[0].response.payload, proposalResponses[0].endorsement.signature));
var request = {
proposalResponses: proposalResponses,
proposal: proposal,
header: header
};
// set the transaction listener and set a timeout of 30sec
// if the transaction did not get committed within the timeout period,
// fail the test
var transactionID = tx_id.getTransactionID();
var eventPromises = [];
let eh = client.newEventHub();
eh.setPeerAddr(options.event_url);
eh.connect();
let txPromise = new Promise((resolve, reject) => { // build up the request for the orderer to have the transaction committed
let handle = setTimeout(() => { var request = {
eh.disconnect(); proposalResponses: proposalResponses,
reject(); proposal: proposal
}, 30000); };
eh.registerTxEvent(transactionID, (tx, code) => { // set the transaction listener and set a timeout of 30 sec
clearTimeout(handle); // if the transaction did not get committed within the timeout period,
eh.unregisterTxEvent(transactionID); // report a TIMEOUT status
eh.disconnect(); var transaction_id_string = tx_id.getTransactionID(); //Get the transaction ID string to be used by the event processing
var promises = [];
if (code !== 'VALID') { var sendPromise = channel.sendTransaction(request);
console.error( promises.push(sendPromise); //we want the send transaction first, so that we know where to check status
'The transaction was invalid, code = ' + code);
reject(); // get an eventhub once the fabric client has a user assigned. The user
} else { // is required bacause the event registration must be signed
console.log( let event_hub = fabric_client.newEventHub();
'The transaction has been committed on peer ' + event_hub.setPeerAddr('grpc://localhost:7053');
eh._ep._endpoint.addr);
resolve(); // using resolve the promise so that result status may be processed
} // under the then clause rather than having the catch clause process
}); // the status
}); let txPromise = new Promise((resolve, reject) => {
eventPromises.push(txPromise); let handle = setTimeout(() => {
var sendPromise = channel.sendTransaction(request); event_hub.disconnect();
return Promise.all([sendPromise].concat(eventPromises)).then((results) => { resolve({event_status : 'TIMEOUT'}); //we could use reject(new Error('Trnasaction did not complete within 30 seconds'));
console.log(' event promise all complete and testing complete'); }, 3000);
return results[0]; // the first returned value is from the 'sendPromise' which is from the 'sendTransaction()' call event_hub.connect();
}).catch((err) => { event_hub.registerTxEvent(transaction_id_string, (tx, code) => {
console.error( // this is the callback for transaction event status
'Failed to send transaction and get notifications within the timeout period.' // first some clean up of event listener
); clearTimeout(handle);
return 'Failed to send transaction and get notifications within the timeout period.'; event_hub.unregisterTxEvent(transaction_id_string);
}); event_hub.disconnect();
} else {
console.error( // now let the application know what happened
'Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...' var return_status = {event_status : code, tx_id : transaction_id_string};
); if (code !== 'VALID') {
return 'Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...'; console.error('The transaction was invalid, code = ' + code);
} resolve(return_status); // we could use reject(new Error('Problem with the tranaction, event status ::'+code));
}, (err) => { } else {
console.error('Failed to send proposal due to error: ' + err.stack ? err.stack : console.log('The transaction has been committed on peer ' + event_hub._ep._endpoint.addr);
err); resolve(return_status);
return 'Failed to send proposal due to error: ' + err.stack ? err.stack : }
err; }, (err) => {
}).then((response) => { //this is the callback if something goes wrong with the event registration or processing
if (response.status === 'SUCCESS') { reject(new Error('There was a problem with the eventhub ::'+err));
console.log('Successfully sent transaction to the orderer.'); });
return tx_id.getTransactionID(); });
} else { promises.push(txPromise);
console.error('Failed to order the transaction. Error code: ' + response.status);
return 'Failed to order the transaction. Error code: ' + response.status; return Promise.all(promises);
} } else {
}, (err) => { console.error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...');
console.error('Failed to send transaction due to error: ' + err.stack ? err throw new Error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...');
.stack : err); }
return 'Failed to send transaction due to error: ' + err.stack ? err.stack : }).then((results) => {
err; console.log('Send transaction promise and event listener promise have completed');
// check the results in the order the promises were added to the promise all list
if (results && results[0] && results[0].status === 'SUCCESS') {
console.log('Successfully sent transaction to the orderer.');
} else {
console.error('Failed to order the transaction. Error code: ' + response.status);
}
if(results && results[1] && results[1].event_status === 'VALID') {
console.log('Successfully committed the change to the ledger by the peer');
} else {
console.log('Transaction failed to be committed to the ledger due to ::'+results[1].event_status);
}
}).catch((err) => {
console.error('Failed to invoke successfully :: ' + err);
}); });

View file

@ -7,8 +7,9 @@
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
}, },
"dependencies": { "dependencies": {
"fabric-ca-client": "unstable", "fabric-ca-client": "^1.0.2",
"fabric-client": "unstable" "fabric-client": "^1.0.2",
"grpc": "^1.6.0"
}, },
"author": "Anthony O'Dowd", "author": "Anthony O'Dowd",
"license": "Apache-2.0", "license": "Apache-2.0",

View file

@ -5,64 +5,73 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
/* /*
* Hyperledger Fabric Sample Query Program * Chaincode query
*/ */
var hfc = require('fabric-client'); var Fabric_Client = require('fabric-client');
var path = require('path'); var path = require('path');
var util = require('util');
var os = require('os');
var options = { //
wallet_path: path.join(__dirname, './creds'), var fabric_client = new Fabric_Client();
user_id: 'PeerAdmin',
channel_id: 'mychannel',
chaincode_id: 'fabcar',
network_url: 'grpc://localhost:7051',
};
var channel = {}; // setup the fabric network
var client = null; var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpc://localhost:7051');
channel.addPeer(peer);
Promise.resolve().then(() => { //
console.log("Create a client and set the wallet location"); var member_user = null;
client = new hfc(); var store_path = path.join(__dirname, 'hfc-key-store');
return hfc.newDefaultKeyValueStore({ path: options.wallet_path }); console.log('Store path:'+store_path);
}).then((wallet) => { var tx_id = null;
console.log("Set wallet path, and associate user ", options.user_id, " with application");
client.setStateStore(wallet);
return client.getUserContext(options.user_id, true);
}).then((user) => {
console.log("Check user is enrolled, and set a query URL in the network");
if (user === undefined || user.isEnrolled() === false) {
console.error("User not defined, or not enrolled - error");
}
channel = client.newChannel(options.channel_id);
channel.addPeer(client.newPeer(options.network_url));
return;
}).then(() => {
console.log("Make query");
var transaction_id = client.newTransactionID();
console.log("Assigning transaction_id: ", transaction_id._transaction_id);
// queryCar - requires 1 argument, ex: args: ['CAR4'], // create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
// queryAllCars - requires no arguments , ex: args: [''], Fabric_Client.newDefaultKeyValueStore({ path: store_path
const request = { }).then((state_store) => {
chaincodeId: options.chaincode_id, // assign the store to the fabric client
txId: transaction_id, fabric_client.setStateStore(state_store);
fcn: 'queryAllCars', var crypto_suite = Fabric_Client.newCryptoSuite();
args: [''] // use the same location for the state store (where the users' certificate are kept)
}; // and the crypto store (where the users' keys are kept)
return channel.queryByChaincode(request); var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);
// get the enrolled user from persistence, this user will sign all requests
return fabric_client.getUserContext('user1', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded user1 from persistence');
member_user = user_from_store;
} else {
throw new Error('Failed to get user1.... run registerUser.js');
}
// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'fabcar',
fcn: 'queryAllCars',
args: ['']
};
// send the query proposal to the peer
return channel.queryByChaincode(request);
}).then((query_responses) => { }).then((query_responses) => {
console.log("returned from query"); console.log("Query has completed, checking results");
if (!query_responses.length) { // query_responses could have more than one results if there multiple peers were used as targets
console.log("No payloads were returned from query"); if (query_responses && query_responses.length == 1) {
} else { if (query_responses[0] instanceof Error) {
console.log("Query result count = ", query_responses.length) console.error("error from query = ", query_responses[0]);
} } else {
if (query_responses[0] instanceof Error) { console.log("Response is ", query_responses[0].toString());
console.error("error from query = ", query_responses[0]); }
} } else {
console.log("Response is ", query_responses[0].toString()); console.log("No payloads were returned from query");
}
}).catch((err) => { }).catch((err) => {
console.error("Caught Error", err); console.error('Failed to query successfully :: ' + err);
}); });

82
fabcar/registerUser.js Normal file
View file

@ -0,0 +1,82 @@
'use strict';
/*
* Copyright IBM Corp All Rights Reserved
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Register and Enroll a user
*/
var Fabric_Client = require('fabric-client');
var Fabric_CA_Client = require('fabric-ca-client');
var path = require('path');
var util = require('util');
var os = require('os');
//
var fabric_client = new Fabric_Client();
var fabric_ca_client = null;
var admin_user = null;
var member_user = null;
var store_path = path.join(__dirname, 'hfc-key-store');
console.log(' Store path:'+store_path);
// create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
Fabric_Client.newDefaultKeyValueStore({ path: store_path
}).then((state_store) => {
// assign the store to the fabric client
fabric_client.setStateStore(state_store);
var crypto_suite = Fabric_Client.newCryptoSuite();
// use the same location for the state store (where the users' certificate are kept)
// and the crypto store (where the users' keys are kept)
var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);
var tlsOptions = {
trustedRoots: [],
verify: false
};
// be sure to change the http to https when the CA is running TLS enabled
fabric_ca_client = new Fabric_CA_Client('http://localhost:7054', null , '', crypto_suite);
// first check to see if the admin is already enrolled
return fabric_client.getUserContext('admin', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded admin from persistence');
admin_user = user_from_store;
} else {
throw new Error('Failed to get admin.... run enrollAdmin.js');
}
// at this point we should have the admin user
// first need to register the user with the CA server
return fabric_ca_client.register({enrollmentID: 'user1', affiliation: 'org1.department1'}, admin_user);
}).then((secret) => {
// next we need to enroll the user with CA server
console.log('Successfully registered user1 - secret:'+ secret);
return fabric_ca_client.enroll({enrollmentID: 'user1', enrollmentSecret: secret});
}).then((enrollment) => {
console.log('Successfully enrolled member user "user1" ');
return fabric_client.createUser(
{username: 'user1',
mspid: 'Org1MSP',
cryptoContent: { privateKeyPEM: enrollment.key.toBytes(), signedCertPEM: enrollment.certificate }
});
}).then((user) => {
member_user = user;
return fabric_client.setUserContext(member_user);
}).then(()=>{
console.log('User1 was successfully registered and enrolled and is ready to intreact with the fabric network');
}).catch((err) => {
console.error('Failed to register: ' + err);
if(err.toString().indexOf('Authorization') > -1) {
console.error('Authorization failures may be caused by having admin credentials from a previous CA instance.\n' +
'Try again after deleting the contents of the store directory '+store_path);
}
});

View file

@ -16,10 +16,6 @@ if [ "$LANGUAGE" = "node" -o "$LANGUAGE" = "NODE" ]; then
CC_SRC_PATH=/opt/gopath/src/github.com/fabcar/node CC_SRC_PATH=/opt/gopath/src/github.com/fabcar/node
fi fi
if [ ! -d ~/.hfc-key-store/ ]; then
mkdir ~/.hfc-key-store/
fi
cp $PWD/creds/* ~/.hfc-key-store/
# launch network; create channel and join peer to channel # launch network; create channel and join peer to channel
cd ../basic-network cd ../basic-network
./start.sh ./start.sh
@ -33,4 +29,8 @@ docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/g
sleep 10 sleep 10
docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"initLedger","Args":[""]}' docker exec -e "CORE_PEER_LOCALMSPID=Org1MSP" -e "CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp" cli peer chaincode invoke -o orderer.example.com:7050 -C mychannel -n fabcar -c '{"function":"initLedger","Args":[""]}'
printf "\nTotal execution time : $(($(date +%s) - starttime)) secs ...\n\n" printf "\nTotal setup execution time : $(($(date +%s) - starttime)) secs ...\n\n\n"
printf "Start by installing required packages run 'npm install'\n"
printf "Then run 'node enrollAdmin.js', then 'node registerUser'\n\n"
printf "The 'node invoke.js' will fail until it has been updated with valid arguments\n"
printf "The 'node query.js' may be run at anytime once the user has been registered\n\n"