Chaincode for Go developers, Part 3: Develop a client application for a blockchain network based on Hyperledger Fabric v0.6

Chaincode for Go developers, Part 3: Develop a client application for a blockchain network based on Hyperledger
Fabric v0.6

Chaincode for Go developers, Part 3

Develop a client application for a blockchain network based on Hyperledger
Fabric v0.6

A deep dive into the building blocks of a Node.js client app

Content series:

This content is part # of # in the series: Chaincode for Go developers, Part 3

https://ibm.co/2pLAj8Q

Stay tuned for additional content in this series.

This content is part of the series:Chaincode for Go developers, Part 3

Stay tuned for additional content in this series.

Get a monthly roundup of the best free tools, training, and community
resources to help you put Blockchain to work. Current
issue | Subscribe

With the Hyperledger Fabric Client SDK for Node.js,
you can easily use APIs to interact with a blockchain based on Hyperledger
Fabric v0.6. This tutorial shows you how to write some of the most common
and necessary functions in a client application. All code examples in this
tutorial are included in the reusable sample client that you can download and
customize to fit your needs.

In this tutorial, the conclusion of a three-part series, you’ll learn how to develop a Node.js client
application to talk to a blockchain network based on Hyperledger Fabric
v0.6. You’ll learn about registration, enrollment, and access control
through TCerts, and get code for setting up a blockchain network, a
Cloudant-based key value store, and an API layer for invoking and querying
the blockchain. By following the steps in this tutorial, you can deploy
the chaincode you developed in Part 1 onto the Blockchain service on IBM Bluemix® and invoke it from your
client application.

Key terms and concepts

The Hyperledger Fabric Client SDK is the official SDK for
Hyperledger Fabric v0.6. It is written in TypeScript and has comprehensive
APIs to interact with a blockchain network based on Hyperledger Fabric via
a Node.js application. The SDK uses gRPC to talk to the blockchain
network.

Chain. The chain is the top level object that gets
the ball rolling. The chain object is used to configure the peers,
membership services, security, key value store, and the event hub. The
chain object gives access to available Member objects, which are used
to transact on the blockchain network.

Member. The member object represents an entity that
can transact on a blockchain network. The member object is used to
register and enroll with the membership services. Once the
registration and enrollment are done, the member object stores the
received certificates in the previously configured key value store.
The member object can then be used to talk to the peer(s) on the
blockchain network to invoke transactions and query the ledger.

KeyValueStore. The KeyValueStore stores member
metadata and enrollment certificates. The SDK provides a default
file-based implementation for the KeyValueStore that can be used in
the client application. However, it is recommended that you write your
own implementation for the KeyValueStore that is more secure and
easily accessible. I’ll take you through an implementation for the
KeyValueStore that is based on Cloudant NoSQL DB in our client.

Registration, enrollment, and access control. To
interact with a blockchain network based on Hyperledger Fabric, a user
needs to register and enroll with the Certificate Authority (CA). The
CA generates transaction certificates, which are required for
transacting on the blockchain network and which can also be used for
attribute-based access control. The CA provides several different
certificate services:

Enrollment Certificate Authority (ECA). The
ECA enables new users to register with the blockchain network
and subsequently request an enrollment certificate pair. The
pair consists of two certificates, one for data signing and
one for data encryption.

Transaction Certificate Authority (TCA) .
Once the user is enrolled in the blockchain network, the user
can request Transaction Certificates (TCerts). TCerts are
required for deploying chaincode and for invoking chaincode
transactions on the blockchain network. The TCert can also be
embedded with encrypted user-defined attributes. These
attributes can then be accessed in the chaincode for access
control. A best practice to ensure privacy is to a different
TCert for every transaction. This is the default behavior of
the SDK.

TLS Certificate Authority. TLS certificates
secure communication channels between the client, peers, and
the CA. The TLS certificates can be requested from the TLS
certificate authority (TCA).

Attribute Certificate Authority (ACA). The
ACA stores attributes for each user and affiliation in a
database. It certifies whether a particular user has ownership
of the attributes. The ACA returns an ACert for validated
attributes, with the attribute values encrypted.

The user makes a registration request to the ECA and passes in
an enrollment ID, role, affiliation, and attribute key value
pairs, among others.

If the enrollment ID passed in is not already registered, the
ECA responds to the user with a one-time password.

The user makes an enrollment request to the ECA and passes in
a signing and encryption key along with the one-time password
token obtained in the previous step.

Upon verification, the ECA returns an enrollment certificate
pair. This pair consists of two certificates, one for signing
and one for encryption. This pair along with other user
metadata is then stored in the key value store configured in
the chain object.

The ECA makes a fetch attributes request to the ACA, passing
in the ECert generated in step 4.

The ACA stores the ECert along with details such as
affiliation, attribute key/value pairs, and their validity in
its database.

The user makes a request for TCerts to the TCA, which can be
used for invoking the chaincode. The user passes in the ECert,
the number of TCerts to be generated, and a list of
attributes, which can be a subset of the list of attributes
passed in step 1.

The TCA makes a request to the ACA to ensure the user
possesses the said attributes. The TCA passes in the ECert
along with the list of attributes.

The ACA looks up the attributes in its database.

If no attributes are found, an error is returned. If all or
some of the attributes are found, then an ACert with the found
attributes are returned to the TCA.

The TCA creates a batch of TCerts and returns them to the
user. Each TCert contains the valid attributes.

Get started

The code samples in this tutorial and available for download were developed and tested with the
following software and versions:

Create the IBM Blockchain service on
Bluemix

When you have your Bluemix account, create the Blockchain service on Bluemix. Be sure to select
the Starter Developer plan (beta), which will set up
a blockchain network for you based on Hyperledger Fabric v0.6.

When you have created the service, navigate to your Blockchain service
homepage and click Service credentials in the
navigation:

You can now see the credentials for your service. Copy the entire
contents in the text box and store them in a safe place. These
credentials contain the information necessary for a client
application to talk to the blockchain network. Later sections in
this tutorial will explain how to put these service
credentials into the configuration file for your sample
client.

Create the Cloudant NoSQL DB service on
Bluemix

The sample client uses my custom implementation of a Cloudant-based key
value store. The Cloudant service is a NoSQL DB service powered by couch
DB. So, as with the Blockchain service, you’ll use your Bluemix account
(get a Bluemix free trial account).

When you have your Bluemix account, create the Cloudant service. Select the Lite (free)
plan.

When you have created the service, navigate to your Cloudant service
homepage and click Service credentials in the
navigation.

Click View credentials under ACTIONS.

You can now see the credentials for your service. Copy the entire contents
in the text box and store them in a safe place for later use.

Download the sample code package

Download and unzip the sample code package (download
it from this tutorial). Navigate to the root of the unzipped
code_package directory in the terminal and run npm install.
This command will download all the modules required to run the sample
client. When complete, you should see a node_modules folder in your
code_package root.

Deploy the sample chaincode

Before you can run the client, you need to deploy the chaincode_sample.go
found under code_package/chaincode/ to the IBM Blockchain service you
created earlier.

Under the APIs section, click Network’s Enroll IDs.
This section lists users that are already registered with the
blockchain network and need only to be enrolled before they can deploy
and invoke the chaincode.

Click the Try It Out button to execute the REST
call to the selected peer in the blockchain network. You will get
a response saying the user has been successfully logged in. Now
you can use the user_type1_0 for deploying the chaincode.

chaincodeID is the path to the chaincode_sample.go
file in a GitHub repository. For this tutorial, I have already
created the repository and uploaded the client code along with the
chaincode for your use.

Click the Try It Out button to execute the Deploy
request. You should get a response similar to this:

Under the chaincode object, replace the value forid with the chaincode ID you saved in step
4-5.

Replace the contents of the credentials object under
the ibm-blockchain-5-prod object with the service
credentials you obtained from the Blockchain service on
Bluemix in step 1-3. The service credentials have a cert link to
download the certificate used for TLS communication between the
client and the Blockchain service: “cert”:
http://bit.ly/2quavwY

Though I have already included the cert in the code_package, I
recommend that you replace that with the cert found at the link
above. Place the cert in the root folder of the code_package.

Similarly, if you want to use the Cloudant-based key value store
implementation for running the client, replace the contents of thecredentials object under thecloudantNoSQLDB object with theservice credentials you obtained from the Cloudant
service on Bluemix in step 2-3.

Code package structure

Let’s take a quick detour to examine the code_package structure, and then
we’ll resume with step 7.

The blockchain_sample_client.js shown in the listing above
does the following:

Reads command line parameters passed in while invoking the client. The
client expects two values: username and affiliation. The client will
use default values if none are provided during client invocation.

The client then performs the setup of the blockchain network. During
setup, the chain object is initialized and configured with all the
peers and membership services that the client intends to talk to. The
cloudant datastore Is also initialized as part of the setup.

The client then goes on to register the default user or the one passed
in as a command line parameter.

This is followed by the enrollment step, where the one-time password
retrieved during registration is used for obtaining the ECert pair.
This ECert pair will be stored in the Cloudant-based key value
store.

The client then creates a sample mortgage application json object.
This client then invokes the createMortgageApplication API in the
blockchain_sdk.js file. This createMortgageApplication method invokes
the appropriate chaincode method in blockchain and passes in the loan
application JSON content.

Once the mortgage application has been successfully created, the
client invokes the getMortgageApplication method, which in turn
queries the blockchain by invoking the appropriate chaincode method to
fetch the mortgage application created in the previous step.

Lines 7 and 8 fetch the Cloudant and Blockchain
service credentials from the runtime.json file, which we had updated
earlier. The config module parses the runtime.json file and makes the
contents available as a JSON object.

Lines 11 to 15 initialize the Cloudant datastore. The
datastore.js file will be used to obtain a handle to a DB instance,
which can be used to perform CRUD operations on our Cloudant
database.

Lines 18 to 24 initialize the custom Cloudant-based
key value store implementation with the DB instance obtained earlier.
This key value store will be used by the Hyperledger Fabric Client SDK
chain object to manage ECerts and other user metadata. This is
followed by the blockchain network setup.

On line 8 a new chain object is created using the
Hyperledger Fabric Client SDK module hfc.

On line 11 the chain object is configured with the
key value store implementation to use for managing ECerts for the
users. In this case, it is the Cloudant key value store
implementation. The Hyperledger Fabric Client SDK also provides a
default file-based key value store implementation that can be used.
(But for deploying the blockchain client application on the cloud, the
file based implementation is not advised, because redeployments of the
client code will lead to loss of the file-based key value store. In
this case, all previously registered users would be rendered useless
since they would not have the required certs to authenticate.)

On line 12 the cipher suite is set to ECDSA for TLS
communication.

Configuration properties for the chain object

IsSecurityEnabled: If the chain object is configured
with a valid membership services endpoint, security is considered to
be enabled. Security enabled means that a TCert will be used to
generate an ECDSA-based digital signature that will be sent as a part
of all chaincode invocation transactions. This TCert will be used by
the respective peer to authenticate the caller.

IsPreFetchMode: In pre-fetch mode, the chain object
will request a batch of TCerts from the membership services upon
initialization instead of waiting for a transaction invocation call.
The intent is to boost performance.

TCertBatchSize: The number of TCerts to be returned
as a part of the get TCert batch request. Default value is 200.

Lines 13 to 17 parse the blockchain service
configuration to retrieve the list of peers and add the discovery url
for these peers to the peerHosts collection.

Lines 18 to 21 retrieve the url for the CA
(membership services). The value for
constants[‘BLOCKCHAIN_NW_PROTOCOL’] is “grpcs”. IBM Bluemix Blockchain
service only supports secure communication.

Lines 23 to 29 retrieve the password from the list of
pre-registered users available in the blockchain service credentials
for WebAppAdmin. As stated earlier, the WebAppAdmin user has registrar
rights. This means the WebAppAdmin user can be used to register other
new users onto the blockchain. This password will be used for
enrolling the WebAppAdmin later.

Line 7 reads the pem file we downloaded from the cert
path provided in the Blockchain service credentials. TLS is enabled
for all communication in the Bluemix Blockchain network. This also
includes the communication between the client application and the
network entities, such as membership services and the peers.

Lines 14 to 17 add the membership services and peers
URLs obtained earlier to the chain object along with the pem file. The
pem file be used by the chain object while communicating with the
membership services and peers.

Lines 19 to 28 enroll the WebAppAdmin in the
blockchain network. As explained earlier, enrollment will generate the
ECert pair, which will be stored by the chain into the cloudant key
value store. If you look at the documents in your cloudant database
via the cloudant service dashboard you should see an entry for
member.WebAppAdmin now, as in this example:

affiliation (string): Affiliation for this member.
Affiliations can be found in the manifest.yaml file. For the
Blockchain service on Bluemix, the parent affiliation isgroup1.

attributes (Attribute[]): The attribute names and
values to grant to this member. These attributes are user-defined and
are stored in the ACA. All or some of these attributes will be
embedded in the TCert requested by this member. The same attributes
will be available to the chaincode for implementing access control by
parsing the caller TCert.

registrar: A user can have the role of a registrar,
which would enable the user to register other members. A member object
with registrar rights needs to be included as a part of the request.
This registrar member will be used to register the requested member.

Lines 7 and 8 retrieve the chain object from the
blockchain_network.js file and retrieve the registrar object from the
chain object.

Line 11 retrieves the member object from the chain.
For any interaction with the blockchain network based on Hyperledger
Fabric, we must have a handle to the member object on whose behalf all
chaincode deployments and invocations can occur. The getMember method
retrieves the member ECert and other metadata information from the
Cloudant key value store.

Lines 15 to 23 create a registration request. Please
note the attribute key/value pairs for username androle. Part 1 of this tutorial series showed how the
chaincode leveraged these attributes for implementing access
control.

Line 27 invokes the register method on the member
object, and subsequent code retrieves the one-time password token
returned from the ECA to be used in the enrollment process.

Lines 7 to 22 perform input validation. The method
expects two parameters: User (that will be used to invoke
the chaincode transaction) and the mortgage application JSON content
to persist on the blockchain.

Line 28 creates the request spec that needs to be
used for invoking the chaincode.

Line 29 calls the recursiveInvoke
function that actually invokes the chaincode per the request spec
provided.

Line 8 retrieves the chaincode ID for the deployed
chaincode from the config (runtime.json). This is the chaincode we
want to invoke.

Line 14 retrieves the name of the function to invoke
in the chaincode. In this case, it is theCreateLoanApplication method.

Line 26 puts in the attribute keys. These have been
hard-coded to role and username but should ideally be passed in as
parameters to the getRequestSpec method.

Note:
If the attribute keys are not passed in as part of the request
spec, these attributes will not be sent as a part of the get
TCert request to the TCA and hence, the resultant TCert will
not have any embedded attributes. When the chaincode
tries to parse this TCert to retrieve the specific attributes (for
example, role and username) for access control, it will fail.Lines 32 to 37 contain the actual request
spec schema.

The getMortgageApplication method is similar in structure to
the createMortgageApplication method. It accepts the user on
whose behalf the chaincode has to be invoked along with the ID for the
mortgage application to fetch.

This is followed by the getRequestSpec method for creating the
request spec as before and invoking the recursiveQuery method
to query the blockchain.

Line 7 invokes the query method on the
member object passing in the appropriate request spec.

When the query transaction has successfully executed on the blockchain, thecomplete event will be called. The data read from the
blockchain needs to be read into a buffer. Because our chaincode
implementation stored the data as a JSON string, the returned content
needs to be parsed as JSON.

Subscribe to events

A blockchain network based on Hyperledger Fabric has a built-in event hub
that our client application will connect to and listen for events.

Here is the code snippet for connecting to the event hub and subscribing to
events. This snippet is in the blockchain_network.js file, but it has been
commented out due the second item noted in the Known
issues section below.

Line 1 connects to the event hub for the specified
peer. The service credentials for the Blockchain service in
runtime.json has the event_host andevent_port values for each peer. These are used to
establish the connection to the event hub.

Line 2 invokes the setupEvents() method
that can be used to subscribe to and handle events from the
blockchain.

Line 11 shows how to register for a chaincode event
and defines the handler function when the event is published. The
chaincode that we deployed emits an event on successful creation of
the loan application. Here we are registering for the same event.

If you run the client with events enabled (uncomment the event code in
blockchain_network.js), the createLoanApplication event
defined in the chaincode will be received by the client and printed to the
console.

Known issues with Hyperledger Fabric
Client SDK

This error occurs when TLS is enabled for communication. One of the
primary reasons for this failure is not having enough file
descriptors available in the operating system. It occurs most
frequently on MAC machines (EL Capitan), less frequently on
Windows 7 machines, and almost negligibly when the
application/client is deployed and run on Bluemix.

To work around this issue during development and testing, I wrap
all Hyperledger Fabric Client SDK calls to the blockchain network
in recursive functions. The retry interval and number of retries
can be changed by modifying the retryInterval andretryLimit variables in the blockchain_sdk.js
file.

EventHub not connecting or crashing post connection.

This error has been attributed to open bugs in some dependent
third-party libraries, such as the grpc node module.

Conclusion

You’ve now seen the steps and code for developing your own Node.js client
to talk to a blockchain network based on Hyperledger Fabric v0.6, and for
deploying the chaincode you developed in Part 1 onto the IBM Blockchain
service on Bluemix so you can invoke it from your client application.
Download the code associated with this tutorial and get started.

This concludes this tutorial series based on Hyperledger Fabric v0.6. I’m
updating this series for Hyperledger Fabric v1.0, so stay tuned!