Simple blockchain network with Hyperledger Composer

Our business case is quite simple — we will write a very naive implementation of asset tokens.

You can read more about them on our blog, but in layman terms those are tokens which are issued for a specific asset (yep 🙂 I know — shocking!).

The difference from other token types is that they kinda represent a share on a very specific item.

It is not a share of business that sells art, but a share in a specific art piece.

It has ups and downs — if you own a share in the art selling business you will receive a dividend based on an average selling margins.

But if you own a share in a specific art piece, if it performs — you might get very, very rich.

If it does not — you might make nothing (or actually loose money).

There will be two actors on our network.

A Merchant — vetted by “our” company / owner of the blockchain, to make sure only real merchants can offer Mona Lisas and Sunflowers.

They can list an art work on our system, issue tokens for it and name them.

A merchant might decide to sell the art, removing it from the system.

A Person — our main user that will buy tokens for a specific art works and will be able to either agree to sell the work or not, when merchant calls for it.

What is important — we are just implementing the “storage” part of our system.

Our solution will expose transactions via REST services that will have to be used by some other software that will implement the exchange of tokens, auctions of art works, user registration, merchant vetting etc.

etc.

etc.

We will just provide a way to store all data on the blockchain.

Bootstrap the NetworkFirst thing you need to do is to make sure the Hyperledger Composer and Fabric are working on your machine.

Simply follow this user guide.

Once this is set up, create a new network by typing yo hyperledger-composer:businessnetwork.

Call the network merchant-network and for the package use org.

szimano.

merchantnetwork (or whatever you prefer, just remember to update package name in the following examples).

ModelOnce the network is bootstrapped, we can start writing the business logic.

First thing we’re gonna write is the model.

It consists of four things:Participants that represent the actors of our system, but also provide granular access to it (when you connect to the blockchain you will be identified as one of the actors on the system).

Assets which are the entities stored on the chain.

Transactions which are the operations on the assets.

Events that can be emitted during transactions for your applications to listen on.

The model file will start with the namespace defined.

So now let us start with the assets then.

First one will be a very simple actor called Person.

Every asset has to have a primary key and we have added a name field.

Fields are marked with o at the beginning.

The second actor will be our Merchant.

It extends the Person, so we do not need to specify the primary key (it will be inherited) and there is no extra information we need to store about the Merchant except them being the Merchant :)Once the participants are settled, we will need to define our assets.

The first one will be the art work itself.

You can see there are two new things — keyword asset and a new ascii art arrow –> meaning a relation.

The assets also needs a primary key plus we have added a description field on which we will store a human readable description of the art work.

Once we have the art, we can create an art token.

Those tokens have names, they are bound to an art work plus they are owned by a Person (which can be both Merchant and regular Person).

The onSale, defaulted to false, will be used by the Person to mark their tokens as "ready to sale".

The assets are in place, now we need the transactions that will trigger the actions on our network.

First one is the transaction during which a Merchant will be able to list an art on the system.

Once the art is listed, we need a way of sending tokens between the users.

And finally, the merchant needs to have a way of selling the art work.

Now, when the model is ready, we need to implement how the system will run on top of it.

QueriesIn the project root create a queries.

qry file – you can define named queries that will use a SQL-like language.

In our case we will need two – the ability to select all tokens for a given art and a given token owner:and a second one to get all tokens for a given art:If you know SQL (and I am pretty sure you do), the above looks very familiar.

The _$VAR is a notation for passing external parameters to the query (more on the usage of those later).

Smart Contract (aka logic.

js)Now, that we have all the bits and pieces in place, we can create our “smart contract” that will list the art work on our system, issue tokens for it and assign them all to the merchant.

You need to start with a specially prepared comment with annotations (like xdocklet in Java that I was using when I started my first job 12 years ago 😀 ).

Our method takes one parameter which is the transaction that we want it to process.

It will be marked with @param annotation, followed by a fully qualified type of the transaction.

It will return a string, which we have to mark with @returns annotation.

And finally, since this is a transaction processor, we need to mark it with @transaction annotation.

Then another transaction to send tokens between users:In this method, we are sending tokens between two participants.

One thing worth noticing is that in code block [1] we are using a query.

The difference here is that instead of passing the actual object as a parameter we need to create a special string pointing to the resource that has a form of: resource:{FULLY_QUALIFIED_TYPE}#{ID}.

In our example we need to pass a Person resource, but since this can be either a Person or Merchant (which inherits from Person) we cannot just hard-code the namespace.

Instead, we are calling getFullyQualifiedType() on the sender object which will give us what we need (either org.

szimano.

merchantnetwork.

Merchant for Merchant or org.

szimano.

merchantnetwork.

Person for Person).

Remember that a Person with a given ID is a different resource then a Merchant with the same ID.

Inheritance here is very limited!Once [7] is executed, the owner of the ArtToken will be changed and the sender user will no longer have access to them.

The final transaction is for selling the art.

To make it easier, we are just writing the transaction on the blockchain to mark that the art has been sold.

The tokens are not then removed from it — this is something that could be done in further network development.

What we are going to use is the onSale field that is set to false by default.

Every owner of an asset token can mark its onSale to true which means that he or she is ready to sell the art.

Once at least 50% of the tokens for a given art work are set as onSale = true then our network will allow creating a sale transaction.

PermissionsSince this is a permissioned blockchain we need a way of describing the permissions.

They all have to have:a unique rule namedescriptionparticipant — for whom should the rule be evaluated (connected user to the blockchain)operation — a mix of READ, CREATE, UPDATE, DELETE and ALLresource — for which asset or participant on the blockchain should the rule be evaluatedaction — either ALLOW or DENYtransaction /optional/ — inside which transaction should this rule be evaluatedcondition /optional/ — a logic that can bind the participant, asset and transaction (see below)The participant and resource can be followed by #{ID} to specify a specific instance, e.

g.

org.

szimano.

merchantnetwork.

Merchant#szimano1.

Let us start with a simple ACL allowing all participant reading all data on Persons.

Then, we will allow creating and reading ListArtWork transaction by Merchants, but we will use the condition field to make sure that the Merchant lists only own art works.

Then, let us allow Merchant selling art work, but again making sure he sells only art listed by them.

Finally, we will allow the network admin to fully control everything.

Permissions are good but this is our network! ;-)Build and run your networkFinally, once all is done, we need to run a few magic commands in the terminal.

Run FabricGiven that you followed the composer installation guide, just type~/fabric-dev-servers/startFabric.

shBuildFirstly, create a new archive.

The first command will produce a BNA file which is a full definition of our network (models, transactions, ACLs and all).

The second command will import the networkadmin card, so that we can connect to the network as an admin (we can create network cards for specific participants of our blockchain — you can read more about it in the Hyperledger Documentation).

You will have to do this only once.

composer archive create -t dir -n .

composer card import –file networkadmin.

cardDeployOnce the network is created, we need to install it and then run.

Make sure the 0.

0.

2 version used in the commands reflects your network version number.

composer network install –card PeerAdmin@hlfv1 –archiveFile merchant-network@0.

0.

2.

bnacomposer network start –networkName merchant-network –networkVersion 0.

0.

2 –networkAdmin admin –networkAdminEnrollSecret adminpw –card PeerAdmin@hlfv1 –file networkadmin.

cardUpgradingWhen your network is up and running instead of starting it you need to upgrade.

Bump your version (let us say to 0.

0.

3 for the sake of the example) in package.

json and then:composer archive create -t dir -n .

– create a new archivecomposer network install –card PeerAdmin@hlfv1 –archiveFile merchant-network@0.

0.

3.

bna – install itcomposer network upgrade –networkName merchant-network –networkVersion 0.

0.

3 –card PeerAdmin@hlfv1 – upgrade network to the new versionThere are a few rules when upgrading your model (it has to be backward compatible) — you can read more about Model Compatibility in the Hyperledger Compose docs.

Expose REST endpointsTo make REST endpoints available for the outside world, type the following in the project directory:composer-rest-serverUse admin@merchant-network cardChoose never use namespacesChoose default options for the restCheck it outGo to http://localhost:3000/explorer to see everything works as expected.

Now, that all is up and running, you can start calling our network via the REST services.

Word on testingFinally, if you take a look at the test file, you can see how one can set up integration tests that spin up a locally running hyperledger network which then gives you the opportunity to test your models/transactions/ACLs etc.

Just to get a glimpse on how can it look like, below you can see one of the tests, checking that a happy path of artwork listing works.

SummaryTL;DR — we have just created a very naive and simple blockchain for storing asset tokens on Hyperledger Fabric using Hyperledger Composer.

Our network consists of participants, which are both actors of our system and also potential users who can connect to the network and issue transactions; assets, which are items stored on the network; transactions, which represent actions on the network and ACLs that define who can perform what.

Hyperledger Composer provides an integrated development network for very fast time-to-market blockchain solutions.

It leverages few very simple DSLs and a commonly used JavaScript language.

It allows not only designing the network, but also a very robust testing framework.

Once the network is up and running, your application can connect via many APIs and REST endpoints that are auto-generated/documented for you.

Questions or concerns?.Leave a comment below, contact us or reach me on twitter.

LinksHyperledger ComposerHyperledger FabricMerchant-network (full example from this blog) on GitHubAsset tokenizationNeed help with your blockchain-based project?BonusDemo of our winning blockchain solution from HackYeah 2018 (subtitled in English if you do not speak Polish).

.

. More details

Leave a Reply