How to use CouchDB wallet in Fabric Node SDK

Keywords: Blockchain network Database Docker SDK

When an application interacts with a Hyperledger Fabric network, the Fabric node first verifies the identity of the application, that is, whether the certificate held by the application allows access to the Hyperledger Fabric network.In Hyperledger, these identities are stored in the wallet.In this tutorial, we will show you how to use a CouchDB wallet to save certificate and private key data in your application.

Hyperledger Fabric Block Chain Development Tutorial: Node.js | Java | Golang

1. Type of Hyperledger Fabric Wallet

There are three types of wallets: file system wallet, memory wallet, and CouchDB wallet.

File system wallet:

A file system wallet is a simple folder, which is a good default choice in most cases.In the fabric-samples/balance-transfer example, the file system wallet is used.When you run this sample code, it creates a fabric-client-kv-orgName folder and stores all required Fabric identities in it.This configuration definition can be referenced orgname.yaml

Memory wallet:

As the name implies, a memory wallet is a wallet temporarily stored in the application memory.This wallet can be used when running in a restricted environment or when access to the file system is not required, such as in a browser.It is important to note that the identity data in this wallet disappears when the application terminates.Specific documentation for the memory wallet can be viewed Here.

CouchDB wallet:

That is, using CouchDB to save identity data, which is the most common choice in production environments.

2. Hyperledger Fabric CouchDB Wallet

Wallet uses two libraries to hold certificates and private keys:

Status Library:

A state library is used to store a certificate of a registered identity, which stores the basic information of an identity:

{
  "name": "test",
  "mspid": "org1",
  "roles": null,
  "affiliation": "",
  "enrollmentSecret": "<ENROLLMENT_SECRET>",
  "enrollment": {
    "signingIdentity": "<PRIVATE_KEY_NAME>",
    "identity": {
      "certificate": "<SIGN_CERT>"
    }
  }
}

Note: signingIdentity points to the address where the private and public keys are stored in the cryptographic database.

Cryptography Database:

A cryptographic database is used to hold the private and public keys of an identity.

3. Enable CouchDB wallet in Hyperledger Fabric application

First introduce the CouchDBKeyValueStore library provided by Fabric Node SDK:

const CDBKVS = require("fabric-client/lib/impl/CouchDBKeyValueStore.js");

Then set up the state library:

let stateStore = await new CDBKVS({
  url: "https://<USERNAME>:<PASSWORD>@<URL>",
  name: "<DB_NAME>"
});

const Client = require("fabric-client");

const client = Client.loadFromConfig("path of network.yaml");

client.setStateStore(stateStore);

Where:

  • < USERNAME>:couchdb user name
  • < PASSWORD>:password for couchdb
  • <URL>:URL of couchdb
  • < DB_NAME>: Optional, State Library name.The default name is userdb, when the specified state library Fabric Node SDK automatically creates the library when it does not exist

Finally, set up the cryptography database:

const cryptoSuite = Client.newCryptoSuite();

let cryptoKS = Client.newCryptoKeyStore(CDBKVS, {
  url: "https://<USERNAME>:<PASSWORD>@<URL>",
  name: "<DB_NAME>"
});

cryptoSuite.setCryptoKeyStore(cryptoKS);

client.setCryptoSuite(cryptoSuite);

4. Use CouchDB wallet in Balance Transfer example

Balance Transfer Is an example code officially provided by Hyperledger Fabric.

Start the balance transfer network, which consists of:

  • 2 CA s
  • 1 SOLO Sort Node
  • Two institutions have 4 peer nodes

Start the docker image of couchdb:

~$ docker run --name couch-userdb -e COUCHDB_USER=admin \
                       -e COUCHDB_PASSWORD=password -p 5984:5984 -d couchdb

The above command automatically pulls the couchdb image from the docker hub.

The CouchDB details are as follows:

  • Container name: couch-userdb
  • CouchDB user name: admin
  • CouchDB password: password
  • URL: localhost:5984

The CouchDB connection URL s are as follows:

https://<USERNAME>:<PASSWORD>@<URL> https://admin:password@localhost:5984

Then update the client configuration in the balance-transfer example: open the file/helper.js and update the getClientForOrg function in it:

'use strict';
var log4js = require('log4js');
var logger = log4js.getLogger('Helper');
logger.setLevel('DEBUG');

var path = require('path');
var util = require('util');

var hfc = require('fabric-client');
hfc.setLogger(logger);

// couchDB config 
const CDBKVS = require("fabric-client/lib/impl/CouchDBKeyValueStore.js");

async function getClientForOrg(userorg, username) {
    logger.debug('getClientForOrg - ****** START %s %s', userorg, username)
    // get a fabric client loaded with a connection profile for this org
    let config = '-connection-profile-path';

    // build a client context and load it with a connection profile
    // lets only load the network settings and save the client for later
    let client = hfc.loadFromConfig(hfc.getConfigSetting('network' + config));

    // This will load a connection profile over the top of the current one one
    // since the first one did not have a client section and the following one does
    // nothing will actually be replaced.
    // This will also set an admin identity because the organization defined in the
    // client section has one defined
    client.loadFromConfig(hfc.getConfigSetting(userorg + config));
    
    //********************** CouchDB configuration **************************************
    // set the state store
    let stateStore = await new CDBKVS({
        url: "https://<USERNAME>:<PASSWORD>@<URL>",
        name: "<DB_NAME>"
    });

    client.setStateStore(stateStore);

    // set the cryto store
    const cryptoSuite = hfc.newCryptoSuite();

    let cryptoKS = hfc.newCryptoKeyStore(CDBKVS, {
        url: "https://<USERNAME>:<PASSWORD>@<URL>",
        name: "<DB_NAME>"
    });

    cryptoSuite.setCryptoKeyStore(cryptoKS);

    client.setCryptoSuite(cryptoSuite);
    
    //********************** CouchDB configuration END **************************************
    
    if (username) {
        let user = await client.getUserContext(username, true);
        if (!user) {
            throw new Error(util.format('User was not found :', username));
        } else {
            logger.debug('User %s was found to be registered and enrolled', username);
        }
    }
    logger.debug('getClientForOrg - ****** END %s %s \n\n', userorg, username)

    return client;
}

Our changes are as follows:

  • Line 13: Import the CouchDBKeyValueStore....
  • Lines 31-52: Set up the status and cryptography databases

There is a small change in the code above:

// Client variable is used as hfc
var hfc = require("fabric-client");

// Instead of Client
const Client = require("fabric-client");

Then register a new user in balance transfer, and once registered successfully, you can use couchdb's api to view the status and cryptography databases.

For example, you can register a user with the following parameters.For org1, we use the same library, org1db, for both the state and cryptographic databases:

Open your browser and access http://localhost:5369/org1db/_all_docs, you can see All documents saved in org1db.

Where 0#, 1#, 2# are admin's certificates.

3#is the certificate alice saved in the State Library

4#and 5#are the public and private keys alice keeps in the cryptographic database

Visit http://localhost:5369/org1db/alice to see all the details of Alice in the state library:

View signingIdentity:

"signingIdentity":"d37a97a8c2377c21537801ec1a929d81905ae57963a2f6c8ba0308931a7fc791"

Now look at the 4# and 5# pictures above and see that they are the same.

You may remember that the signingIdentity field refers to the private and public keys stored in the cryptographic database.

Original Link: Using CouchDB Wallet-Wise in Node.js Applications

Posted by andrewgarn on Sun, 09 Feb 2020 20:49:30 -0800