- Node sdk examples to interact with bityoga fabric set up

- Refer README for more instructions
parent 1359933f
# Fabric SDK Adaptor
Node sdk examples to interact with bityoga fabric set up
# Requirements
1. Bityoga fabric sdk should be up and running
2. Node version
- Supports node version >=8
- Tested with v8.10.0
# Run Instructions
1. ## Clone this repository into your app directory
- git clone https://github.com/bityoga/fabric_node_sdk_helper.git
2. ## Update your app's package.json
- Edit your app's **package.json with the "fabric_node_sdk_helper/package.json"** found in this repository.
3. ## Run npm install
- #### Set node version
- nvm use node v8.9.0 (using nvm)
- npm install
3. ## Update ip address in 'fabric_node_sdk_helper/network_profile.json'
- **update the url ip addresses of orderer, peer2, orgca, tlsca (4 places).**
- update it with your prime manager's ip address
4. ## Retrieve hyperledger fabric tls certificates of 'orderer' and 'peer2'
#### Through shell script - needs ssh permission
- cd fabric_node_sdk_helper/
- In 'fabric_node_sdk_helper/get_tls_certificates.sh' Replace **IP_ADDRESS="178.62.207.235"** with your fabric prime manager's ip address
- **Execute Command :** bash get_tls_certificates.sh
#### (OR) Through Manual scp commands - needs ssh permission
- Replace ipaddress in the below scp commands with your fabric prime manager's ip address.
- scp -r root@178.62.207.235:/root/hlft-store/orderer/tls-msp/tlscacerts/tls-tlsca-7054.pem ./fabric_node_sdk_helper/hlft-store/orderer/tls-msp/tlscacerts/tls-tlsca-7054.pem
- scp -r root@178.62.207.235:/root/hlft-store/peer2/tls-msp/tlscacerts/tls-tlsca-7054.pem ./fabric_node_sdk_helper/hlft-store/peer2/tls-msp/tlscacerts/tls-tlsca-7054.pem
#### (OR) Manually edit the following two files - no need of ssh permission
- fabric_node_sdk_helper/hlft-store/orderer/tls-msp/tlscacerts/tls-tlsca-7054.pem
- fabric_node_sdk_helper/hlft-store/peer2/tls-msp/tlscacerts/tls-tlsca-7054.pem
5. ## Enroll admin
- #### Call this function "once" when your app starts.
- When this function is called, a **wallet** directory will be created in the current directory
- Admin user will be enrolled and the certificates will availalble in **wallet** directory
- If fabric certificates are changed in future, this wallet directory should cleaned, and this function must be called again to get the new certificates
- check wallet directory
- a directory named 'admin' will be available
- certificates for admin will be available under this directory.
- sample :
``` Javascript
// import fabric node sdk helper functions
const enrollAdmin = require('./fabric_node_sdk_helper/enrollAdmin');
async function main() {
admin_enroll_status = await enrollAdmin();
console.log(admin_enroll_status);
}
main();
```
6. ## Register user
- sample :
``` Javascript
// import fabric node sdk helper functions
const registerUser = require('./fabric_node_sdk_helper/registerUser');
app.post('/register', async (req, res) => {
let user_name = req.body.uname;
let user_password = req.body.psw;
let user_role = "client";
let register_status = await registerUser(user_name,
user_password,
user_role);
let response = {
status:register_status
};
res.json(response);
});
```
- check wallet directory
- a directory with the name of the 'registerd user name' will be available
- certificates for the registerd user will be available under this directory.
7. ## Query a chaincode
- sample :
``` Javascript
// import fabric node sdk helper functions
const querychaincode = require('./fabric_node_sdk_helper/query');
app.post('/query', async (req, res) => {
let user_name = req.body.uname;
let CHANNEL_NAME = "appchannel";
let CHAIN_CODE_NAME = "carcc";
let CHAIN_CODE_FUNCTION_NAME = "listCars";
// Without Arguments
let query_result = await querychaincode(user_name,CHANNEL_NAME,CHAIN_CODE_NAME, CHAIN_CODE_FUNCTION_NAME);
// With Arguments
let query_result = await querychaincode(user_name,CHANNEL_NAME,CHAIN_CODE_NAME, CHAIN_CODE_FUNCTION_NAME , "a");
let response = {
"status":"success",
"data":query_result
};
console.log(response);
res.json(response);
});
```
8. ## Invoke a chaincode
- sample :
``` Javascript
// import fabric node sdk helper functions
const invokechaincode = require('./fabric_node_sdk_helper/invoke');
app.post('/invoke', async (req, res) => {
let user_name = req.body.uname;
let car_license_plate = req.body.car_license_plate;
let CHANNEL_NAME = "appchannel";
let CHAIN_CODE_NAME = "carcc";
let CHAIN_CODE_FUNCTION_NAME = "listCars";
let invoke_result = await invokechaincode(user_name,
CHANNEL_NAME,
CHAIN_CODE_NAME,
CHAIN_CODE_FUNCTION_NAME,
car_license_plate,
"Opel","Corsa","Light Blue","7","2050","1");
let response = {
"status":"success",
"data":invoke_result
};
console.log(response);
res.json(response);
});
```
/*
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
const FabricCAServices = require('fabric-ca-client');
const { FileSystemWallet, X509WalletMixin } = require('fabric-network');
const fs = require('fs');
const path = require('path');
const ccpPath = path.resolve(__dirname, '.', 'network_profile.json');
const ccpJSON = fs.readFileSync(ccpPath, 'utf8');
const ccp = JSON.parse(ccpJSON);
const admin_username = "ca-admin-orgca";
const admin_password = "orgcapw";
const ORGANISATION_MSP = "hlfMSP";
const CA_ORGANISATION_NAME = "orgca";
async function enrollAdmin() {
let return_value;
try {
// Create a new CA client for interacting with the CA.
const caInfo = ccp.certificateAuthorities[CA_ORGANISATION_NAME];
console.log(caInfo);
const caTLSCACerts = [];
//const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists('admin');
if (adminExists) {
return_value = 'An identity for the admin user "admin" already exists in the wallet';
}
else {
// Enroll the admin user, and import the new identity into the wallet.
const enrollment = await ca.enroll({ enrollmentID: admin_username, enrollmentSecret: admin_password });
const identity = X509WalletMixin.createIdentity(ORGANISATION_MSP, enrollment.certificate, enrollment.key.toBytes());
await wallet.import('admin', identity);
return_value = 'Successfully enrolled admin user "admin" and imported it into the wallet';
}
}
catch (error) {
return_value = `Failed to enroll admin user "admin": ${error}`;
}
finally {
console.log("'enrollAdmin' function -> returning value");
return return_value;
}
}
module.exports = enrollAdmin;
\ No newline at end of file
#!/bin/bash
set -x #echo on
IP_ADDRESS="46.101.220.140"
REMOTE_MACHINE_ORDERER_TLS_CERT_FILE="/root/hlft-store/orgca/orderer/msp/tls/ca.crt"
REMOTE_MACHINE_PEER2_TLS_CERT_FILE="/root/hlft-store/orgca/peer2/msp/tls/ca.crt"
LOCAL_ORDER_TLS_CERT_FILE="./hlft-store/orderer/tls-msp/tlscacerts/ca.crt"
LOCAL_ORDER_PEER2_CERT_FILE="./hlft-store/peer2/tls-msp/tlscacerts/ca.crt"
scp -r root@$IP_ADDRESS:$REMOTE_MACHINE_ORDERER_TLS_CERT_FILE $LOCAL_ORDER_TLS_CERT_FILE &&
scp -r root@$IP_ADDRESS:$REMOTE_MACHINE_PEER2_TLS_CERT_FILE $LOCAL_ORDER_PEER2_CERT_FILE
-----BEGIN CERTIFICATE-----
MIICATCCAaegAwIBAgIUHtIeXGIFSSSzdVv3i8OKtwTEoekwCgYIKoZIzj0EAwIw
XTELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMQ4wDAYDVQQDEwV0bHNjYTAe
Fw0yMDEwMDcxOTA2MDBaFw0zNTEwMDQxOTA2MDBaMF0xCzAJBgNVBAYTAlVTMRcw
FQYDVQQIEw5Ob3J0aCBDYXJvbGluYTEUMBIGA1UEChMLSHlwZXJsZWRnZXIxDzAN
BgNVBAsTBkZhYnJpYzEOMAwGA1UEAxMFdGxzY2EwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAATiVMVg8vqfYkf33sVX5rsOO+RJr7gio3GQ4cRIBb9a0EL8ic8F40bG
R4/+cuFTVacUpC68JMPvIOXKZDPyL6Sdo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYD
VR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQU5SQIqQSqUa0S4iCIqW6D4F7BKakw
CgYIKoZIzj0EAwIDSAAwRQIhAOxtHlaXYbj/ptd0ncFWXa1fSeTfz2Ig06Nlx6c5
G+W4AiA1TbAWTspXu8dd/ky4w490fCj6nLbdvgE/uWT2npg/aA==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIICATCCAaegAwIBAgIUHtIeXGIFSSSzdVv3i8OKtwTEoekwCgYIKoZIzj0EAwIw
XTELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK
EwtIeXBlcmxlZGdlcjEPMA0GA1UECxMGRmFicmljMQ4wDAYDVQQDEwV0bHNjYTAe
Fw0yMDEwMDcxOTA2MDBaFw0zNTEwMDQxOTA2MDBaMF0xCzAJBgNVBAYTAlVTMRcw
FQYDVQQIEw5Ob3J0aCBDYXJvbGluYTEUMBIGA1UEChMLSHlwZXJsZWRnZXIxDzAN
BgNVBAsTBkZhYnJpYzEOMAwGA1UEAxMFdGxzY2EwWTATBgcqhkjOPQIBBggqhkjO
PQMBBwNCAATiVMVg8vqfYkf33sVX5rsOO+RJr7gio3GQ4cRIBb9a0EL8ic8F40bG
R4/+cuFTVacUpC68JMPvIOXKZDPyL6Sdo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYD
VR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQU5SQIqQSqUa0S4iCIqW6D4F7BKakw
CgYIKoZIzj0EAwIDSAAwRQIhAOxtHlaXYbj/ptd0ncFWXa1fSeTfz2Ig06Nlx6c5
G+W4AiA1TbAWTspXu8dd/ky4w490fCj6nLbdvgE/uWT2npg/aA==
-----END CERTIFICATE-----
/*
* SPDX-License-Identifier: Apache-2.0
*/
"use strict";
const { FileSystemWallet, Gateway } = require("fabric-network");
const fs = require("fs");
const path = require("path");
const ccpPath = path.resolve(__dirname, ".", "network_profile.json");
async function invokechaincode(
USER_NAME,
CHANNEL_NAME,
CHAIN_CODE_NAME,
CHAIN_CODE_FUNCTION_NAME,
...ARGS
) {
let return_value;
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), "wallet");
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(USER_NAME);
if (!userExists) {
//console.log('An identity for the user "user1" does not exist in the wallet');
//console.log('Run the registerUser.js application before retrying');
return_value =
'An identity for the user "user1" does not exist in the wallet. Run the registerUser.js application before retrying';
} else {
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, {
wallet,
identity: USER_NAME,
discovery: { enabled: false, asLocalhost: false },
});
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork(CHANNEL_NAME);
// Get the contract from the network.
const contract = network.getContract(CHAIN_CODE_NAME);
// Submit the specified transaction.
// createCar transaction - requires 5 argument, ex: ('createCar', 'CAR12', 'Honda', 'Accord', 'Black', 'Tom')
// changeCarOwner transaction - requires 2 args , ex: ('changeCarOwner', 'CAR10', 'Dave')
//await contract.submitTransaction(CHAIN_CODE_FUNCTION_NAME, "BE8800","Opel","Corsa","Light Blue","7","2050","1");
return_value = await contract.submitTransaction(
CHAIN_CODE_FUNCTION_NAME,
...ARGS
);
return_value = return_value.toString();
//await contract.submitTransaction(CHAIN_CODE_FUNCTION_NAME, "b","a","1");
console.log("Transaction has been submitted");
// Disconnect from the gateway.
await gateway.disconnect();
}
} catch (error) {
return_value = `Failed to evaluate transaction: ${error}`;
//process.exit(1);
} finally {
return return_value;
}
}
module.exports = invokechaincode;
{
"name": "hlf-bityoga",
"version": "1.0.0",
"client": {
"organization": "hlf",
"connection": {
"timeout": {
"peer": {
"endorser": "300"
}
}
}
},
"channels": {
"appchannel": {
"orderers": ["orderer"],
"peers": {
"peer2": {
"endorsingPeer": "true",
"chaincodeQuery": "true",
"ledgerQuery": "true",
"eventSource": "true",
"discover": "true"
},
"peer1": {
"endorsingPeer": "false",
"chaincodeQuery": "false",
"ledgerQuery": "true",
"eventSource": "false",
"discover": "true"
}
}
}
},
"organizations": {
"hlf": {
"mspid": "hlfMSP",
"peers": ["peer2", "peer1"],
"certificateAuthorities": ["orgca", "tlsca"]
}
},
"orderers": {
"orderer": {
"url": "grpcs://46.101.220.140:8053",
"tlsCACerts": {
"path": "./hlft-store/orderer/tls-msp/tlscacerts/ca.crt"
},
"grpcOptions": {
"ssl-target-name-override": "orderer"
}
}
},
"peers": {
"peer2": {
"url": "grpcs://46.101.220.140:8055",
"tlsCACerts": {
"path": "./hlft-store/peer2/tls-msp/tlscacerts/ca.crt"
},
"grpcOptions": {
"ssl-target-name-override": "peer2"
}
}
},
"certificateAuthorities": {
"orgca": {
"caName": "orgca",
"url": "https://46.101.220.140:8052",
"httpOptions": {
"verify": false
}
},
"tlsca": {
"caName": "tlsca",
"url": "https://46.101.220.140:8081",
"httpOptions": {
"verify": false
}
}
}
}
{
"engines": {
"node": ">=8",
"npm": ">=5"
},
"scripts": {
"lint": "eslint .",
"pretest": "npm run lint",
"test": "nyc mocha --recursive"
},
"engineStrict": true,
"author": "Hyperledger",
"license": "Apache-2.0",
"dependencies": {
"fabric-ca-client": "~1.4.3",
"fabric-network": "~1.4.3"
},
"devDependencies": {
"chai": "^4.2.0",
"eslint": "^5.9.0",
"mocha": "^5.2.0",
"nyc": "^15.0.0",
"sinon": "^7.1.1",
"sinon-chai": "^3.3.0"
},
"nyc": {
"exclude": [
"coverage/**",
"test/**"
],
"reporter": [
"text-summary",
"html"
],
"all": true,
"check-coverage": true,
"statements": 100,
"branches": 100,
"functions": 100,
"lines": 100
}
}
/*
* SPDX-License-Identifier: Apache-2.0
*/
"use strict";
const { FileSystemWallet, Gateway } = require("fabric-network");
const fs = require("fs");
const path = require("path");
const ccpPath = path.resolve(__dirname, ".", "network_profile.json");
async function querychaincode(
USER_NAME,
CHANNEL_NAME,
CHAIN_CODE_NAME,
CHAIN_CODE_FUNCTION_NAME,
...ARGS
) {
let return_value;
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), "wallet");
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(USER_NAME);
if (!userExists) {
// console.log('An identity for the user "user1" does not exist in the wallet');
// console.log('Run the registerUser.js application before retrying');
return_value =
'An identity for the user "user1" does not exist in the wallet. Run the registerUser.js application before retrying';
} else {
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, {
wallet,
identity: USER_NAME,
discovery: { enabled: false, asLocalhost: false },
});
// Get the network (channel) our contract is deployed to.
const network = await gateway.getNetwork(CHANNEL_NAME);
// Get the contract from the network.
const contract = network.getContract(CHAIN_CODE_NAME);
// Evaluate the specified transaction.
// queryCar transaction - requires 1 argument, ex: ('queryCar', 'CAR4')
// queryAllCars transaction - requires no arguments, ex: ('queryAllCars')
console.log(ARGS);
console.log(CHAIN_CODE_FUNCTION_NAME);
// if (ARGS.length > 0 ) {
// console.log(CHAIN_CODE_FUNCTION_NAME);
// return_value = await contract.evaluateTransaction(CHAIN_CODE_FUNCTION_NAME,ARGS);
// return_value = return_value.toString();
// }
// else {
// return_value = await contract.evaluateTransaction(CHAIN_CODE_FUNCTION_NAME);
// return_value = return_value.toString();
// }
return_value = await contract.evaluateTransaction(
CHAIN_CODE_FUNCTION_NAME,
...ARGS
);
return_value = return_value.toString();
//const result = await contract.evaluateTransaction(CHAIN_CODE_FUNCTION_NAME,"b");
//const result = await contract.evaluateTransaction(CHAIN_CODE_FUNCTION_NAME,"a");
console.log(
`Transaction has been evaluated, result is: ${return_value.toString()}`
);
//return_value = result;
}
//return result;
//process.exit(1);
} catch (error) {
return_value = `Failed to evaluate transaction: ${error}`;
//process.exit(1);
} finally {
return return_value;
}
}
module.exports = querychaincode;
/*
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
const { FileSystemWallet, Gateway, X509WalletMixin } = require('fabric-network');
const path = require('path');
const ccpPath = path.resolve(__dirname, '.', 'network_profile.json');
async function registerUser(user_name, user_password, user_role) {
let return_value;
try {
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userExists = await wallet.exists(user_name);
if (userExists) {
return_value = 'An identity for the user "'+user_name+'" already exists in the wallet';
}
else {
// Check to see if we've already enrolled the admin user.
const adminExists = await wallet.exists('admin');
if (!adminExists) {
return_value = "An identity for the admin user 'admin' does not exist in the wallet. Call 'enrollAdmin' function before retrying";
}
else {
// Create a new gateway for connecting to our peer node.
const gateway = new Gateway();
await gateway.connect(ccpPath, { wallet, identity: 'admin', discovery: { enabled: true, asLocalhost: false } });
// Get the CA client object from the gateway for interacting with the CA.
const ca = gateway.getClient().getCertificateAuthority();
const adminIdentity = gateway.getCurrentIdentity();
// Register the user, enroll the user, and import the new identity into the wallet.
const secret = await ca.register({ enrollmentID: user_name,role: user_role,enrollmentSecret:user_password }, adminIdentity);
const enrollment = await ca.enroll({ enrollmentID: user_name, enrollmentSecret: secret });
const userIdentity = X509WalletMixin.createIdentity('hlfMSP', enrollment.certificate, enrollment.key.toBytes());
await wallet.import(user_name, userIdentity);
return_value = 'Successfully registered and enrolled user "'+user_name+'" with role "'+user_role+'" and imported it into the wallet';
}
}
}
catch (error) {
//return_value = `Failed to register user ${user_name}: ${error}`;
return_value = "Failed to register user "+user_name+": " + error;
}
finally{
console.log("'registerUser' function -> returning value");
return return_value;
}
}
module.exports = registerUser;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment