Deep-Dive into FabCar: A Complete Application Example on Hyperledger Fabric (Part 3)

This is Part 3 of this series. We have seen Chaincode portion of FabCar application. Now we are moving forward to the Client Application portion. We will take a look on how to use SDK interacting with the deployed Chaincode in Part 2.

7. Understand FabCar Client Application

In Hyperledger Fabric, Client Application is the point external world interacting with the Fabric network and the deployed chaincode. This interaction is done through Software Development Kit (SDK). Hyperledger Fabric offers SDK for various programming languages. The officially released SDK are Java and Node SDK.

As Hyperledger Fabric is a permissioned blockchain platform, every participant must be permissioned (authorized) before one can interact with the network. Of no exception, Client Application also needs to get this permission. It is done by obtaining the appropriate certificates issued by a Certificate Authority acceptable of the Fabric network.

Inside the Client Application is the logic how a user is interacting with the Fabric network and the chaincode. Per Hyperledger Fabric design, Client Application will interact with the Peer and the Orderer, for endorsement and for block generation respectively. The access point of Peer and Orderer is needed in Client Application. Also, the channel name (Id) and chaincode name (Id) are specified when the proposal is reaching the Fabric network. Remember a Fabric network can support multiple channels and multiple chaincodes.

Finally, when Client Application performs query or invoke on the chaincode, make sure to supply the right function names and required arguments. The whole application works only when these two parts, Client Application and Chaincode, work hand-in-hand.

With this, we are going to examine this in FabCar Client Application.

As FabCar Client Application is written in JavaScript, the Node SDK is being used.

There are three NPM packages in Node SDK. You can find them here (https://github.com/hyperledger/fabric-sdk-node).

fabric-client is more from a client perspective, mainly focusing on chaincode installation and instantiation, submission of query and transaction to the network.

fabric-ca-client is for Fabric CA. Fabric CA is an optional item as some may use their own CA instead. If Fabric CA is used, this package performs all the enrollment and registration role on it.

fabric-network provides a higher level of abstraction than fabric-client, serving as submission of query and transactions to the network.

In the latest FabCar code, the fabric-network and fabric-ca-client is being used. If you see some previous chaincode you will see fabric-ca is used instead.

When we examine the code we will see how to use these two packages.

FabCar Client Application is inside fabric-samples/fabcar/ directory. The latest release 1.4 the FabCar codes are reworked in JavaScript. We see three folders: javascript/, typescript/ and javascript-low-level/. The demonstration here is using javascript/. If you are interested in pre 1.4 code, you can use javascript-low-level/. If you compare them you can see the large improvement on JavaScript coding.

Inside the fabric-samples/fabcar/javascript/ directory there are four JavaScript code. We broadly divide them into two categories.

Image for post
Image for post

The two codes enrollAdmin.js and registerUser.js are responsible for admin and user enrollment on the Fabric network before we can interact the chaincode. The result is key pair and certificates for admin and for user. In 1.4 they are stored in wallet/ directory locally.

enrollAdmin.js

We first use enrollAdmin.js to generate the certificate for an administrator.

Here is the logic

  1. Load the required modules from fabric-ca-client and fabric-network.
  2. Retrieve the detail about the Basic Network deployment. It is used for obtaining the access point of Fabric CA (line 20–21).
  3. Check whether “admin” is already inside the wallet directory. If so, no further action is needed.
  4. Enroll the admin user to the Fabric CA with enrollment ID and Secret (aligned with what is defined in Fabric CA, see ca.example.com service in the docker-compose file basic-network/docker-composer.yml).
  5. The result of enrollment is key pair and certificate. The result is then stored in wallet/admin/.

registerUser.js

Then we use registerUser.js to register and enroll user1. It is the admin we created above to perform this registration. This user can later perform query and invoke.

Here is the logic

  1. Load the required modules from fabric-network.
  2. Retrieve the detail about the Basic Network deployment.
  3. Check whether user1 is already enrolled. If so no further action is needed.
  4. Check whether admin is here. If admin is not yet enrolled, prompt for enrollAdmin.js and no further action is needed.
  5. Create a new gateway connecting to peer, with connection detail from Basic Network deployment.
  6. Register the user1 with admin created in previous part. The result is a secret.
  7. Now we can enroll the user1 with the secret.
  8. The result of enrollment is key pair and certificate for user1. The result is then stored in wallet/user1/.

The fabric-samples come with two JavaScript file: query.js and invoke.js. From the name we know that they are for the two category of chaincode invoke.

query.js

There are two function defined in the chaincode using query: queryAllCars() and queryCar(). The code query.js is for these two chaincode functions.

Since query does not involve modifying the ledger content, the request can be fulfilled in the Peer by retrieving the data requested in the local world state database.

The logic of query.js is like this.

  1. Load the required modules from fabric-network.
  2. Retrieve the detail about the Basic Network deployment.
  3. Check whether user1 is already enrolled (in wallet). If not, prompt for registerUser.js and no further action is needed.
  4. Create a new gateway connecting to peer, with connection detail from Basic Network deployment.
  5. Use the gateway to retrieve the channel (network) mychannel and chaincode (contract) fabcar.
  6. Use contract API evaluateTransaction() with the arguments required for query.
  7. The result is shown in string.

Here is where to specify the required chaincode function and arguments.

Image for post
Image for post
Use evaluateTransaction() to make query

invoke.js

There are two function defined in the chaincode using query: createCar() and changeCarOwner(). The code invoke.js is for these two chaincode functions.

The logic of invoke.js is like this.

  1. Load the required modules from fabric-network.
  2. Retrieve the detail about the Basic Network deployment.
  3. Check whether user1 is already enrolled (in wallet). If not, prompt for registerUser.js and no further action is needed.
  4. Create a new gateway connecting to peer, with connection detail from Basic Network deployment.
  5. Use the gateway to retrieve the channel (network) mychannel and chaincode (contract) fabcar.
  6. Use contract API submitTransaction() with the arguments required for query.
  7. Disconnect the gateway once transaction is processed.

Here is where to specify the required chaincode function and arguments.

Image for post
Image for post
Use submitTransaction() to invoke transactions that will update ledger

Finally, we will use the Client Application to interact with the chaincode.

For simplicity, we just perform one query function and one invoke function. The step is like this

  1. Use query.js to inspect CAR5
  2. Use invoke.js to change car owner of CAR5
  3. Use query.js again to inspect CAR5, and see if the owner is correctly changed

We can run this on top of what we have done on Section 6, as we have not acted on CAR5 yet.

First, we enroll the Administrator on Fabric CA

Image for post
Image for post

Then, we use Administrator to register the User1 and enroll User1.

Image for post
Image for post

We only need to run these two codes once. With the user1 and the key pair, we can invoke functions. User1 can be used any time when needed.

Now we can modify the two files to reflect the function.

For query.js we modify the arguments in evaluateTransaction()

Image for post
Image for post
Modify the arguments to query a specific Car ID

Now we can execute the Client Application query.js.

Image for post
Image for post

We now modify the arguments in submitTransaction() in the invoke.js such that we change the owner of CAR5 to another owner.

Image for post
Image for post
Modify the arguments to change car owner

We execute the Client Application invoke.js, and then use query.js to check the new owner.

Image for post
Image for post
Car owner changed.

Now we see the owner is changed to what we specify in the invoke.js.

This is end of Part 3. In the final part we will see how to make an API server to interact with the FabCar chaincode.

Written by

Happy to share what I learn on blockchain. Visit http://www.ledgertech.biz/kcarticles.html for my works. or reach me on https://www.linkedin.com/in/ktam1/.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store