Developing a blockchain with Hyperledger Composer (Tutorial 2)

You can use composer playground online, or you can use it local. This step I install it local

npm version 6.2.0
node version 8.9.1
composer-cli version v0.19.12
composer-rest-server version 0.19.12
generator-hyperledger-composer version 0.19.12
yo version 2.05

Installing components

Step 1: Install the CLI tools

There are a few useful CLI tools for Composer developers. The most important one is composer-cli, which contains all the essential operations, so we'll install that first. Next, we'll also pick up generator-hyperledger-composer, composer-rest-server and Yeoman plus the generator-hyperledger-composer. Those last 3 are not core parts of the development environment, but they'll be useful if you're following the tutorials or developing applications that interact with your Business Network, so we'll get them installed now.

Note that you should not use su or sudo for the following npm commands.

Essential CLI tools:

npm install -g composer-cli

Utility for running a REST Server on your machine to expose your business networks as RESTful APIs:

npm install -g composer-rest-server

Useful utility for generating application assets:

npm install -g generator-hyperledger-composer

Yeoman is a tool for generating applications, which utilises generator-hyperledger-composer:

npm install -g yo

Step 2: Install Playground

If you’ve already tried Composer online, you’ll have seen the browser app “Playground”. You can run this locally on your development machine too, giving you a UI for viewing and demonstrating your business networks.

Browser app for simple editing and testing Business Networks:

npm install -g composer-playground

Step 3: Set up your IDE

Whilst the browser app can be used to work on your Business Network code, most users will prefer to work in an IDE. Our favourite is VSCode, because a Composer extension is available.

Install VSCode from this URL: https://code.visualstudio.com/download

Open VSCode, go to Extensions, then search for and install the Hyperledger Composer extension from the Marketplace.

Step 4: Install Hyperledger Fabric

This step gives you a local Hyperledger Fabric runtime to deploy your business networks to.

In a directory of your choice (we will assume ~/fabric-dev-servers), get the .tar.gz file that contains the tools to install Hyperledger Fabric:

mkdir ~/fabric-dev-servers && cd ~/fabric-dev-servers  
curl -O https://raw.githubusercontent.com/hyperledger/composer-tools/master/packages/fabric-dev-servers/fabric-dev-servers.tar.gz
tar -xvf fabric-dev-servers.tar.gz

A zip is also available if you prefer: just replace the .tar.gz file with fabric-dev-servers.zip and the tar -xvf command with a unzip command in the preceding snippet.

Use the scripts you just downloaded and extracted to download a local Hyperledger Fabric runtime:

cd ~/fabric-dev-servers
./downloadFabric.sh
Congratulations, you’ve now installed everything required for the typical Developer Environment. Read on to learn some of the most common things you’ll do with this environment to develop and test your Blockchain Business Networks.

Controlling your dev environment

Starting and stopping Hyperledger Fabric

You control your runtime using a set of scripts which you’ll find in ~/fabric-dev-servers if you followed the suggested defaults.

The first time you start up a new runtime, you’ll need to run the start script, then generate a PeerAdmin card:

cd ~/fabric-dev-servers
./startFabric.sh
./createPeerAdminCard.sh

You can start and stop your runtime using ~/fabric-dev-servers/stopFabric.sh, and start it again with ~/fabric-dev-servers/startFabric.sh.

At the end of your development session, you run ~/fabric-dev-servers/stopFabric.sh and then ~/fabric-dev-servers/teardownFabric.sh. Note that if you've run the teardown script, the next time you start the runtime, you'll need to create a new PeerAdmin card just like you did on first time startup.

The local runtime is intended to be frequently started, stopped and torn down, for development use. If you’re looking for a runtime with more persistent state, you’ll want to run one outside of the dev environment, and deploy Business Networks to it. Examples of this include running it via Kubernetes, or on a managed platform such as IBM Cloud.

Start the web app (“Playground”)

To start the web app, run:

composer-playground

It will typically open your browser automatically, at the following address: http://localhost:8080/login

You should see the PeerAdmin@hlfv1 Card you created with the createPeerAdminCard script on your "My Business Networks" screen in the web app: if you don't see this, you may not have correctly started up your runtime!


Go to the site https://composer-playground.mybluemix.net, deploy new business network

Go to 
models/sample.cto and copy this content

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Sample business network definition.
*/
namespace org.acme.sample
asset Account identified by accountId {
o String accountId
--> Customer owner
o Double balance
}
participant Customer identified by customerId {
o String customerId
o String firstName
o String lastName
}
transaction AccountTransfer {
--> Account from
--> Account to
o Double amount
}

Go to lib/sample.js and copy this content

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* global getAssetRegistry getFactory emit */
/**
* Transfer funds from one account to another.
* @param {org.acme.sample.AccountTransfer} accountTransfer The account transaction instance.
* @transaction
*/
async function accountTransfer(accountTransfer) { // eslint-disable-line no-unused-vars
if (accountTransfer.from.balance < accountTransfer.amount) {
throw new Error('Insufficient funds!');
}
accountTransfer.from.balance -= accountTransfer.amount;
accountTransfer.to.balance += accountTransfer.amount;

return getAssetRegistry('org.acme.sample.Account')
.then(function (assetRegistry) {
return assetRegistry.update(accountTransfer.from);
})
.then(function () {
return getAssetRegistry('org.acme.sample.Account');
})
.then(function (assetRegistry) {
return assetRegistry.update(accountTransfer.to);
})
}

Go to the permission file and edit the content

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Sample access control list.
*/
rule EverybodyCanReadEverything {
description: "Allow all participants read access to all resources"
participant: "org.acme.sample.Customer"
operation: READ
resource: "org.acme.sample.*"
action: ALLOW
}
rule EverybodyCanSubmitTransactions {
description: "Allow all participants to submit transactions"
participant: "org.acme.sample.Customer"
operation: CREATE
resource: "org.acme.sample.AccountTransfer"
action: ALLOW
}
rule OwnerHasFullAccessToTheirAssets {
description: "Allow all participants full access to their assets"
participant(p): "org.acme.sample.Customer"
operation: ALL
resource(r): "org.acme.sample.Account"
condition: (r.owner.getIdentifier() === p.getIdentifier())
action: ALLOW
}
rule SystemACL {
description: "System ACL to permit all access"
participant: "org.hyperledger.composer.system.Participant"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}
rule NetworkAdminUser {
description: "Grant business network administrators full access to user resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "**"
action: ALLOW
}
rule NetworkAdminSystem {
description: "Grant business network administrators full access to system resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}

If you have problem, you can import from github


Testing

Go to test tab, Customer, Create new Participant

Then you create one more customer with the name is Simon Stone

Then create two accounts

Then Submit Transaction

Now we will go to Account and check the balance. The money already be transfered! Good job ~^^


Run with REST API

Step 1: Create the network business card

yo hyperledger-composer:businessnetwork

Go to nanabank-network folder

logic.js

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
'use strict';
/**
* Write your transction processor functions here
*/
/**
* Sample transaction
* @param {org.example.nanabank.AccountTransfer} accountTransfer
* @transaction
*/
async function accountTransfer(accountTransfer) {  // eslint-disable-line no-unused-vars
if (accountTransfer.from.balance < accountTransfer.amount) {
throw new Error('Insufficient funds!');
}
accountTransfer.from.balance -= accountTransfer.amount;
accountTransfer.to.balance += accountTransfer.amount;
return getAssetRegistry('org.example.nanabank.Account')
.then(function (assetRegistry) {
return assetRegistry.update(accountTransfer.from);
})
.then(function () {
return getAssetRegistry('org.example.nanabank.Account');
})
.then(function (assetRegistry) {
return assetRegistry.update(accountTransfer.to);
})
}

model

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Write your model definitions here
*/
namespace org.example.nanabank
asset Account identified by accountId {
o String accountId
--> Customer owner
o Double balance
}
participant Customer identified by customerId {
o String customerId
o String firstName
o String lastName
}
transaction AccountTransfer {
--> Account from
--> Account to
o Double amount
}

Permission

/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Sample access control list.
*/
rule EverybodyCanReadEverything {
description: "Allow all participants read access to all resources"
participant: "org.example.nanabank.Customer"
operation: READ
resource: "org.example.nanabank.*"
action: ALLOW
}
rule EverybodyCanSubmitTransactions {
description: "Allow all participants to submit transactions"
participant: "org.example.nanabank.Customer"
operation: CREATE
resource: "org.example.nanabank.AccountTransfer"
action: ALLOW
}
rule OwnerHasFullAccessToTheirAssets {
description: "Allow all participants full access to their assets"
participant(p): "org.example.nanabank.Customer"
operation: ALL
resource(r): "org.example.nanabank.Account"
condition: (r.owner.getIdentifier() === p.getIdentifier())
action: ALLOW
}
rule SystemACL {
description:  "System ACL to permit all access"
participant: "org.hyperledger.composer.system.Participant"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}
rule NetworkAdminUser {
description: "Grant business network administrators full access to user resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "**"
action: ALLOW
}
rule NetworkAdminSystem {
description: "Grant business network administrators full access to system resources"
participant: "org.hyperledger.composer.system.NetworkAdmin"
operation: ALL
resource: "org.hyperledger.composer.system.**"
action: ALLOW
}
If something wrong in the way, you can do it again from the beginning by typing this command:
rm -rf ~/.composer

Run

composer archive create -t dir -n .

Install PeerAdmin

./startFabric.sh
./createPeerAdminCard.sh

Then

composer network install --card PeerAdmin@hlfv1 --archiveFile nanabank-network@0.0.1.bna
composer network start --networkName nanabank-network --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card
composer card import --file networkadmin.card

Test the deploy:

composer network ping --card admin@nanabank-network

Run REST server

composer-rest-server

Time to play around

Create two Customers

Try to Get to test:

Then create Account dan_account and simon_account

Try to get the list:

Then transfer the money!

Then if you get account list again, you can see the balance changed