Set up a containerized PostgreSQL database using Kubernetes and configure it as a Hyperledger Fabric wallet
Hyperledger Fabric is one of the blockchain projects within Hyperledger. It is private and permissioned; security on the Hyperledger Fabric is enforced with digital signatures. All requests made to the fabric must be signed by users with appropriate enrolment certificates. Once user is enrolled, Node js application persists certificate in wallet for future usages.
There are four types of wallets: file system, in-memory, hardware security module, and CouchDB. The Hyperledger Fabric SDK for Node.js provides a default file-system wallet for storing Fabric certificates, storing users’ certificates in folders. The Hyperledger Fabric SDK also provides a way to configure a wallet in CouchDB.
But what if an user wants to use PostgreSQL database instead of CouchDB? There is no direct provision to store enrolment certificates to PostgreSQL database. The PostgreSQL database support SQL and NoSQL data storing and has strong community support. This pattern demonstrates a methodology to use PostgreSQL database as wallet using Fabric SDK for Node.js.
At the end of this code pattern, users will understand - how to configure a containerized PostgreSQL database as a Fabric certificate wallet using Fabric Node js SDK.
- Hyperledger Fabric network is setup using IBM Blockchain Platform.
- Configure and deploy a containerized PostgreSQL database using Kubernetes.
- Deploy the client application using Fabric Node SDK through which user can communicate with blockchain network.
- To communicate with the blockchain network, users need to register and enroll with the network which will generate the enrollment certificates and store them in a PostgreSQL database. These certificates will be used for further communication with the network.
- IBM Cloud Account
- Git Client - needed for clone commands.
- Node js - 8.9 or greater
Follow these steps to setup and run this code pattern. The steps are described in detail below.
- Get the code
- Create IBM Cloud Services
- Setup Hyperledger Fabric Network using IBM Blockchain Platform
- Setup PostgreSQL Database
- Update connection profile and PostgreSQL credentials
- Run the application
- API description
- Clone the repo using the below command.
git clone https://github.com/IBM/fabric-postgres-wallet.git
Create IBM Kubernetes Service Instance
Create a Kubernetes cluster with Kubernetes Service using IBM Cloud Dashboard.
Note: It can take up to 15-20 minutes for the cluster to be set up and provisioned.
Create IBM Blockchain Platform Service Instance
Create IBM Blockchain Platform Service instance using IBM Cloud Dashboard.
Follow this tutorial to create fabric network using IBM Blockchain Platform. You can decide network components (number of organizations, number of peers in each org etc.) as per your requirement. For example, the blockchain network may consist of two organizations with single peer each and an orderer service for carrying out all the transactions.
Install and instantiate the smart contract
This code pattern can be executed with the sample chaincode fabcar.go or else you can install your own chaincode. Instantiate the chaincode after installation. You can refer to step 12 to step 14 here to install and instantiate smart contract.
Download connection profile
- Under
Instantiated smart contracts
section, click on the three vertical dots for your smart contract. Click onConnect with SDK
option. - Provide the MSP name and Certificate Authority. Scroll down and click on
Download Connection Profile
.
- Rename the downloaded json file as
connection-profile.json
. It will be used in further steps.
There are two approaches to set up PostgreSQL DB instance. Follow any one of those.
IBM Cloud provides PostgreSQL Database as a service. Type PostgreSQL
in catalog search box on IBM Cloud Dashboard and create PostgreSQL instance.
Once service is created, navigate to left menu and create service credentials.
The database credentials will be used further in step 5
.
To deploy PostgreSQL database on Kubernetes, ensure you are able to run kubectl
commands properly and then follow below steps.
Note: All scripts are available in
scripts
folder for reference.
-
PostgreSQL Docker Image
We are using PostgreSQL latest Docker image from the public registry. This image will provide the functionality of providing custom configurations/environment variables of PostgreSQL like username, password, database name and path, etc.
-
Config Maps for PostgreSQL Configurations
We will be using config maps for storing PostgreSQL related information. Here, we are using the database, username and password in the config map which will be used by the PostgreSQL pod in the deployment template.
Create PostgreSQL config maps resource as shown.
$ cd scripts $ kubectl create -f postgres-configmap.yaml configmap "postgres-config" created
-
Persistent Storage Volume
To save the data, we will be using Persistent volumes and persistent volume claim resource within Kubernetes to store the data on persistent storages.
Here, we are using local directory/path as Persistent storage resource
/mnt/data
Create storage related deployments as shown.
$ kubectl create -f postgres-storage.yaml persistentvolume "postgres-pv-volume" created persistentvolumeclaim "postgres-pv-claim" created
-
PostgreSQL Deployment
PostgreSQL manifest for deployment of PostgreSQL container uses PostgreSQL latest(or higher version 10.4) image. It is using PostgreSQL configuration like username, password, database name from the configmap that we created earlier. It also mounts the volume created from the persistent volumes and claims to make PostgreSQL container’s data persists.
Create PostgreSQL deployment using the below steps.
$ kubectl create -f postgres-deployment.yaml deployment "postgres" created
-
PostgreSQL Service
To access the deployment or container, we need to expose PostgreSQL service. Kubernetes provides different type of services like ClusterIP, NodePort and LoadBalancer.
Create PostgreSQL Service using the following step.
$ kubectl create -f postgres-service.yaml service "postgres" created
-
Get Connection Details for PostgreSQL Database
-
Get port of PostgreSQL
To get port number, run command as:
$ kubectl get svc postgres NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE postgres NodePort *.**7.*1.*53 <none> 5432:31070/TCP 5m
Here, 31070 is external port number for PostgreSQL service running on Kubernetes cluster.
-
Get the public IP for Kubernetes Cluster
Once cluster is up and running then find out the public IP of your cluster. It will be required for further steps.
a) Go to
IBM Cloud Dashboard -> Kubernetes Cluster -> <your cluster>
. It gives you details of the cluster.b) Access
Worker Nodes
tab, it will show you the public IP of your cluster as shown in below screenshot.Make a note of this public IP.
-
Connection details of PostgreSQL Database
This port number and cluster public ip will be used as db connection details further in
step 5
.
-
After setting up fabric network and PostgreSQL DB as mentioned above, perform the following steps:
-
Replace
server/config/connection-profile.json
with your fabric network connection profile which was downloaded instep 3
. -
Replace your PostgreSQL credentials in
server/config/postgres-config.json
. In case of containerized PostgreSQL database, replace IP and port in this json file. And in case of IBM Cloud PostgreSQL service, replace the json file content with your PostgreSQL credentials.
Choose the mode of deployment (local or on IBM Cloud) and perform the steps.
Deploy node app locally
To run application, first install npm dependencies and run the application.
npm install
npm start
The server will start running, visit localhost:3000 for api swagger.
Deploy node app on IBM Cloud
Deploy the application to IBM Cloud using the command:
ibmcloud cf push
Deployment might take a few minutes to complete. Ensure that there are no errors while deploying the application.
Login to IBM Cloud
. On the Dashboard
, verify that app is running fine. Click on the web application entry. When application page opens, click on Visit App URL
for api swagger.
After running application, we can see swagger UI as below:
This Fabric PostgreSQL wallet provide following APIs:
- POST user API - This API is used for registering and enrolling user to blockchain fabric network. Once user is registered certificate is stored to PostgreSQL wallet. Need to do the following changes to request body in order to register user to blockchain network:
org - should be mapped to your network org name.
user - user name you wish to register
pw - password for user (will be used for authentication of user)
attrs - this is custom attribute object, where you can add any custom attributes need to be added to certificate and which can be used by chaincode for ACL implementation.
-
GET user API - This API will return all users saved to PostgreSQL wallet.
-
POST access-token API - This API will return JWT token after validating username and password (which we provided while registering user in above POST user api) in PostgreSQL wallet. This token is encoded with user information which will be used to retrieve certificate from wallet while interacting with fabric network. Download/copy the access token generated through API.
-
GET monitor health API - This API checks the health of deployed node application.
-
GET ping API - This API will query fabric network using certificate stored in PostgreSQL wallet. To execute this api, you need to authorize first using the
Authorize
button provided in top-right corner.Click on the
Authorize
button and provide the access-token for authentication as bearerToken copied from the output ofAccess-token API
. The api will authenticate user based on token and once user is authenticated, it will decode user information (userid, role) from token, then api will retrieve user certificate from wallet based on userid (user id is used as key to store certificate in wallet). Fabric SDK for Node.js will use this certificate and connection profile to query/invoke chaincode.
Note: In this code pattern, we have installed fabcar chaincode on network, so we are calling
queryAllCars
chaincode function. Please do change this as per your chaincode functions.
- Quick start guide for IBM Blockchain Platform
- PostgreSQL DB
- Learn more about wallets of Hyperledger Fabric
This code pattern is licensed under the Apache Software License, Version 2. Separate third-party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 (DCO) and the Apache Software License, Version 2.