Photo by Micah Williams on Unsplash
Hyperledger Fabric is all about permissions. These permissions are provided in the form of certificates and keys. In broad term, it is known as Identities.
Originally published at https://schadokar.dev.
When an application interacts with the Hyperledger Fabric Network, it uses this identity to authenticate itself. Fabric network validates the identity and authorizes the application to interact.
In short, identities are very important and if you don't save them properly, then it may turn into a headache. π©
Where can I store the Identities? πΌ
In Hyperledger Fabric, this storage is known as Wallet.
There are three types of wallet:
-
File System: This is a simple folder. A local storage wallet. It is a good default choice for wallets. In
fabric-samples/balance-transfer
, thefile system
is the default wallet. When you run thebalance-transfer
it creates afabric-client-kv-orgName
folder and saves all the identities in it. This configuration is defined in theorgname.yaml
link. - In-Memory: A wallet in application storage. Use this type of wallet when your application is running in a constrained environment without access to a file system; typically a web browser. Itβs worth remembering that this type of wallet is volatile; identities will be lost after the application ends normally or crashes. - Documentation
- CouchDB: Using couchdb as a wallet. This option is best for production.
In this tutorial, we will configure the CouchDB
as the Wallet. π¨π»βπ»
For the demonstration, I am using
Fabric Node SDK
andfabric/samples/balance-transfer
.
The wallet uses 2 stores to save the certificates and keys:
1. State Store:
The state store is used to store the certificates of the enrolled identity. It stores the basic information of the identity:
{
"name": "test",
"mspid": "org1",
"roles": null,
"affiliation": "",
"enrollmentSecret": "<ENROLLMENT_SECRET>",
"enrollment": {
"signingIdentity": "<PRIVATE_KEY_NAME>",
"identity": {
"certificate": "<SIGN_CERT>"
}
}
}
βοΈ Note: The signingIdentity is the pointer or the address of the private and public key stored in the crypto-store.
2. Crypto Store:
The crypto store is used to store the public and private key of the identity.
To configure the couchdb as wallet:
Step 1
Import the CouchDBKeyValueStore
library, which is provided by the Node SDK
.
const CDBKVS = require("fabric-client/lib/impl/CouchDBKeyValueStore.js");
Do read the
CouchDBKeyValueStore.js
it is worth reading.
Step 2
Set the state store
.
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);
-
<USERNAME>
is the username of the couchdb. -
<PASSWORD>
is the password of the couchdb. -
<URL>
is the couchdb URL. -
<DB_NAME>
(OPTIONAL) is the dbname to use as state store. The default dbname isuserdb
. It creates the DB if it doesn't exist.
Client is the interface between the user and the fabric network.
Step 3
Set the crypto store
.
const cryptoSuite = Client.newCryptoSuite();
let cryptoKS = Client.newCryptoKeyStore(CDBKVS, {
url: "https://<USERNAME>:<PASSWORD>@<URL>",
name: "<DB_NAME>"
});
cryptoSuite.setCryptoKeyStore(cryptoKS);
client.setCryptoSuite(cryptoSuite);
You have to update the client according to the above steps to make it use the couchdb.
In the next section, we'll implement the above steps in the balance-transfer
fabric sample.
Implementation of CouchDB in Balance Transfer
I am using the balance transfer fabric sample as a reference.
I am assuming that you know how to run the balance transfer.
Start the balance transfer network
Follow the balance transfer instructions to start the network.
It will start the network with:
- 2 CAs
- A SOLO Orderer
- 4 peers (2 peers per Org)
Start a couchdb for the wallet
This step is optional if you're using the cloud based couchdb.
Docker-based Couchdb
docker run --name couch-userdb -e COUCHDB_USER=admin -e COUCHDB_PASSWORD=password -p 5984:5984 -d couchdb
Above command will pull the docker image of the couchdb
from the docker hub if it doesn't exist.
CouchDB Details:
- Container Name: couch-userdb
- CouchDB Username: admin
- CouchDB Password: password
- URL: localhost:5984
The CouchDB connection URL is
https://<USERNAME>:<PASSWORD>@<URL>
https://admin:password@localhost:5984
Update the client in the balance-transfer
Open the app/helper.js
and update the getClientForOrg
.
In the below code, we just replaced await client.initCredentialStores();
with the above couchdb config steps.
The changes we made,
-
Line 13: Import the
CouchDBKeyValueStore
. Step 1 from above. - Line 31-52: Set the state store and crypto store. Step 2 & 3.
There is a minor change in the above code.
// Client variable is used as hfc
var hfc = require("fabric-client");
// Instead of Client
const Client = require("fabric-client");
It is not necessary that db(dbname) of state store and crypto store is the same. Both the stores can have their separate dbs. It depends on the requirement. You can have state store and crypto store db as orgName-state-store
and orgName-crypto-store
respectively.
Each organization must have their state-store and crypto-store db, else it will throw the Authentication Error.
Error: fabric-ca request register failed with errors [[{"code":20,"message":"Authentication failure"}]]
Register a new user in the balance transfer
Once you register a user, you can check the state-store and crypto-store using the couchdb apis.
For Example: Register a user
I used the below arguments to register a user. For org1
, I used the same db org1db
for both state-store
and crypto-store
.
- Name: alice
- Org: org1
- DBNAME: org1db
- CouchDB URL: http://admin:password@localhost:5369
Open the browser, go to http://localhost:5369/org1db/_all_docs
. It returns all the docs saved in the org1db
.
The indexes 0, 1, 2
are the certificates of the admin
.
The index 3
is the alice
certificate stored in the state-store
.
The indexes 4-5
are the alice
's public and private keys stored in the crypto-store
.
Go to http://localhost:5369/org1db/alice
.
It returns all the details of the alice
stored in the state store.
Check the signingIdentity
.
"signingIdentity":"d37a97a8c2377c21537801ec1a929d81905ae57963a2f6c8ba0308931a7fc791"
Now, check the id of the indexes 4 & 5
in the above image. Both are same.
If you remember, signingIdentity
field is a reference of the private and public keys of the identity stored in the crypto store.
Conclusion
CouchDB wallet is a great choice for a production use case. You can try with other dbs but in that case, you have to write the library accordingly like CouchDBKeyValueStore.js
.
Below are the references I found helpful.
If you find any resource which you think can be added here, don't feel shy to share. π
References π
- https://developer.ibm.com/tutorials/store-fabric-certificates-keys-ibm-cloudant-fabric-node-sdk/
- https://stackoverflow.com/questions/53639061/hyperledger-fabric-what-is-the-difference-between-state-store-and-crypto-store
- https://stackoverflow.com/questions/54305378/hyperledger-fabric-client-credential-store-using-couchdb
- https://stackoverflow.com/questions/58371858/hyperledger-fabric-client-credential-store-using-couchdbcouchdbkeyvaluestore
Top comments (0)