Walkthrough of Hyperledger Fabric Node SDK and Client Application

Photo by designecologist in pexels

Hyperledger Fabric is a container-based blockchain framework used for developing decentralized applications using plug-and-play components aimed at making it modular. It doesn’t mean that we can’t create network components (peers and orderers) natively. But this isn’t how the software is distributed. However, chaincode currently supports containerized (sandbox) environments only.

In the previous article, I have described core components and implementation of Nodejs chaincode. we’ve set up our Dev environment, developed our chaincode, get everything up & running locally. We installed and invoked all chaincode functions via our CLI Container. Everything looks fine. Now what? Is that everything we ever wanted? of course not ! We shouldn’t be satisfied at all. We need to do more. As developers, our target is users. After all, do users sit there and run respective docker commands for particular operations..? No !. we need to build neat graphical user interface with clickable operations.

Since the latest release of Hyperledger Fabric 1.4 recently, people are eager to build applications using Fabric to solve their business problems. However, many encounter difficulties in building Networks due to the complexity of Fabric in the configuration. if that is a certain degree of complexity, building middle-ware and client-side is also the same. It is because network is permissioned, you can’t directly access Network API. You need to provide proper identity and certificates to access network. This certification to outsiders can be provided by Certificate Authority(CA) using Hyperledger Fabric SDK. However, there is a good tutorial “writing your first application” available in official documentation explaining key components about client Applications. In this article, I am going to explain various modules available in Hyperledger Fabric Node SDK and a walkthrough of code involved in the issuance of certificates for various participants outside the network and how Fabric Node SDK provides access to interact with chaincode apart from the containerized environment.

Connection-Profile

Why I am talking about connection profiles here? Well, A connection profile allows SDK to connect with the network. connection profile describes entire network topology of peers, orderers and certificate Authorities and which peers are part of the channel and where they’re located. So, Whenever client submits transaction, it will then populate over all the peers using configuration defined in connection profile for the particular channel. You can only connect to the network with proper connection profile. A connection profile is normally created by an administrator who understands the network topology. Connection profiles play a key role in connecting clients to the network. Here is the structural explanation about connection profiles.

Main Modules in Hyperledger Fabric Node SDK

In the next section, we are going to walk through some code. so as a pre-requisite, we need to have basic idea on modules, various classes, and methods used in Hyperledger Fabric SDK. So skipping this section is not recommended.

SDK consists of three major modules

1.fabric-network:

This module provides a high-level API for interacting with the deployed chaincode. Interaction includes submission of transactions and queries.

2.fabric-ca-client:

This module provides various certification operations like user registrations and enrollments, re-enrollments on the network.

3.fabric-client:

This module provides network-level operations like creating channels, joining peers to the channel, installing and Instantiation of chaincode, submitting transactions and querying chaincode, querying transaction details, block height, installed chaincodes and many more.

even though fabric-client is capable of doing many operations, fabric-network is recommended API for client applications to interact with smart contracts deployed to Fabric network. because the majority of key classes for client applications are only inheritable from fabric-network.

Key Classes and methods in fabric-network

fabric-network has three main classes

1. Gateway

Gateway Class in fabric-network module is used to connect and interact with running fabric networks. this class includes various methods. those are,

a. connect:

This method connects running fabric-network based on the peers and their IP addresses defined in connection profile using existed user or Admin identity.

b. disconnect:

This method disconnects from running fabric-network and cleans up the cache.

c. getClient:

This method returns current registered client details as an object.

d. getNetwork:

This method communicates with a specified channel in the network.

e. getContract method will have access to a particular chaincode deployed to channel on top of the network defined in the connection profile.

f. submitTransaction method will submit a specified chaincode method and args to the peers(endorsers).

g. evaluateTransaction is similar to GET method in HTTP requests, it can only read the ledger state and used for query methods in chaincode.

2. FileSystemWallet

This class defines the implementation of an Identity wallet that persists to the fabric file system. this class includes some common methods exists, import, delete.

a. exists:

This method checks whether provided identity exists in the file system or not.

b. import:

This method imports generated PKI and x509 certificates and keys into the filesystem wallet under the identity of participant.

c. delete:

This method deletes the identity of a particular user from the filesystem wallet.

3. X509WalletMixin

Basically, CA provides enrollment certificates in PKI format(public key infrastructure). This class is used for creating identity in X.509 credential model using PKI user Certificates. This class includes createIdentity() method for creating Identity. This X.509 certificate is used for signing transactions in the network.

Key methods in fabric-ca-client

fabric-ca-client has few common methods used for CA operations. these are register, enroll, re-enroll.

a. register:

This method is used for registering new Participants. when registration is successful, it returns user secret. This secret needs to be provided while enrolling.

b. enroll:

This method is used for enrolling registered Participants in the network. in order to enroll, the user must be registered first. if enrollment succeeded, this method will return PKI based Certificate and Private key of the user.

c. reenroll:

There could be cases when a certificate expires or gets compromised (so it has to be revoked). So this is when re-enrollment comes into the picture and you enroll the same identity again with the CA to get new certificates using this method.

Code Walkthrough

In this section of the code walkthrough, we are going to have a look at fabcar client Application in order to understand how certificates are issued for clients Accessing network(BYFN). So make sure you’re looking at fabcar directory in fabric-samples repository or clone entire repository and switch to fabcar/javascript directory in your local clone. you should see enrollAdmin.js, registerUser.js, invoke.js and query.js. these are the main files to have a look into. In Hyperledger Fabric, Certificate issuance is a two-step process — 1.Registration 2.Enrollment.

Here enrollAdmin.js is for enrolling Admin user on the network. When we create our network, an admin user for CA will be registered as admin and secret as adminpw. Check here. So we just need to enroll Admin by providing these credentials. Once an admin user is enrolled, PKI based public key and private keys will be issued to the admin user and then X.509 based encrypted certificate will also be issued. these three credentials will then imported into the wallet.

First lets open enrollAdmin.js, however, the code is neatly commented out. We’re going to recall what we have learned so far.

Here, lines 7 and 8 import fabric-ca-client and classes FileSystemWallet, X509WalletMixin from fabric-network.

const FabricCAServices = require(‘fabric-ca-client’);
const { FileSystemWallet, X509WalletMixin }=require(’fabric-network’);

From lines 12 to 14, the absolute path of connection profile is defined and parsed contents of connection profile into JSON. this connection profile consists of enough information about various participants of the network. this connection profile is broadly used for connecting with the network.

const ccpPath = path.resolve(__dirname, '..’, '..’, 'first-network’, 'connection-org1.json’);
const ccpJSON = fs.readFileSync(ccpPath, 'utf8’);
const ccp = JSON.parse(ccpJSON);

From lines 20 to 24 in the main function, Certificate Authority used in the network is defined using connection profile configuration. If you can see connection profile in first-network, there is an object certificateAuthorities at the bottom lines of the file having all the information relating to CA. A new instance of FabricCAServices will be created using url and caName defined in connection profile and ready for enrolling Admin. this instance of ca can be used for registering users too if admin registration successful.

const caInfo = ccp.certificateAuthorities[‘ca.org1.example.com’];
const caTLSCACerts = caInfo.tlsCACerts.pem;
const ca = new FabricCAServices(caInfo.url, { trustedRoots: caTLSCACerts, verify: false }, caInfo.caName);

From lines 24 to 30, a new directory wallet will be created in current directory. A new instance of fabric FileSystemWallet will be created for the wallet to check and import identities. From lines 30 to 34, it will check whether admin user exists in the wallet or not using exists method of FileSystemWallet class. if identity admin does not exist, it will proceed for enrollments.

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) {
console.log(‘An identity for the admin user "admin" already exists in the wallet’);
return;
}

In line 37, the enroll method from fabric-ca-client module is called with enrollmentID and enrollmentSecret as an object of arguments. as said earlier, if enroll method succeded, it will return the object of PKI based certificate and private key of enrolled admin.

const enrollment = await ca.enroll({ enrollmentID: ‘admin’, enrollmentSecret: 'adminpw' });

In line 38, X.509 identity standard will be created for admin by providing certificates and private key generated in previous enrollment as arguments to createIdentity() method.

const identity = X509WalletMixin.createIdentity(‘Org1MSP’, enrollment.certificate, enrollment.key.toBytes());

When this method succeded, it will return X.509 based encrypted signing Certificate. this certificate can broadly be used for registering new users. In line 39, previously generated PKI certificates and X.509 signing certificate will then import into the wallet under the identity of admin.

await wallet.import(‘admin’, identity);

Register user:

As we already know, registration of new users can only be done by CA and it should have a proper x509 standard signing Certificate to issue identities to new users. in the previous section of code, we’ve seen how admin enrollment is done and x509 signing Certificate is issued to admin. The same approach will be applied for registering users. For that, user needs to be registered first. While most part of the code in registerUser.js is similar to enrollAdmin.js, we are going to walk through a few new things in registerUser.js. so, open registerUser.js and have a look at line 36 here, Gateway class from fabric-network module is used for connecting network. As we already know, only authorized participants will have access to the network. In this case, CA admin is already Authorized, so we can use CA admin identity to connect with network. In the next line, gateway initiates a connection to our network by using connection profile and admin identity from the wallet. it says gateway to look at localhost as our network is running locally (asLocalhost : true).

const gateway = new Gateway();

await gateway.connect(ccpPath, { wallet, identity: 'admin’, discovery: { enabled: true, asLocalhost: true } });

Line 40, 41 returns underlying admin of CA. This admin is used for registering user

const ca = gateway.getClient().getCertificateAuthority();
const adminIdentity = gateway.getCurrentIdentity();

Line 44 registers a new user using register method by taking Affiliations, user Id, admin identity as an object of arguments. As said earlier modules walkthrough, register method will return the secret of the newly registered user and this secret can be used for enrolling user on the network.

const secret = await ca.register({ affiliation: 'org1.department1’, enrollmentID: 'user1’, role: 'client' }, adminIdentity);

In the next line, secret of the registered user will be passed to enroll method. once, user enrollment is done, PKI Certificates will be issued and then an Identity certificate(X.509)for the user will be created. Voila..!! This identity will be used for accessing and interacting with the network and X.509 signing certificate will be used for signing transactions. These three credentials will then import into the wallet under the identity of user user1.

const enrollment = await ca.enroll({ enrollmentID: 'user1’, enrollmentSecret: secret });
const userIdentity = X509WalletMixin.createIdentity(’Org1MSP’, enrollment.certificate, enrollment.key.toBytes());
await wallet.import(’user1’, userIdentity);
```

Querying and Invoking Chaincode:

In the previous sections, we’ve seen how identities are issued for admin and users. In this section, we are going to walk through actual code that query and invoke chaincode using user1 identity created in the last section. So, open query.js, traditionally as an initial thing, it will import required modules and defines connection profile, checks whether admin exists or not and then checks if the user is registered or not.

In lines 29–30, it will initiate the Gateway connection, connects with the network using user1 Identity.

const gateway = new Gateway();

await gateway.connect(ccpPath, { wallet, identity: 'user1’, discovery: { enabled: true, asLocalhost: true } });

On line 33, the gateway will then have access to channel named ‘mychannel’ in the network using getNetwork () method

const network = await gateway.getNetwork(’mychannel’);

In line 36, the gateway will have access to the deployed contract (fabcar) in ‘mychannel’ using getContract() method of Gateway class.

contract = network.getContract(’fabcar’);

In line 41, it will query a particular chaincode method by taking arguments(if applied)defined in evaluteTransaction() . In this line, it queries queryAllCars chaincode method. so it doesn’t require arguments.

const result = await contract.evaluateTransaction(’queryAllCars’);

evaluteTransaction() method is a is a get method. it will simply pick a peer defined in connection profile and query ledger state of a particular key from that peer and return result instantly.

in invoke.js code, there is a method submitTransaction() for submitting transactions by taking chaincode function name and arguments. here , createCar function will be invoked with arguments.

await contract.submitTransaction(’createCar’, 'CAR12’, 'Honda’, 'Accord’, 'Black’, 'Tom’);

Since it writes data onto the ledger, so the transaction will be populated over the network. once endorsing peers executed transaction, the ledger state will get updated with a new car.

Conclusion

Now that we’ve explored various modules in Hyperledger Fabric Node SDK and walkthrough of code involved in registering and enrolling users. We looked at how SDK provides Access to interact with chaincode functions. you should have a good sense of how applications interact with a blockchain network using SDK. this is not the end. Now a days Accessing Application is done by REST API,which is not yet available officially in Hyperledger Fabric. However, it is not very difficult to build API with one of the famous JavaScript library express. I made few Hyperledger Fabric Applications using express routing and traditional frontend things aiming for beginner. You can have a look at one of them here.

Happy Hyperledger Fabric 🤗

References

  1. https://github.com/hyperledger/fabric-samples/tree/v1.4.3/fabcar/javascript
  2. https://fabric-sdk-node.github.io/release-1.4/index.html
  3. https://hyperledger-fabric.readthedocs.io/en/release-1.4/write_first_app.html


Walkthrough of Hyperledger Fabric Node SDK and Client Application was originally published in Data Driven Investor on Medium, where people are continuing the conversation by highlighting and responding to this story.