Switched private data JS app to commons util (#294)

* Switched private data JS app to commons util

Reusing JS app & ca utils
Refactored for Org1 & Org2
assettransfer-basic JS app update for commons util refactor

Signed-off-by: Sijo Cherian <sijo@ibm.com>

* fixed assettransfer-ledgerqueries & private usage of commons util refactor

Signed-off-by: Sijo Cherian <sijo@ibm.com>

Co-authored-by: Sijo Cherian <sijo@ibm.com>
This commit is contained in:
Sijo Cherian 2020-08-13 08:22:05 -04:00 committed by GitHub
parent b92d61d5cf
commit 36a2d3a7d0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 188 deletions

View file

@ -6,16 +6,17 @@
'use strict'; 'use strict';
const {Gateway, Wallets} = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client'); const FabricCAServices = require('fabric-ca-client');
const path = require('path'); const path = require('path');
const {buildCAClient, registerAndEnrollUser, enrollAdmin} = require('../../test-application/javascript/CAUtil.js'); const { buildCAClient, registerAndEnrollUser, enrollAdmin } = require('../../test-application/javascript/CAUtil.js');
const {buildCCP, buildWallet} = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildWallet } = require('../../test-application/javascript/AppUtil.js');
const channelName = 'mychannel'; const channelName = 'mychannel';
const chaincodeName = 'basic'; const chaincodeName = 'basic';
const mspOrg1 = 'Org1MSP';
const walletPath = path.join(__dirname, 'wallet'); const walletPath = path.join(__dirname, 'wallet');
const userId = 'appUser'; const org1UserId = 'appUser';
function prettyJSONString(inputString) { function prettyJSONString(inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2); return JSON.stringify(JSON.parse(inputString), null, 2);
@ -71,21 +72,21 @@ function prettyJSONString(inputString) {
async function main() { async function main() {
try { try {
// build an in memory object with the network configuration (also known as a connection profile) // build an in memory object with the network configuration (also known as a connection profile)
const ccp = buildCCP(); const ccp = buildCCPOrg1();
// build an instance of the fabric ca services client based on // build an instance of the fabric ca services client based on
// the information in the network configuration // the information in the network configuration
const caClient = buildCAClient(FabricCAServices, ccp); const caClient = buildCAClient(FabricCAServices, ccp, 'ca.org1.example.com');
// setup the wallet to hold the credentials of the application user // setup the wallet to hold the credentials of the application user
const wallet = await buildWallet(Wallets, walletPath); const wallet = await buildWallet(Wallets, walletPath);
// in a real application this would be done on an administrative flow, and only once // in a real application this would be done on an administrative flow, and only once
await enrollAdmin(caClient, wallet); await enrollAdmin(caClient, wallet, mspOrg1);
// in a real application this would be done only when a new user was required to be added // in a real application this would be done only when a new user was required to be added
// and would be part of an administrative flow // and would be part of an administrative flow
await registerAndEnrollUser(caClient, wallet, userId, 'org1.department1'); await registerAndEnrollUser(caClient, wallet, mspOrg1, org1UserId, 'org1.department1');
// Create a new gateway instance for interacting with the fabric network. // Create a new gateway instance for interacting with the fabric network.
// In a real application this would be done as the backend server session is setup for // In a real application this would be done as the backend server session is setup for
@ -99,8 +100,8 @@ async function main() {
// signed by this user using the credentials stored in the wallet. // signed by this user using the credentials stored in the wallet.
await gateway.connect(ccp, { await gateway.connect(ccp, {
wallet, wallet,
identity: userId, identity: org1UserId,
discovery: {enabled: true, asLocalhost: true} // using asLocalhost as this gateway is using a fabric network deployed locally discovery: { enabled: true, asLocalhost: true } // using asLocalhost as this gateway is using a fabric network deployed locally
}); });
// Build a network instance based on the channel where the smart contract is deployed // Build a network instance based on the channel where the smart contract is deployed

View file

@ -6,14 +6,16 @@
'use strict'; 'use strict';
const {Gateway, Wallets} = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client'); const FabricCAServices = require('fabric-ca-client');
const path = require('path'); const path = require('path');
const {buildCAClient, registerAndEnrollUser, enrollAdmin} = require('../../test-application/javascript/CAUtil.js'); const { buildCAClient, registerAndEnrollUser, enrollAdmin } = require('../../test-application/javascript/CAUtil.js');
const {buildCCP, buildWallet} = require('../../test-application/javascript/AppUtil.js'); const { buildCCPOrg1, buildWallet } = require('../../test-application/javascript/AppUtil.js');
const channelName = 'mychannel'; const channelName = 'mychannel';
const chaincodeName = 'ledger'; const chaincodeName = 'ledger';
const mspOrg1 = 'Org1MSP';
const walletPath = path.join(__dirname, 'wallet'); const walletPath = path.join(__dirname, 'wallet');
const userId = 'appUser'; const userId = 'appUser';
@ -78,21 +80,21 @@ async function main() {
try { try {
// build an in memory object with the network configuration (also known as a connection profile) // build an in memory object with the network configuration (also known as a connection profile)
const ccp = buildCCP(); const ccp = buildCCPOrg1();
// build an instance of the fabric ca services client based on // build an instance of the fabric ca services client based on
// the information in the network configuration // the information in the network configuration
const caClient = buildCAClient(FabricCAServices, ccp); const caClient = buildCAClient(FabricCAServices, ccp, 'ca.org1.example.com');
// setup the wallet to hold the credentials of the application user // setup the wallet to hold the credentials of the application user
const wallet = await buildWallet(Wallets, walletPath); const wallet = await buildWallet(Wallets, walletPath);
// in a real application this would be done on an administrative flow, and only once // in a real application this would be done on an administrative flow, and only once
await enrollAdmin(caClient, wallet); await enrollAdmin(caClient, wallet, mspOrg1);
// in a real application this would be done only when a new user was required to be added // in a real application this would be done only when a new user was required to be added
// and would be part of an administrative flow // and would be part of an administrative flow
await registerAndEnrollUser(caClient, wallet, userId, 'org1.department1'); await registerAndEnrollUser(caClient, wallet, mspOrg1, userId, 'org1.department1');
// Create a new gateway instance for interacting with the fabric network. // Create a new gateway instance for interacting with the fabric network.
// In a real application this would be done as the backend server session is setup for // In a real application this would be done as the backend server session is setup for
@ -107,7 +109,7 @@ async function main() {
await gateway.connect(ccp, { await gateway.connect(ccp, {
wallet, wallet,
identity: userId, identity: userId,
discovery: {enabled: true, asLocalhost: true} // using asLocalhost as this gateway is using a fabric network deployed locally discovery: { enabled: true, asLocalhost: true } // using asLocalhost as this gateway is using a fabric network deployed locally
}); });
// Build a network instance based on the channel where the smart contract is deployed // Build a network instance based on the channel where the smart contract is deployed
@ -125,7 +127,7 @@ async function main() {
console.log('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger'); console.log('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the ledger');
await contract.submitTransaction('InitLedger'); await contract.submitTransaction('InitLedger');
console.log('*** Result: committed'); console.log('*** Result: committed');
} catch(initError) { } catch (initError) {
// this is error is OK if we are rerunning this app without restarting // this is error is OK if we are rerunning this app without restarting
console.log(`******** initLedger failed :: ${initError}`) console.log(`******** initLedger failed :: ${initError}`)
} }
@ -189,7 +191,7 @@ async function main() {
// Rich Query with Pagination (Only supported if CouchDB is used as state database) // Rich Query with Pagination (Only supported if CouchDB is used as state database)
console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Tom" assets'); console.log('\n--> Evaluate Transaction: QueryAssetsWithPagination, function returns "Tom" assets');
result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Tom"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}','3',''); result = await contract.evaluateTransaction('QueryAssetsWithPagination', '{"selector":{"docType":"asset","owner":"Tom"}, "use_index":["_design/indexOwnerDoc", "indexOwner"]}', '3', '');
console.log(`*** Result: ${prettyJSONString(result.toString())}`); console.log(`*** Result: ${prettyJSONString(result.toString())}`);
console.log('\n--> Submit Transaction: TransferAssetByColor, transfer all yellow assets to new owner(Michel)'); console.log('\n--> Submit Transaction: TransferAssetByColor, transfer all yellow assets to new owner(Michel)');

View file

@ -8,10 +8,9 @@
const { Gateway, Wallets } = require('fabric-network'); const { Gateway, Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client'); const FabricCAServices = require('fabric-ca-client');
const path = require('path'); const path = require('path');
const fs = require('fs'); const { buildCAClient, registerAndEnrollUser, enrollAdmin } = require('../../test-application/javascript/CAUtil.js');
const caUtils = require('./caUtils'); const { buildCCPOrg1, buildCCPOrg2, buildWallet } = require('../../test-application/javascript/AppUtil.js');
const myChannel = 'mychannel'; const myChannel = 'mychannel';
const myChaincodeName = 'private'; const myChaincodeName = 'private';
@ -19,8 +18,11 @@ const myChaincodeName = 'private';
const memberAssetCollectionName = 'assetCollection'; const memberAssetCollectionName = 'assetCollection';
const org1PrivateCollectionName = 'Org1MSPPrivateCollection'; const org1PrivateCollectionName = 'Org1MSPPrivateCollection';
const org2PrivateCollectionName = 'Org2MSPPrivateCollection'; const org2PrivateCollectionName = 'Org2MSPPrivateCollection';
const mspOrg2 = 'Org2MSP';
const mspOrg1 = 'Org1MSP'; const mspOrg1 = 'Org1MSP';
const mspOrg2 = 'Org2MSP';
const Org1UserId = 'appUser1';
const Org2UserId = 'appUser2';
function prettyJSONString(inputString) { function prettyJSONString(inputString) {
if (inputString) { if (inputString) {
return JSON.stringify(JSON.parse(inputString), null, 2); return JSON.stringify(JSON.parse(inputString), null, 2);
@ -31,36 +33,33 @@ function prettyJSONString(inputString) {
} }
async function initContractFromOrg1Identity() { async function initContractFromOrg1Identity() {
console.log('\nFabric client user & Gateway init: Using Org1 identity to Org1 Peer'); console.log('\n--> Fabric client user & Gateway init: Using Org1 identity to Org1 Peer');
// load the network configuration // build an in memory object with the network configuration (also known as a connection profile)
let ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json'); const ccpOrg1 = buildCCPOrg1();
let fileExists = fs.existsSync(ccpPath);
if (!fileExists) { // build an instance of the fabric ca services client based on
throw new Error(`no such file or directory: ${ccpPath}`); // the information in the network configuration
} const caOrg1Client = buildCAClient(FabricCAServices, ccpOrg1, 'ca.org1.example.com');
let ccpOrg1 = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
// Create a new file system based wallet for managing identities. // setup the wallet to cache the credentials of the application user, on the app server locally
const walletPathOrg1 = path.join(__dirname, 'wallet/org1'); const walletPathOrg1 = path.join(__dirname, 'wallet/org1');
const walletOrg1 = await Wallets.newFileSystemWallet(walletPathOrg1); const walletOrg1 = await buildWallet(Wallets, walletPathOrg1);
console.log(`Org1 wallet path: ${walletPathOrg1}`);
// Create a new CA client for interacting with this Orgs CA. // in a real application this would be done on an administrative flow, and only once
const caInfo = ccpOrg1.certificateAuthorities['ca.org1.example.com']; // stores admin identity in local wallet, if needed
const caTLSCACerts = caInfo.tlsCACerts.pem; await enrollAdmin(caOrg1Client, walletOrg1, mspOrg1);
const caService = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName); // register & enroll application user with CA, which is used as client identify to make chaincode calls
// and stores app user identity in local wallet
// register & enroll admin user with CA, stores admin identity in local wallet // In a real application this would be done only when a new user was required to be added
await caUtils.EnrollOrgAdminUser(mspOrg1, walletOrg1, caService); // and would be part of an administrative flow
await registerAndEnrollUser(caOrg1Client, walletOrg1, mspOrg1, Org1UserId, 'org1.department1');
// register & enroll application user with CA, which is used as client identify to make chaincode calls, stores app user identity in local wallet
await caUtils.RegisterOrgUser(caUtils.Org1UserId, mspOrg1, walletOrg1, caService);
try { try {
// Create a new gateway for connecting to Org's peer node. // Create a new gateway for connecting to Org's peer node.
const gatewayOrg1 = new Gateway(); const gatewayOrg1 = new Gateway();
//connect using Discovery enabled //connect using Discovery enabled
await gatewayOrg1.connect(ccpOrg1, await gatewayOrg1.connect(ccpOrg1,
{ wallet: walletOrg1, identity: caUtils.Org1UserId, discovery: { enabled: true, asLocalhost: true } }); { wallet: walletOrg1, identity: Org1UserId, discovery: { enabled: true, asLocalhost: true } });
return gatewayOrg1; return gatewayOrg1;
} catch (error) { } catch (error) {
@ -70,35 +69,21 @@ async function initContractFromOrg1Identity() {
} }
async function initContractFromOrg2Identity() { async function initContractFromOrg2Identity() {
console.log('\nFabric client user & Gateway init: Using Org2 identity to Org2 Peer'); console.log('\n--> Fabric client user & Gateway init: Using Org2 identity to Org2 Peer');
// load the network configuration const ccpOrg2 = buildCCPOrg2();
let ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org2.example.com', 'connection-org2.json'); const caOrg2Client = buildCAClient(FabricCAServices, ccpOrg2, 'ca.org2.example.com');
let fileExists = fs.existsSync(ccpPath);
if (!fileExists) {
throw new Error(`no such file or directory: ${ccpPath}`);
}
const ccpOrg2 = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
// Create a new file system based wallet for managing identities.
const walletPathOrg2 = path.join(__dirname, 'wallet/org2'); const walletPathOrg2 = path.join(__dirname, 'wallet/org2');
const walletOrg2 = await Wallets.newFileSystemWallet(walletPathOrg2); const walletOrg2 = await buildWallet(Wallets, walletPathOrg2);
console.log(`Org2 wallet path: ${walletPathOrg2}`);
// Create a new CA client for interacting with this Orgs CA. await enrollAdmin(caOrg2Client, walletOrg2, mspOrg2);
const caInfo = ccpOrg2.certificateAuthorities['ca.org2.example.com']; await registerAndEnrollUser(caOrg2Client, walletOrg2, mspOrg2, Org2UserId, 'org2.department1');
const caTLSCACerts = caInfo.tlsCACerts.pem;
const caService = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
await caUtils.EnrollOrgAdminUser(mspOrg2, walletOrg2, caService);
// register & enroll application user with CA, which is used as client identify to make chaincode calls, stores app user identity in local wallet
await caUtils.RegisterOrgUser(caUtils.Org2UserId, mspOrg2, walletOrg2, caService);
try { try {
// Create a new gateway for connecting to Org's peer node. // Create a new gateway for connecting to Org's peer node.
const gatewayOrg2 = new Gateway(); const gatewayOrg2 = new Gateway();
await gatewayOrg2.connect(ccpOrg2, await gatewayOrg2.connect(ccpOrg2,
{ wallet: walletOrg2, identity: caUtils.Org2UserId, discovery: { enabled: true, asLocalhost: true } }); { wallet: walletOrg2, identity: Org2UserId, discovery: { enabled: true, asLocalhost: true } });
return gatewayOrg2; return gatewayOrg2;
} catch (error) { } catch (error) {
@ -149,7 +134,7 @@ async function main() {
result = await statefulTxn.submit(); result = await statefulTxn.submit();
//Add asset2 //Add asset2
console.log('Submit Transaction: CreateAsset ' + assetID2); console.log('\n--> Submit Transaction: CreateAsset ' + assetID2);
statefulTxn = contractOrg1.createTransaction('CreateAsset'); statefulTxn = contractOrg1.createTransaction('CreateAsset');
tmapData = Buffer.from(JSON.stringify(asset2Data)); tmapData = Buffer.from(JSON.stringify(asset2Data));
statefulTxn.setTransient({ statefulTxn.setTransient({
@ -157,21 +142,20 @@ async function main() {
}); });
result = await statefulTxn.submit(); result = await statefulTxn.submit();
console.log('\n***********************');
console.log('Evaluate Transaction: GetAssetByRange asset0-asset9'); console.log('\n--> Evaluate Transaction: GetAssetByRange asset0-asset9');
// GetAssetByRange returns assets on the ledger with ID in the range of startKey (inclusive) and endKey (exclusive) // GetAssetByRange returns assets on the ledger with ID in the range of startKey (inclusive) and endKey (exclusive)
result = await contractOrg1.evaluateTransaction('GetAssetByRange', 'asset0', 'asset9'); result = await contractOrg1.evaluateTransaction('GetAssetByRange', 'asset0', 'asset9');
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
console.log('\n***********************'); console.log('\n--> Evaluate Transaction: ReadAssetPrivateDetails from ' + org1PrivateCollectionName);
console.log('Evaluate Transaction: ReadAssetPrivateDetails from ' + org1PrivateCollectionName);
// ReadAssetPrivateDetails reads data from Org's private collection. Args: collectionName, assetID // ReadAssetPrivateDetails reads data from Org's private collection. Args: collectionName, assetID
result = await contractOrg1.evaluateTransaction('ReadAssetPrivateDetails', org1PrivateCollectionName, assetID1); result = await contractOrg1.evaluateTransaction('ReadAssetPrivateDetails', org1PrivateCollectionName, assetID1);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~'); console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~');
console.log('Evaluate Transaction: ReadAsset ' + assetID1); console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1);
result = await contractOrg2.evaluateTransaction('ReadAsset', assetID1); result = await contractOrg2.evaluateTransaction('ReadAsset', assetID1);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
let assetOwner = JSON.parse(result.toString()).owner; let assetOwner = JSON.parse(result.toString()).owner;
@ -183,7 +167,7 @@ async function main() {
// Buyer from Org2 agrees to buy the asset assetID1 // // Buyer from Org2 agrees to buy the asset assetID1 //
// To purchase the asset, the buyer needs to agree to the same value as the asset owner // To purchase the asset, the buyer needs to agree to the same value as the asset owner
let dataForAgreement = { assetID: assetID1, appraisedValue: 100 }; let dataForAgreement = { assetID: assetID1, appraisedValue: 100 };
console.log('\nSubmit Transaction: AgreeToTransfer payload ' + JSON.stringify(dataForAgreement)); console.log('\n--> Submit Transaction: AgreeToTransfer payload ' + JSON.stringify(dataForAgreement));
statefulTxn = contractOrg2.createTransaction('AgreeToTransfer'); statefulTxn = contractOrg2.createTransaction('AgreeToTransfer');
tmapData = Buffer.from(JSON.stringify(dataForAgreement)); tmapData = Buffer.from(JSON.stringify(dataForAgreement));
statefulTxn.setTransient({ statefulTxn.setTransient({
@ -203,13 +187,13 @@ async function main() {
console.log('\n**************** As Org1 Client ****************'); console.log('\n**************** As Org1 Client ****************');
// All members can send txn ReadTransferAgreement, set by Org2 above // All members can send txn ReadTransferAgreement, set by Org2 above
console.log('Evaluate Transaction: ReadTransferAgreement ' + assetID1); console.log('\n--> Evaluate Transaction: ReadTransferAgreement ' + assetID1);
result = await contractOrg1.evaluateTransaction('ReadTransferAgreement', assetID1); result = await contractOrg1.evaluateTransaction('ReadTransferAgreement', assetID1);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
// Transfer the asset to Org2 // // Transfer the asset to Org2 //
// To transfer the asset, the owner needs to pass the MSP ID of new asset owner, and initiate the transfer // To transfer the asset, the owner needs to pass the MSP ID of new asset owner, and initiate the transfer
console.log('Submit Transaction: TransferAsset ' + assetID1); console.log('\n--> Submit Transaction: TransferAsset ' + assetID1);
let buyerDetails = { assetID: assetID1, buyerMSP: mspOrg2 }; let buyerDetails = { assetID: assetID1, buyerMSP: mspOrg2 };
statefulTxn = contractOrg1.createTransaction('TransferAsset'); statefulTxn = contractOrg1.createTransaction('TransferAsset');
tmapData = Buffer.from(JSON.stringify(buyerDetails)); tmapData = Buffer.from(JSON.stringify(buyerDetails));
@ -218,27 +202,27 @@ async function main() {
}); });
result = await statefulTxn.submit(); result = await statefulTxn.submit();
console.log('\n***********************');
//Again ReadAsset : results will show that the buyer identity now owns the asset: //Again ReadAsset : results will show that the buyer identity now owns the asset:
console.log('Evaluate Transaction: ReadAsset ' + assetID1); console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID1);
result = await contractOrg1.evaluateTransaction('ReadAsset', assetID1); result = await contractOrg1.evaluateTransaction('ReadAsset', assetID1);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
assetOwner = JSON.parse(result.toString()).owner; assetOwner = JSON.parse(result.toString()).owner;
console.log(' Asset owner: ' + Buffer.from(assetOwner, 'base64').toString()); console.log(' Asset owner: ' + Buffer.from(assetOwner, 'base64').toString());
//Confirm that transfer removed the private details from the Org1 collection: //Confirm that transfer removed the private details from the Org1 collection:
console.log('Evaluate Transaction: ReadAssetPrivateDetails'); console.log('\n--> Evaluate Transaction: ReadAssetPrivateDetails');
// ReadAssetPrivateDetails reads data from Org's private collection: Should return empty // ReadAssetPrivateDetails reads data from Org's private collection: Should return empty
result = await contractOrg1.evaluateTransaction('ReadAssetPrivateDetails', org1PrivateCollectionName, assetID1); result = await contractOrg1.evaluateTransaction('ReadAssetPrivateDetails', org1PrivateCollectionName, assetID1);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
console.log('Evaluate Transaction: ReadAsset ' + assetID2); console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID2);
result = await contractOrg1.evaluateTransaction('ReadAsset', assetID2); result = await contractOrg1.evaluateTransaction('ReadAsset', assetID2);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
console.log('\n***********************'); console.log('\n********* Demo deleting asset **************');
// Delete Asset2 // Delete Asset2
console.log('Deleting Asset ' + assetID2); console.log('--> Submit Transaction: DeleteAsset ' + assetID2);
statefulTxn = contractOrg1.createTransaction('DeleteAsset'); statefulTxn = contractOrg1.createTransaction('DeleteAsset');
let dataForDelete = { assetID: assetID2 }; let dataForDelete = { assetID: assetID2 };
@ -247,13 +231,14 @@ async function main() {
asset_delete: tmapData asset_delete: tmapData
}); });
result = await statefulTxn.submit(); result = await statefulTxn.submit();
console.log('Evaluate Transaction: ReadAsset ' + assetID2);
console.log('\n--> Evaluate Transaction: ReadAsset ' + assetID2);
result = await contractOrg1.evaluateTransaction('ReadAsset', assetID2); result = await contractOrg1.evaluateTransaction('ReadAsset', assetID2);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~'); console.log('\n~~~~~~~~~~~~~~~~ As Org2 Client ~~~~~~~~~~~~~~~~');
// Org2 can ReadAssetPrivateDetails: Org2 is owner, and private details exist in new owner's Collection // Org2 can ReadAssetPrivateDetails: Org2 is owner, and private details exist in new owner's Collection
console.log('Evaluate Transaction as Org2: ReadAssetPrivateDetails ' + assetID1 + ' from ' + org2PrivateCollectionName); console.log('\n--> Evaluate Transaction as Org2: ReadAssetPrivateDetails ' + assetID1 + ' from ' + org2PrivateCollectionName);
result = await contractOrg2.evaluateTransaction('ReadAssetPrivateDetails', org2PrivateCollectionName, assetID1); result = await contractOrg2.evaluateTransaction('ReadAssetPrivateDetails', org2PrivateCollectionName, assetID1);
console.log(' result: ' + prettyJSONString(result.toString())); console.log(' result: ' + prettyJSONString(result.toString()));
} finally { } finally {

View file

@ -1,97 +0,0 @@
/*
* Copyright IBM Corp. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
const adminUserId = 'admin';
const adminUserPasswd = 'adminpw';
const org1UserId = 'appUser1';
const org2UserId = 'appUser2';
const caChaincodeUserRole = 'client';
async function registerOrgUser(appUserId, mspId, wallet, caService) {
try {
// Check to see if we've already enrolled the user.
const userIdentity = await wallet.get(appUserId);
if (userIdentity) {
console.log('An identity for the user ' + appUserId + ' already exists in the wallet');
return;
}
// Check to see if we've already enrolled the admin user.
const adminIdentity = await wallet.get(adminUserId);
if (!adminIdentity) {
console.log('An identity for the admin user does not exist in the wallet');
console.log('Call enrollAdmin for admin user enroll before retrying');
return;
}
// build a user object for authenticating with the CA
const provider = wallet.getProviderRegistry().getProvider(adminIdentity.type);
const adminUser = await provider.getUserContext(adminIdentity, adminUserId);
// Register the user, enroll the user, and import the new identity into the wallet.
// if affiliation is specified by client, the affiliation value must be configured in CA
const secret = await caService.register({
affiliation: 'org2.department1',
enrollmentID: appUserId,
role: caChaincodeUserRole
}, adminUser);
const enrollment = await caService.enroll({
enrollmentID: appUserId,
enrollmentSecret: secret
});
const x509Identity = {
credentials: {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
},
mspId: mspId,
type: 'X.509',
};
await wallet.put(appUserId, x509Identity);
console.log('Successfully registered and enrolled user ' + appUserId + ' and imported it into the wallet');
} catch (error) {
console.error(`Failed to register user : ${error}`);
process.exit(1);
}
}
async function enrollOrgAdminUser(mspId, wallet, caService) {
try {
// Check to see if we've already enrolled the admin user.
const identity = await wallet.get(adminUserId);
if (identity) {
console.log('An identity for the admin user already exists in the wallet');
return;
}
// Enroll the admin user, and import the new identity into the wallet.
const enrollment = await caService.enroll({ enrollmentID: adminUserId, enrollmentSecret: adminUserPasswd });
const x509Identity = {
credentials: {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
},
mspId: mspId,
type: 'X.509',
};
await wallet.put(adminUserId, x509Identity);
console.log('Successfully enrolled admin user and imported it into the wallet');
} catch (error) {
console.error(`Failed to enroll admin user : ${error}`);
process.exit(1);
}
}
exports.AdminUserId = adminUserId;
exports.Org1UserId = org1UserId;
exports.Org2UserId = org2UserId;
exports.RegisterOrgUser = registerOrgUser;
exports.EnrollOrgAdminUser = enrollOrgAdminUser;

View file

@ -9,7 +9,7 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
exports.buildCCP = () => { exports.buildCCPOrg1 = () => {
// load the common connection configuration file // load the common connection configuration file
const ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json'); const ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json');
const fileExists = fs.existsSync(ccpPath); const fileExists = fs.existsSync(ccpPath);
@ -25,6 +25,23 @@ exports.buildCCP = () => {
return ccp; return ccp;
}; };
exports.buildCCPOrg2 = () => {
// load the common connection configuration file
const ccpPath = path.resolve(__dirname, '..', '..', 'test-network',
'organizations', 'peerOrganizations', 'org2.example.com', 'connection-org2.json');
const fileExists = fs.existsSync(ccpPath);
if (!fileExists) {
throw new Error(`no such file or directory: ${ccpPath}`);
}
const contents = fs.readFileSync(ccpPath, 'utf8');
// build a JSON object from the file contents
const ccp = JSON.parse(contents);
console.log(`Loaded the network configuration located at ${ccpPath}`);
return ccp;
};
exports.buildWallet = async (Wallets, walletPath) => { exports.buildWallet = async (Wallets, walletPath) => {
// Create a new wallet : Note that wallet is for managing identities. // Create a new wallet : Note that wallet is for managing identities.
let wallet; let wallet;

View file

@ -14,9 +14,9 @@ const adminUserPasswd = 'adminpw';
* @param {*} FabricCAServices * @param {*} FabricCAServices
* @param {*} ccp * @param {*} ccp
*/ */
exports.buildCAClient = (FabricCAServices, ccp) => { exports.buildCAClient = (FabricCAServices, ccp, caHostName) => {
// Create a new CA client for interacting with the CA. // Create a new CA client for interacting with the CA.
const caInfo = ccp.certificateAuthorities['ca.org1.example.com']; const caInfo = ccp.certificateAuthorities[caHostName]; //lookup CA details from config
const caTLSCACerts = caInfo.tlsCACerts.pem; const caTLSCACerts = caInfo.tlsCACerts.pem;
const caClient = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName); const caClient = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
@ -24,7 +24,7 @@ exports.buildCAClient = (FabricCAServices, ccp) => {
return caClient; return caClient;
}; };
exports.enrollAdmin = async (caClient, wallet) => { exports.enrollAdmin = async (caClient, wallet, orgMspId) => {
try { try {
// Check to see if we've already enrolled the admin user. // Check to see if we've already enrolled the admin user.
const identity = await wallet.get(adminUserId); const identity = await wallet.get(adminUserId);
@ -40,7 +40,7 @@ exports.enrollAdmin = async (caClient, wallet) => {
certificate: enrollment.certificate, certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(), privateKey: enrollment.key.toBytes(),
}, },
mspId: 'Org1MSP', mspId: orgMspId,
type: 'X.509', type: 'X.509',
}; };
await wallet.put(adminUserId, x509Identity); await wallet.put(adminUserId, x509Identity);
@ -50,7 +50,7 @@ exports.enrollAdmin = async (caClient, wallet) => {
} }
}; };
exports.registerAndEnrollUser = async (caClient, wallet, userId, affiliation) => { exports.registerAndEnrollUser = async (caClient, wallet, orgMspId, userId, affiliation) => {
try { try {
// Check to see if we've already enrolled the user // Check to see if we've already enrolled the user
const userIdentity = await wallet.get(userId); const userIdentity = await wallet.get(userId);
@ -87,7 +87,7 @@ exports.registerAndEnrollUser = async (caClient, wallet, userId, affiliation) =
certificate: enrollment.certificate, certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(), privateKey: enrollment.key.toBytes(),
}, },
mspId: 'Org1MSP', mspId: orgMspId,
type: 'X.509', type: 'X.509',
}; };
await wallet.put(userId, x509Identity); await wallet.put(userId, x509Identity);