Developing multi-user application using the Hyperledger Composer REST Server

Firstly, some quick background. What is Hyperledger Composer? It’s a framework for rapidly building Blockchain business networks on top of a Blockchain platform, such as Hyperledger Fabric. It’s pretty cool. You can find some more information here: http://hyperledger.github.io/composer/

Blockchain is a technology for building networks that connect organizations together. Once started, a Blockchain network allows participants to transfer assets between each other by submitting transactions, and those transactions are recorded in an immutable ledger.

So once you have your Blockchain Network how do you integrate with your client application? One solution would be to call the Hyperledger Composer JavaScript APIs directly or you could use the Hyperledger Composer REST Server in multi-user mode.

The Hyperledger Composer REST Server will generate a set of REST endpoints from a Hyperledger Composer Model. The endpoints can then be called from a client application to interact with a Blockchain. When the client applications calls one of the REST endpoints, the REST server will then submit a transaction to the Blockchain. This transaction must be signed by a certificate to say which identity is being used to submit the transaction. When the REST server is started it must be given a identity to use and by defaults all transactions will be signed with this identity.

The REST server can be configured to use authentication. This allows a client application to authenticate with the REST server and then the REST server can distinguish between each of the clients.

However this still doesn’t allow the Blockchain to distinguish between clients. The REST server will still sign each transaction with the same certificate. To enable the REST server to sign each transaction with a different identity per authenticated client the REST server must be configured to use multi-user mode. Each authenticated client will then have a private wallet on the REST server that contains the identity that will be used to sign the transaction on behalf of the different authenticated clients.

This article shows how to configure the REST server for multi-user mode and how it can be called from a client application to add participants and identities and how to submit transactions that are signed by different identities. The client app is written using Angular and will use GitHub authentication to authenticate itself with the REST server. This is just one example of the type of authentication that can be used. The REST server uses an open source library called Passport and there are over 300 plugins that are available to use, eg. LDAP, Facebook, SAML, and Google.

If you haven’t downloaded Hyperledger Composer you can follow the instructions to setup your development environment here: https://hyperledger.github.io/composer/installing/development-tools.

Once you have the development environment setup you firstly need to create and deploy a business network. The one I have used in this article can be found here: https://github.com/caroline-church/collectable-penguin-app/blob/master/collectable-penguin-network.bna. The client app used can be found here: https://github.com/caroline-church/collectable-penguin-app. The app allows users (Collectors of penguins) to sign up and to buy penguins from a “wholesaler” and each user has their own set of penguins which they have bought.

To setup the app you first need to add an OAuth application to GitHub here: https://github.com/settings/developers.

The app needs to have two REST servers running. The first has no authentication and will run in single user mode. This REST server will just be used to create participants and identities when users sign up to the app. It can be started by using the following command.

composer-rest-server -c admin@collectable-penguin-network -p 3001

The second REST server will run in multi-user mode. Firstly you need to set an environment variable to set some properties for the REST server. The <CLIENT-ID> and <CLIENT-SECRET> properties can be found in the github OAuth app that was created previously. The successRedirect property is set to the url of where app is running.

export COMPOSER_PROVIDERS='{
"github": {
"provider": "github",
"module": "passport-github",
"clientID": "<CLIENT-ID>",
"clientSecret": "<CLIENT-SECRET>",
"authPath": "/auth/github",
"callbackURL": "/auth/github/callback",
"successRedirect": "http://localhost:4200?loggedIn=true",
"failureRedirect": "/"
}
}'

Once the environment variable is set then the second REST server can be started with the following command

composer-rest-server -c admin@collectable-penguin-network -m true

The client app can then call the REST endpoints. To start the user needs to authenticate with GitHub. This can be done be having a link on the page, the URL is the URL of the multi-user REST server e.g

<a href="http://localhost:3000/auth/github">Sign in with github</a>

Then the user needs to sign up to the app. This data can then be used to create a participant and identity. In this case a Collector participant will be created.

The following will create a Collector participant using the single user REST server

return this.httpClient.post('http://localhost:3001/api/org.collectable.penguin.Collector', collector).toPromise()

The body of the post should be the data the user supplied e.g.

const collector = {
$class: 'org.collectable.penguin.Collector',
collectorId: 'carolineId',
firstName: 'Caroline',
lastName: 'Church'
};

Once the participant has been created then an identity can be issued for that participant, again using the single user REST server. The response type must be set to blob as this endpoint returns a business network card.

return this.httpClient.post('http://localhost:3001/api/system/identities/issue', identity, {responseType: 'blob'}).toPromise();

The body of the post should include the ID and participant created previously e.g.

const identity = {
participant: 'org.collectable.penguin.Collector#carolineId,
userID: carolineId,
options: {}
};

The newly created identity can then be added to the wallet of the multi-user REST server. The card from the previous call to the endpoint is used to create a new file object, this file object is then used to create some formData. A header is added to the request to set the content type to be multipart/form-data. The wallet import endpoint can then be called with the data. The withCredentials option is set in-order to create a cookie to pass the authentication token to the REST server.

const file = new File([cardData], 'myCard.card', {type: 'application/octet-stream', lastModified: Date.now()});
const formData = new FormData();
formData.append('card', file);
const headers = new HttpHeaders();
headers.set('Content-Type', 'multipart/form-data');
return this.httpClient.post('http://localhost:3000/api/wallet/import', formData, {withCredentials: true, headers}).toPromise();

Now the client is authenticated with the REST server and an identity has been added to the wallet the endpoints can now be called. The REST server will submit transactions that are signed with the identity that was previously added.

For example the following HTTP request will get all the available penguins

return this.httpClient.get('http://localhost:3000/api/queries/availablePenguins', {withCredentials: true}).toPromise();

And the next HTTP request will get the penguins that the authenticated user owns

return this.httpClient.get('http://localhost:3000/api/queries/myPenguins', {withCredentials: true}).toPromise();

So now you know how to create a multi-user application using the Hyperledger Composer REST Server! But one last thing. If you have tried running the app you may have noticed alot of pictures of penguins. These are all penguins owned by the Hyperledger Composer team and are given to (or thrown at) people who break the build!