0% found this document useful (0 votes)
165 views64 pages

CCS Lab Manual: Blockchain & Docker Guide

The document is a lab manual for a course on Cryptocurrency and Blockchain Technologies at Anna University, detailing practical exercises related to Docker, Hyperledger Fabric, and blockchain application development. It includes instructions for software installation, creating and deploying blockchain networks, and interacting with these networks through various applications. The manual serves as a guide for students to perform hands-on experiments and gain practical knowledge in blockchain technologies.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
165 views64 pages

CCS Lab Manual: Blockchain & Docker Guide

The document is a lab manual for a course on Cryptocurrency and Blockchain Technologies at Anna University, detailing practical exercises related to Docker, Hyperledger Fabric, and blockchain application development. It includes instructions for software installation, creating and deploying blockchain networks, and interacting with these networks through various applications. The manual serves as a guide for students to perform hands-on experiments and gain practical knowledge in blockchain technologies.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

lOMoARcPSD|23170297

CCS Lab Manual New

Computer science and engineering (University College of Engineering)

Scan to open on Studocu

Studocu is not sponsored or endorsed by any college or university


Downloaded by sudarsan R (sudarsansrs@[Link])
lOMoARcPSD|23170297

ANNA UNIVERSITY

UNIVERSITY COLLEGE OF ENGINEERING-DINDIGUL

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

CCS339 CRYPTOCURRENCY AND BLOCKCHAIN TECHNOLOGIES

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

ANNA UNIVERSITY
UNIVERSITY COLLEGE OF ENGINEERING – DINDIGUL
DINDIGUL – 62422

BONAFIDE CERTIFICATE

This is to certify that is a bonafide record of work done by


Mr./Ms._______________________________________
in____________________________________________ laboratory
during the academic year 2023-20

University Registration No:

Staff In charge Head of the Department

Submitted for the university Practical Examination held on_________________

INTERNAL EXAMINER EXTERNAL EXAMINER

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

INDEX
EX. DATE TITLE PAGE MARKS REMARKS
NO NO
1 Install and understand docker
container, [Link], java and
hyperledger fabric, ethereum and
perform necessary software
installation on local machine/create
instance on cloud to run
2 Create and deploy a blockchain
network using hyperledger fabric sdk
for java set up and initialize the
channel, install and instantiate chain
code, and perform invoke and query
on your blockchain network
3 Interact with a blockchain network.
Execute transactions and requests
against a blockchain network by
creating an app to test the network
and its rules

4 Deploy an asset-transfer app using


blockchain. Learn app development
within a hyperledger fabric network

5 Use blockchain to track fitness club


rewards. Build a web app that uses
hyperledger fabric to track and trace
member rewards.

6 Car auction network: a hello world


example with hyperledger fabric
node sdk and ibm blockcha in starter
plan. Use hyperledger fabric to
invoke chain code while storing
results and data in the starter plan

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Install and understand Docker container, [Link], Java and


Ex : No : 1 Hyperledger Fabric, Ethereum and perform necessary
software installation on local machine/create instance on cloud
DATE :
to run

AIM :
Install and understand Docker container, [Link], Java and Hyperledger Fabric, Ethereum and
perform necessary software installation on local machine/create instance on cloud to run.

PROCEDURE :

INSTALLATION OF SOFTWARES
Install the Linux Windows Subsystem in Windows 11 :

 Step 1 : Open the Start menu and type "Windows features" into the search bar and click
"Turn Windows Features On or Off".
 Step 2 : Tick the "Windows Subsystem for Linux" checkbox and press the “OK” button.
 Step 3 : When the operation is complete, you will be asked to restart your computer.
 Step 4 : The Linux distribution can be launched from the Start menu.
 Step 5 : In Microsoft store install the Ubuntu 22.04.

Install the docker on Ubuntu 22.04 in WSL :

 Step 1 : Installing Docker


a. sudo apt update
b. sudo apt install apt-transport-https ca-certificates curl software-properties-common
c. curl -fsSL [Link] | sudo apt-key add –
d. sudo add-apt-repository "deb [arch=amd64] [Link]
focal stable"
e. sudo apt-cache policy docker-ce
f. sudo apt install docker-ce

g. sudo systemctl status docker

 Step 2 : Working with Docker Images

1. docker run hello-world

2. docker search ubuntu

3. docker pull ubuntu

4. docker images

 Step 3 : Running a Docker Container

1. docker run -it ubuntu

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

 Step 4 : Managing Docker Containers

1. docker ps

2. docker ps -a

3. docker ps -l

4. docker start ( ID number )

5. docker stop ( NAMES )

6. docker rm youthful_curie

 Step 5 : Committing Changes in a Container to a


Docker Images

1. docker commit -m "What you did to the image" -a "Author Name" container_id
repository/new_image_name
2. docker commit -m "added [Link]" -a "sammy" d9b100f2f636 sammy/ubuntu-nodejs
3. docker images

 Step 6 : pushing Docker Images to a Docker Repository

a. docker login -u docker-registry-username


b. docker tag sammy/ubuntu-nodejs docker-registry-username/ubuntu-nodejs
c. docker push docker-registry-username/docker-image-name
d. docker push sammy/ubuntu-nodejs
Install Prerequisites for Hyperledger fabric :

Installing cURL : Sudo apt-get install curl


Sudo apt-cache search libcurl | grep python
Sudo apt-get install python3-pycurl
Sudo apt-cache search libcurl
REFERENCE : [Link]
linux/

Installing Golang : sudo apt-get install golang-go


export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin
REFERENCE : [Link]

Installing [Link] and NVM :


 sudo apt update
5

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

 sudo apt install nodejs


 node -v
 sudo apt install npm

Installing jq : sudo apt-get install jq


Installing JAVA : sudo apt-get install default-jre
sudo apt-get install default-jdk

INSTALLATION OF SAMPLES, BINARIES AND DOCKER IMAGES :


Determine a location on your machine where you want to place the fabric-samples repository and
enter that directory in a terminal window. The command that follows will perform the following
steps:

1. If needed, clone the hyperledger/fabric-samples repository


2. Checkout the appropriate version tag
3. Install the Hyperledger Fabric platform-specific binaries and config files for the version
specified into the /bin and /config directories of fabric-samples
4. Download the Hyperledger Fabric docker images for the version specified

STEPS INVOLVED :

mkdir -p $HOME/go/src/[Link]/<your_github_userid> cd
$HOME/go/src/[Link]/<your_github_userid>
curl -sSL [Link] | bash -s -- -h
curl -sSL [Link] | bash -s -- 2.3.1 1.4.9
export GOPATH:$Home/<user-defined-workspace>/go
export PATH=<path to download location>/bin:$PATH
curl -sSL [Link] bash -s

RESULT :
Thus the Installation of necessary software on local machine/create instance on cloud to run
Was created successfully.

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Create and deploy a blockchain network using Hyperledger


Ex : No : 2 Fabric SDK for Java Set up and initialize the channel, install
and instantiate chain code, and perform invoke and query on
DATE :
your blockchain network

AIM :
To Create and deploy a blockchain network using Hyperledger Fabric SDK for Java Set up and
initialize the channel, install and instantiate chain code, and perform invoke and query on your blockchain
network.

PROCEDURE :

Using the Fabric test network :

 It includes two peer organizations and an ordering organization.


 For simplicity, a single node Raft ordering service is configured.
 To reduce complexity, a TLS Certificate Authority (CA) is not deployed. All certificates
are issued by the root CAs.
 The sample network deploys a Fabric network with Docker Compose. Because the nodes
are isolated within a Docker Compose network, the test network is not configured to
connect to other running Fabric nodes.

Bring up the test network :

You can find the scripts to bring up the network in the test-network directory of
the fabric-samples repository. Navigate to the test network directory by using the following
command:

 cd fabric-samples/test-network

In this directory, you can find an annotated script, [Link] , that stands up a Fabric network
using the Docker images on your local machine. You can run ./[Link] -h to print the script
help text:

From inside the test-network directory, run the following command to remove any containers or
artifacts from any previous runs:

 ./[Link] down

You can then bring up the network by issuing the following command. You will experience
problems if you try to run the script from another directory:

 ./[Link] up

This command creates a Fabric network that consists of two peer nodes, one ordering node. No
channel is created when you run ./[Link] up , though we will get there in a future step. If the
command completes successfully, you will see the logs of the nodes being created:

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

The components of the test network :


After your test network is deployed, you can take some time to examine its components.
Run the following command to list all of Docker containers that are running on your machine. You
should see the three nodes that were created by the [Link] script

 docker ps -a
Every peer in the network needs to belong to an organization. In the test network, each
organization operates one peer each, [Link] and [Link] .

Creating a channel :
Now that we have peer and orderer nodes running on our machine, we can use the script to
create a Fabric channel for transactions between Org1 and Org2

You can use the [Link] script to create a channel between Org1 and Org2 and join their peers
to the channel. Run the following command to create a channel with the default name
of mychannel :

 ./[Link] createChannel
If the command was successful, you can see the following message printed in your logs:

========= Channel successfully joined ===========

You can also use the channel flag to create a channel with custom name. As an example, the
following command would create a channel named channel1 :

 ./[Link] createChannel -c channel1

The channel flag also allows you to create multiple channels by specifying different channel
names. After you create mychannel or channel1 , you can use the command below to create a
second channel named channel2 :

 ./[Link] createChannel -c channel2

If you want to bring up the network and create a channel in a single step, you can use
the up and createChannel modes together:

 ./[Link] up createChannel

Starting a chaincode on the channel :

After you have used the [Link] to create a channel, you can start a chaincode on the
channel using the following command:
 ./[Link] deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-go -ccl go

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Interacting with the network :

Make sure that you are operating from the test-network directory. If you followed the
instructions to install the Samples, Binaries and Docker Images, You can find the peer binaries in
the bin folder of the fabric-samples repository. Use the following command to add those binaries
to your CLI Path:
 export PATH=${PWD}/../bin:$PATH
You also need to set the FABRIC_CFG_PATH to point to the [Link] file in the fabric-
samples repository:

 export FABRIC_CFG_PATH=$PWD/../config/
You can now set the environment variables that allow you to operate the peer CLI as Org1:

 export CORE_PEER_TLS_ENABLED=true
 export CORE_PEER_LOCALMSPID="Org1MSP"
 exportCORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizati
ons/[Link]/peers/[Link]/tls/[Link]
 export
CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.e
[Link]/users/Admin@[Link]/msp
 export CORE_PEER_ADDRESS=localhost:7051

Run the following command to initialize the ledger with assets:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride [Link] --tls --


cafile
"${PWD}/organizations/ordererOrganizations/[Link]/orderers/[Link]/msp/tlscacer
ts/[Link]" -C mychannel -n basic --peerAddresses localhost:7051 --
tlsRootCertFiles
"${PWD}/organizations/peerOrganizations/[Link]/peers/[Link]/tls/[Link]"
--peerAddresses localhost:9051 --tlsRootCertFiles
"${PWD}/organizations/peerOrganizations/[Link]/peers/[Link]/tls/[Link]"
-c '{"function":"InitLedger","Args":[]}'
Note : Above command is a single line command

If successful, you should see similar output to below:

-> INFO 001 Chaincode invoke successful. result:


status:200

You can now query the ledger from your CLI. Run the following command to get the list of assets
that were added to your channel ledger:

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

peer chaincode query -C mychannel -n basic -c '{"Args":["GetAllAssets"]}'

If successful, you should see the following output:

{"ID": "asset1", "color": "blue", "size": 5, "owner": "Tomoko", "appraisedValue": 300},


{"ID": "asset2", "color": "red", "size": 5, "owner": "Brad", "appraisedValue": 400},
{"ID": "asset3", "color": "green", "size": 10, "owner": "Jin Soo", "appraisedValue": 500},
{"ID": "asset4", "color": "yellow", "size": 10, "owner": "Max", "appraisedValue": 600},
{"ID": "asset5", "color": "black", "size": 15, "owner": "Adriana", "appraisedValue": 700},
{"ID": "asset6", "color": "white", "size": 15, "owner": "Michel", "appraisedValue": 800}

Chaincodes are invoked when a network member wants to transfer or change an asset on the
ledger. Use the following command to change the owner of an asset on the ledger by invoking the
asset-transfer (basic) chaincode:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride [Link] --


tls --cafile
"${PWD}/organizations/ordererOrganizations/[Link]/orderers/[Link]/msp/tls
cacerts/[Link]" -C mychannel -n basic --peerAddresses localhost:7051 --
tlsRootCertFiles
"${PWD}/organizations/peerOrganizations/[Link]/peers/[Link]/tls/c
[Link]" --peerAddresses localhost:9051 --tlsRootCertFiles
"${PWD}/organizations/peerOrganizations/[Link]/peers/[Link]/tls/c
[Link]" -c '{"function":"TransferAsset","Args":["asset6","Christopher"]}'

Note : Above command is a single line command

If the command is successful, you should see the following response:

2019-12-04 [Link].048 EST [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 001


Chaincode invoke successful. result: status:200

we can take this opportunity to query the chaincode running on the Org2 peer. Set the following
environment variables to operate as Org2:

 export CORE_PEER_TLS_ENABLED=true
 export CORE_PEER_LOCALMSPID="Org2MSP"
 export
CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/[Link]
[Link]/peers/[Link]/tls/[Link]
 export
CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/[Link]
[Link]/users/Admin@[Link]/msp
 export CORE_PEER_ADDRESS=localhost:9051

You can now query the asset-transfer (basic) chaincode running on [Link] :
10

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

 peer chaincode query -C mychannel -n basic -c '{"Args":["ReadAsset","asset6"]}'

The result will show that "asset6" was transferred to Christopher:


 {"ID":"asset6","color":"white","size":15,"owner":"Christopher","appraisedValue":800}

Bring down the network :


When you are finished using the test network, you can bring down the network with the
following command:
 ./[Link] down

Bring up the network with Certificate Authorities :


If you would like to bring up a network using Fabric CAs, first run the following command
to bring down any running networks:
 ./[Link] down
 ./[Link] up -ca

REFERENCES :

[Link]

RESULT :
Creating and deploying a blockchain network using Hyperledger Fabric SDK for Java Set up
and initialize the channel, install and instantiate chain code, and perform invoke and query on your
blockchain network was successfully completed.

11

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Interact with a blockchain network. Execute transactions and


Ex : No : 3 requests against a blockchain network by creating an app to
test the network and its rules
DATE :

AIM :
Interact with a blockchain network. Execute transactions and requests against a blockchain network
by creating an app to test the network and its rules.

PROCEDURE :

Installing Dependencies
Part 1: Project Setup
Part 2: Sell Products
Part 3: Buy Products
Part 4: Marketplace Website Setup (Front End)
Part 5: Sell Products (Front End)
Part 6: Buy Products (Front End)
Part 7: Deploy Project

What Are We Going To Build?

Today, I’m going to teach you blockchain programming from square one by building a complete
application that’s powered by the blockchain.

We'll create:

1. Ethereum smart contracts with the Solidity programming language.


2. We’ll write tests for the smart contracts in JavaScript.
3. We’ll deploy to the smart contracts to a blockchain.

4. We’ll create a client side website with [Link] and [Link] so that users can talk to the smart
contracts

12

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Installing Dependencies:
The dependency is a personal blockchain, which is a local development blockchain that can be
used to mimic the behavior of a public blockchain. I recommend using Ganache as your personal
blockchain for Ethereum development.

[Link] :
The first dependency you'll need is Node Package Manager, or NPM, which comes with
[Link].
 node -v
 $ npm install -g truffle@5.0.5
Truffle Framework :

Now let's install the Truffle Framework, which provides a suite of tools for developing
Ethereum smart contacts with the Solidity programming language.
Here is an overview of all the functionality we'll get with the Truffle Framework:

 Smart Contract Management, Network Management.


 Automated Testing, Development Console.
 Deployment & Migrations, Script Runner, Client Side Development.

13

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Metamask Ethereum Wallet :

Now it's time to turn your web browser into a blockchain browser. Most major web browsers
do not currently connect to blockchain networks, so we'll have to install a browser extension that
allows them to do this. I'll the Metamask extension for Google Chrome. To install Metamask, visit
this link or search for the Metamask Chrome plugin in the Google Chrome web store.

Part 1: Project Setup :


Let's get started building our app quickly! Instead of setting up the project manually, we're
going to use my starter kit. Create your project by cloning the starter kit like this:

 git clone [Link] marketplace

Now, enter into the directory you just cloned like this:

 $ cd marketplace

You've just set up your project instantly. Let's take a look at what we just created:

This is a custom truffle project that I have created to help you start building full stack blockchain
applications fast! You can create smart contracts, test them, and build front-end web apps
with [Link], [Link] and Bootstrap all inside of this project.
14

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

It has all of the dependencies you need already inside the [Link] file:
{
"name": "eth-marketplace",
"version": "0.1.0",
"description": "An Ethereum Marketplace",
"author": "gregory@[Link]",
"dependencies": {
"babel-polyfill": "6.26.0",
"babel-preset-env": "1.7.0",
"babel-preset-es2015": "6.24.1",
"babel-preset-stage-2": "6.24.1",
"babel-preset-stage-3": "6.24.1",
"babel-register": "6.26.0",
"bootstrap": "4.3.1",
"chai": "4.2.0",
"chai-as-promised": "7.1.1",
"chai-bignumber": "3.0.0",
"react": "16.8.4",
"react-bootstrap": "1.0.0-beta.5",
"react-dom": "16.8.4",
"react-scripts": "2.1.3",
"truffle": "5.0.5",
"web3": "1.0.0-beta.55"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"

You can go ahead and install your dependencies like this:

$ npm install

Next let's look at the [Link] file:

require('babel-register');
require('babel-polyfill');

15

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

[Link] = {
networks: {
development: {
host: "[Link]",
port: 7545,
network_id: "*" // Match any network id
},
},
contracts_directory: './src/contracts/',
contracts_build_directory: './src/abis/',
compilers: {
solc: {
optimizer: {
enabled: true,
runs: 200
}
}
}

The primary responsibility of this file is to connect our project to the blockchain network. I've already
set this up to connect to our Ganache personal blockchain, i.e., [Link]:7545.

You can see that configuration under the contracts_directory and contracts_build_directory settings.

let's begin writing our smart contract by creating a new file in the contracts directory:

 $ touch src/contracts/[Link]

Inside this file, let's begin writing our smart contract Solidity programming language:

First, we start by declaring the version of the Solidity programming language that we want to
use. Next, we declare our smart contract Marketplace. We'll add all of the smart contract code inside
of the curly braces. Let's do this.
pragma solidity ^0.5.0;

contract Marketplace {
string public name;

This code creates a "state variable", whose value will be stored on the blockchain. We'll call the
variable name because we'll use it to store the name for the smart contract (just for testing purposes).

Next, let's set the value of this variable like this:


pragma solidity ^0.5.0;

contract Marketplace {
string public name;

16

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

constructor() public {
name = "Dapp University Marketplace";
}

We assign the value of name inside the constructor function. This is a special function that gets called
whenever the smart contract is created for the first time, i.e., deployed to the blockchain.

Now let's compile the smart contract to make sure that everything worked:

 $ truffle compile

Next, let's deploy the mart contract to our Ganache personal blockhain. To do this, create a new
migration file like this:

 $ touch migrations/2_deploy_contracts.js

This file tells Truffle to to deploy our smart contract to the blockchain. It's kind of like a migration file
for a traditional database if you're familiar with that.

Enter this code into your newly created migration:


const Marketplace = [Link]("Marketplace");

[Link] = function(deployer) {
[Link](Marketplace);

};

Now migrate run the migrations like this:

Now we can check our smart contract from the Truffle console. You can launch the Truffle console
from the command line like this:

 $ truffle console

Now we can get a deployed copy of the smart contract inside the console with JavaScript like this:

 marketplace = await [Link]()

Your console might return undefined, but that's ok! You can obtain the value of the smart contract by
typing the variable name again like this:

 marketplace

You obtain the address of the smart contract on the blockchain like this:

 [Link]
 name = await [Link]() (let's read the name)
 name

successfully set up your project and deployed a basic smart contract to the blockchain!
17

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Now let's write a test for the smart contract. Testing smart contracts is very important because you
need to make sure that they work perfectly before going live on the blockchain. Remember, once you
deploy them, they cannot change! You can only re-deploy a new copy.

Create a new file for the smart contract tests like this:

 $ mkdir test
 $ touch test/[Link]

Inside this file, use the following code:


const Marketplace = [Link]('./[Link]')

contract('Marketplace', (accounts) => {


let marketplace

before(async () => {
marketplace = await [Link]()
})

describe('deployment', async () => {


it('deploys successfully', async () => {
const address = await [Link]
[Link](address, 0x0)
[Link](address, '')
[Link](address, null)
[Link](address, undefined)
})

it('has a name', async () => {


const name = await [Link]()
[Link](name, 'Dapp University Marketplace')
})

})

})

Let me explain this test. We write all our tests in Javascript inside this file with the Mocha testing
framework and the Chai assertion library. These come bundled with the Truffle framework. We'll
write all these tests in JavaScript to simulate client-side interaction with our smart contract, much like
we did in the console.

Now, let's run the tests from the command line like this:

 $ truffle test
Part 2: Sell Products :
We'll create the first feature, which will allow a user to list an item for sale in the marketplace.
In order to do that we'll need to model the product with a struct like this
struct Product {
uint id;
string name;

18

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

uint price;
address owner;
bool purchased;
}
Solidity allows you to create your own data structures, with any arbitrary attributes. That's exactly
what we've done by creating a Product struct. It stores all the attributes of a product that we'll need,
like id, name, price, owner, and purchased.
Next, we need a place to store this products on the blockchain. We'll create a mapping on Solidity like
this:
mapping(uint => Product) public products;

Mappings work like associative arrays, or hash tables, with key value-pairs. Mappings have unique
keys that return unique values

Next, we want to keep track of how many products exist in the smart contract with
a productCount counter cache like this:

uint public productCount = 0;

At this point, your smart contract should look like this:


pragma solidity ^0.5.0;

contract Marketplace {
string public name;
uint public productCount = 0;
mapping(uint => Product) public products;

struct Product {
uint id;
string name;
uint price;
address owner;
bool purchased;
}

constructor() public {
name = "Dapp University Marketplace";
}

}
Next, let's create a function to create new products. This function will do a few things:

 Create a new product with a struct


 Add the struct to the mapping, and store it on the blockchain
 Trigger an event that lets someone know a product was creatd

We can create that function like this:

function createProduct(string memory _name, uint _price) public {

19

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

// Require a valid name


require(bytes(_name).length > 0);
// Require a valid price
require(_price > 0);
// Increment product count
productCount ++;
// Create the product
products[productCount] = Product(productCount, _name, _price, [Link], false);
// Trigger an event
emit ProductCreated(productCount, _name, _price, [Link], false);
}

Now let's add the event definition so that it can be triggered:


event ProductCreated(
uint id,
string name,
uint price,
address owner,
bool purchased

);

External subscribers can listen for this event to verify that a product was created on the blockchain.
We'll check for this event inside the smart contract tests momentarily.

Now your complete smart contract code for this section should look like this:
pragma solidity ^0.5.0;

contract Marketplace {
string public name;
uint public productCount = 0;
mapping(uint => Product) public products;

struct Product {
uint id;
string name;
uint price;
address owner;
bool purchased;
}

event ProductCreated(

20

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

uint id,
string name,
uint price,
address owner,
bool purchased
);

constructor() public {
name = "Dapp University Marketplace";
}

function createProduct(string memory _name, uint _price) public {


// Require a valid name
require(bytes(_name).length > 0);
// Require a valid price
require(_price > 0);
// Increment product count
productCount ++;
// Create the product
products[productCount] = Product(productCount, _name, _price, [Link], false);
// Trigger an event
emit ProductCreated(productCount, _name, _price, [Link], false);
}
}
Now let's add some tests to ensure that this function works properly. Use this code inside your test
file:
const Marketplace = [Link]('./[Link]')

require('chai')
.use(require('chai-as-promised'))
.should()

contract('Marketplace', ([deployer, seller, buyer]) => {


let marketplace
21

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

before(async () => {
marketplace = await [Link]()
})

describe('deployment', async () => {


it('deploys successfully', async () => {
const address = await [Link]
[Link](address, 0x0)
[Link](address, '')
[Link](address, null)
[Link](address, undefined)
})

it('has a name', async () => {


const name = await [Link]()
[Link](name, 'Dapp University Marketplace')
})
})

describe('products', async () => {


let result, productCount

before(async () => {
result = await [Link]('iPhone X', [Link]('1', 'Ether'), { from: seller })
productCount = await [Link]()
})

it('creates products', async () => {


// SUCCESS
[Link](productCount, 1)
const event = [Link][0].args
[Link]([Link](), [Link](), 'id is correct')

22

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

[Link]([Link], 'iPhone X', 'name is correct')


[Link]([Link], '1000000000000000000', 'price is correct')
[Link]([Link], seller, 'owner is correct')
[Link]([Link], false, 'purchased is correct')

// FAILURE: Product must have a name


await await [Link]('', [Link]('1', 'Ether'), { from: seller
}).[Link];
// FAILURE: Product must have a price
await await [Link]('iPhone X', 0, { from: seller }).[Link];
})
})
})
Let's examine each new part. First, we add some extra tools to our test suite like this. We already
installed these in our [Link]:
require('chai')
.use(require('chai-as-promised'))
.should()
Next, add 3 new accounts to the test scenario, deployer, seller, and buyer:
contract('Marketplace', ([deployer, seller, buyer]) => {

Then, we create a new test example for creating products: describe('products', async () => {
let result, productCount

before(async () => {
result = await [Link]('iPhone X', [Link]('1', 'Ether'), { from: seller })
productCount = await [Link]()
})

//...
This sets up the test example with a before hook, which creates a product before each test runs.
Finally, we create a full test for product creation like this:
it('creates products', async () => {
// SUCCESS
[Link](productCount, 1)
const event = [Link][0].args

23

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

[Link]([Link](), [Link](), 'id is correct')


[Link]([Link], 'iPhone X', 'name is correct')
[Link]([Link], '1000000000000000000', 'price is correct')
[Link]([Link], seller, 'owner is correct')
[Link]([Link], false, 'purchased is correct')
// FAILURE: Product must have a name
await await [Link]('', [Link]('1', 'Ether'), { from: seller
}).[Link];
// FAILURE: Product must have a price
await await [Link]('iPhone X', 0, { from: seller }).[Link];
})

Part 3: Buy Products :


Now let's create a function to purchase products. Whenver someone calls this function, they
will submit the id of the product that they want to purchase (this will be handled by our client side
application).
Additionally, they will send Ethereum cryptocurrency from their wallet to purchase the product when
they call this function. We'll set the function up to do this like so:
function purchaseProduct(uint _id) public payable {
// ...
}
Notice, we have made this function payable, which means that it will accept Etherum cryptocurrency.
We'll see this in action momentarily. Because we want to pay the owner, we must update the existing
struct and event to use the address payable type like this:
struct Product {
uint id;
string name;
uint price;
address payable owner;
bool purchased;
}
event ProductCreated(
uint id,
string name,
uint price,
address payable owner,
bool purchased
);
Now let's fill out the code inside the function:

function purchaseProduct(uint _id) public payable {


// Fetch the product

24

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Product memory _product = products[_id];


// Fetch the owner
address payable _seller = _product.owner;
// Make sure the product has a valid id
require(_product.id > 0 && _product.id <= productCount);
// Require that there is enough Ether in the transaction
require([Link] >= _product.price);
// Require that the product has not been purchased already
require(!_product.purchased);
// Require that the buyer is not the seller
require(_seller != [Link]);
// Transfer ownership to the buyer
_product.owner = [Link];
// Mark as purchased
_product.purchased = true;
// Update the product
products[_id] = _product;
// Pay the seller by sending them Ether
address(_seller).transfer([Link]);
// Trigger an event
emit ProductPurchased(productCount, _product.name, _product.price, [Link], true);
}
Now let's create a new event for product sales. It will work almost exactly like the event we created in
the last section, just a different name:
event ProductPurchased(
uint id,
string name,
uint price,
address payable owner,
bool purchased
);
Now let's add a test for the purchaseProduct function like this:
it('sells products', async () => {
// Track the seller balance before purchase
let oldSellerBalance
oldSellerBalance = await [Link](seller)

25

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

oldSellerBalance = new [Link](oldSellerBalance)

// SUCCESS: Buyer makes purchase


result = await [Link](productCount, { from: buyer, value: [Link]('1',
'Ether')})

// Check logs
const event = [Link][0].args
[Link]([Link](), [Link](), 'id is correct')
[Link]([Link], 'iPhone X', 'name is correct')
[Link]([Link], '1000000000000000000', 'price is correct')
[Link]([Link], buyer, 'owner is correct')
[Link]([Link], true, 'purchased is correct')

// Check that seller received funds


let newSellerBalance
newSellerBalance = await [Link](seller)
newSellerBalance = new [Link](newSellerBalance)

let price
price = [Link]('1', 'Ether')
price = new [Link](price)

const exepectedBalance = [Link](price)

[Link]([Link](), [Link]())

// FAILURE: Tries to buy a product that does not exist, i.e., product must have valid id
await [Link](99, { from: buyer, value: [Link]('1',
'Ether')}).[Link]; // FAILURE: Buyer tries to buy without enough ether
// FAILURE: Buyer tries to buy without enough ether
await [Link](productCount, { from: buyer, value: [Link]('0.5',
'Ether') }).[Link];
// FAILURE: Deployer tries to buy the product, i.e., product can't be purchased twice

26

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

await [Link](productCount, { from: deployer, value: [Link]('1',


'Ether') }).[Link];
// FAILURE: Buyer tries to buy again, i.e., buyer can't be the seller
await [Link](productCount, { from: buyer, value: [Link]('1', 'Ether')
}).[Link];
})
This test works much like the sellProduct() function test. It does a few key things:
Now, let's run the tests from the command line like this:
 $ truffle test
et's deploy the smart contract to the network so that we can start building the client side application to
interact with it in the next section
 $ truffle migrate –reset
Part 4: Marketplace Website Setup (Front End) :
Now let's start building the client side application for the Marketplace. Here's what we'll do in this
section:

 Start the app, and run the starter kit in our browser
 Connect our web browser to the blockchain
 Connect our web app to the blockchain, and start talking to the Marketplace smart contract

 Before we begin, make sure that your development server is running:


 $ npm run start
This should start your web server and automatically open the website in your browser like this:
This starter kit comes with everything we need to build our application:

 [Link] for building out the interface


 Bootstrap for creating UI elements without writing CSS
 [Link] for connecting our app to the blockchain

To do this we'll need to do two things:

 Connect Metamask to our Ganache personal blockchain instance


 Import some accounts from Ganache into Metamask so that we can act on their behalf as users
of our marketplace application

27

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Now let's connect our client side application to the blockchain with the help of a
href="[Link] target="_blank">[Link]. We'll start by
importing web3 into our main [Link] component like this:
import Web3 from 'web3'
Now let's create a new function that will get called whenever our React component is loaded.
async componentWillMount() {
await this.loadWeb3()
}
Now, let's create the loadWeb3() function that will create the connection like this:
async loadWeb3() {
if ([Link]) {
window.web3 = new Web3([Link])
await [Link]()
}
else if (window.web3) {
window.web3 = new Web3([Link])
}
else {
[Link]('Non-Ethereum browser detected. You should consider trying MetaMask!')
}
}
This function detects the presence of an Ethereum provider in the web browser, which allows us to
connect our app to the blockchain.
Now let's create a function that loads data from the blockchain. We'll call it first like this:
async componentWillMount() {
await this.loadWeb3()
await [Link]()
}
And we'll define it like this:

async loadBlockchainData() {
const web3 = window.web3
}
Inside of here, we've connected stored the web3 connection to a variable.
async loadBlockchainData() {
const web3 = window.web3
const accounts = await [Link]()
[Link](accounts)
}
Now go to your browser and see the account logged to the console!
28

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Next, we're going to store this account to the React state object so that we can use it later:

async loadBlockchainData() {
const web3 = window.web3
const accounts = await [Link]()
[Link](accounts)
[Link]({ account: accounts[0] })
}
While we're here, let's set some default values for the state object. React lets us do that like this:
constructor(props) {
super(props)
[Link] = {
account: '',
productCount: 0,
products: [],
loading: true
}
}
First, create a new component called [Link] inside the same directory as [Link]. Then use this code
inside that file:

import React, { Component } from 'react';

class Navbar extends Component {

render() {
return (
<nav className="navbar navbar-dark fixed-top bg-dark flex-md-nowrap p-0 shadow">
<a
className="navbar-brand col-sm-3 col-md-2 mr-0"
href="[Link]
target="_blank"
rel="noopener noreferrer"
>
Dapp University's Blockchain Marketplace
</a>
<ul className="navbar-nav px-3">
<li className="nav-item text-nowrap d-none d-sm-none d-sm-block">
<small className="text-white"><span id="account">{[Link]}</span></small>
</li>
</ul>
</nav>
);
}
}
export default Navbar;

Now import the Navbar component at the top of [Link]:

import Navbar from './Navbar'

Now let's render it out on the page. First, delete all the old Navbar code, and replace it with this:
29

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

<Navbar account={[Link]} />

Next, let's add the connection to the marketplace smart contract. First, we'll import the smart contract
ABI at the top of [Link] like this:

import Marketplace from '../abis/[Link]'

Now, let's update the loadBlockchainData() function to connect the smart contract:

async loadBlockchainData() {
const web3 = window.web3
// Load account
const accounts = await [Link]()
[Link]({ account: accounts[0] })
const networkId = await [Link]()
const networkData = [Link][networkId]
if(networkData) {
const marketplace = [Link]([Link], [Link])
[Link](marketplace)
} else {
[Link]('Marketplace contract not deployed to detected network.')
}
}

Now your final component should look like this:

import React, { Component } from 'react';


import Web3 from 'web3'
import logo from '../[Link]';
import './[Link]';
import Marketplace from '../abis/[Link]'
import Navbar from './Navbar'

class App extends Component {

async componentWillMount() {
await this.loadWeb3()
await [Link]()
}

async loadWeb3() {
if ([Link]) {
window.web3 = new Web3([Link])
await [Link]()
}
else if (window.web3) {
window.web3 = new Web3([Link])
}
else {
[Link]('Non-Ethereum browser detected. You should consider trying MetaMask!')
}
}

async loadBlockchainData() {
const web3 = window.web3
30

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

// Load account
const accounts = await [Link]()
[Link]({ account: accounts[0] })
const networkId = await [Link]()
const networkData = [Link][networkId]
if(networkData) {
const marketplace = [Link]([Link], [Link])
[Link](marketplace)
} else {
[Link]('Marketplace contract not deployed to detected network.')
}
}

constructor(props) {
super(props)
[Link] = {
account: '',
productCount: 0,
products: [],
loading: true
}
}

render() {
return (
<div>
<Navbar account={[Link]} />
<div className="container-fluid mt-5">
<div className="row">
<main role="main" className="col-lg-12 d-flex text-center">
<div className="content mr-auto ml-auto">
<a
href="[Link]
target="_blank"
rel="noopener noreferrer"
>
<img src={logo} className="App-logo" alt="logo" />
</a>
<h1>Dapp University Starter Kit</h1>
<p>
Edit <code>src/components/[Link]</code> and save to reload.
</p>
<a
className="App-link"
href="[Link]
target="_blank"
rel="noopener noreferrer"
>
LEARN BLOCKCHAIN <u><b>NOW! </b></u>
</a>
</div>
</main>
</div>
</div>
</div>
31

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

);
}
}

export default App;

Part 5: Sell Products (Front End) ;


Now let's create a way to sell products from our marketplace website. We'll do these tasks:
First, let's add some more data to our loadBlockchainData() function. We'll get the productCount

async loadBlockchainData() {
const web3 = window.web3
// Load account
const accounts = await [Link]()
[Link]({ account: accounts[0] })
const networkId = await [Link]()
const networkData = [Link][networkId]
if(networkData) {
const marketplace = [Link]([Link], [Link])
[Link]({ marketplace })
const productCount = await [Link]().call()
[Link]([Link]())
[Link]({ loading: false})
} else {
[Link]('Marketplace contract not deployed to detected network.')
}
}
Next, we'll create a function that adds the product to the blockchain by calling
the createProduct() function with [Link] like this:

createProduct(name, price) {
[Link]({ loading: true })
[Link](name, price).send({ from: [Link] })
.once('receipt', (receipt) => {
[Link]({ loading: false })
})

In order to call this function with the form, we must bind it to the component inside the constructor
like this:

constructor(props) {
32

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

// ...
[Link] = [Link](this)
}

Let's create a new file in the current directory called

[Link]
with the following code:
import React, { Component } from 'react';

class Main extends Component {

render() {
return (
<div id="content">
<h1>Add Product</h1>
<form onSubmit={(event) => {
[Link]()
const name = [Link]
const price = [Link]([Link](), 'Ether')
[Link](name, price)
}}>
<div className="form-group mr-sm-2">
<input
id="productName"
type="text"
ref={(input) => { [Link] = input }}
className="form-control"
placeholder="Product Name"
required />
</div>
<div className="form-group mr-sm-2">
<input
id="productPrice"
type="text"
ref={(input) => { [Link] = input }}
className="form-control"
placeholder="Product Price"
required />
</div>
<button type="submit" className="btn btn-primary">Add Product</button>
</form>
<p> </p>
<h2>Buy Product</h2>
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Owner</th>
<th scope="col"></th>
</tr>
</thead>

33

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

<tbody id="productList">
<tr>
<th scope="row">1</th>
<td>iPhone x</td>
<td>1 Eth</td>
<td>0x39C7BC5496f4eaaa1fF75d88E079C22f0519E7b9</td>
<td><button className="buyButton">Buy</button></td>
</tr>
<tr>
<th scope="row">2</th>
<td>Macbook Pro</td>
<td>3 eth</td>
<td>0x39C7BC5496f4eaaa1fF75d88E079C22f0519E7b9</td>
<td><button className="buyButton">Buy</button></td>
</tr>
<tr>
<th scope="row">3</th>
<td>Airpods</td>
<td>0.5 eth</td>
<td>0x39C7BC5496f4eaaa1fF75d88E079C22f0519E7b9</td>
<td><button className="buyButton">Buy</button></td>
</tr>
</tbody>
</table>
</div>
);
}
}

export default Main;

Go back to [Link] and import the newly created component at the top of the file like this:

import Main from './Main'


Now replace everything inside the <main> HTML tag with this:

<main role="main" className="col-lg-12 d-flex">


{ [Link]
? <div id="loader" className="text-center"><p className="text-center">Loading...</p></div>
: <Main createProduct={[Link]} />
}
</main>

This will render the newly created component out onto the page whenever the app has loaded. If it is
loading, then it will show the loader!
Part 6: Buy Products (Front End) :
First, let's fetch all of the products from the blockchain inside of
the loadBlockchainData() function like this:
const productCount = await [Link]().call()
[Link]({ productCount })
// Load products
for (var i = 1; i <= productCount; i++) {
34

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

const product = await [Link](i).call()


[Link]({
products: [...[Link], product]
})
}
Now, let's create a function for buying the proudct:

purchaseProduct(id, price) {
[Link]({ loading: true })
[Link](id).send({ from: [Link], value: price })
.once('receipt', (receipt) => {
[Link]({ loading: false })
})
}
Now let's bind the function inside the constructor:

constructor(props) {
// ...
[Link] = [Link](this)
[Link] = [Link](this)
}
Now we'll pass two new props down to the Main component:

We'll update our code so that it looks like this:

<main role="main" className="col-lg-12 d-flex">


{ [Link]
? <div id="loader" className="text-center"><p className="text-center">Loading...</p></div>
: <Main
products={[Link]}
createProduct={[Link]}
purchaseProduct={[Link]} />
}
</main>

Replace all of the code inside the <tbody> tag with this:

{ [Link]((product, key) => {


return(
<tr key={key}>
<th scope="row">{[Link]()}</th>
<td>{[Link]}</td>
<td>{[Link]([Link](), 'Ether')} Eth</td>
<td>{[Link]}</td>
<td>
{ ![Link]
? <button
name={[Link]}
value={[Link]}
onClick={(event) => {
[Link]([Link], [Link])
}}
>
Buy
35

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

</button>
: null
}
</td>
</tr>
)
})}

Part 7: Deploy Project :


Now let's deploy our project to a live blockchain.
Refer this video for the deployment of project : [Link]
REFERENCE LINK : [Link]

RESULT :
Thus the Interaction with a blockchain network. Executing transactions and requests against a
blockchain network by creating an app to test the network and its rules was deployed successfully.

36

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Deploy an asset-transfer app using blockchain. Learn app


Ex : No : 4 development within a Hyperledger Fabric network
DATE :

AIM :
Deploy an asset-transfer app using blockchain. Learn app development within a Hyperledger Fabric
network.

PROCEDURE :
About Asset Transfer :
This Asset Transfer (basic) sample demonstrates how to initialize a ledger with assets, query
those assets, create a new asset, query a single asset based on an asset ID, update an existing asset, and
transfer an asset to a new owner. It involves the following two components:
1. Sample application: which makes calls to the blockchain network, invoking transactions implemented
in the chaincode (smart contract). The application is located in the following fabric-samples directory:
 asset-transfer-basic/application-javascript
2. Smart contract itself, implementing the transactions that involve interactions with the ledger. The
smart contract (chaincode) is located in the following fabric-samples directory:
 asset-transfer-basic/chaincode-(javascript, java, go, typescript)
Please note that for the purposes of this tutorial, the terms chaincode and smart contract are used
interchangeably. For this example, we will be using the javascript chaincode.
We’ll go through three principle steps:
1. Setting up a development environment.
2. Explore a sample smart contract.
3. Interact with the smart contract with a sample application.

Before you begin¶

In addition to the standard Prerequisites for Fabric, this tutorial leverages the Hyperledger Fabric SDK
for [Link]. See the [Link] SDK README for a up to date list of prerequisites.

on Linux, you need to install Python v2.7, make, and a C/C++ compiler toolchain such as GCC.
You can run the following command to install the other tools:
 sudo apt install build-essential
Set up the blockchain network¶

Navigate to the test-network subdirectory within your local clone of the fabric-samples repository.
cd fabric-samples/test-network
If you already have a test network running, bring it down to ensure the environment is clean.
./[Link] down
Launch the Fabric test network using the [Link] shell script.
37

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

./[Link] up createChannel -c mychannel -ca


This command will deploy the Fabric test network with two peers, an ordering service, and three
certificate authorities (Orderer, Org1, Org2). Instead of using the cryptogen tool, we bring up the test
network using Certificate Authorities,
Next, let’s deploy the chaincode by calling the ./[Link] script with the chaincode name and
language options.
./[Link] deployCC -ccn basic -ccp ../asset-transfer-basic/chaincode-javascript/ -ccl javascript
If the chaincode is successfully deployed, the end of the output in your terminal should look similar to
below:

Committed chaincode definition for chaincode 'basic' on channel 'mychannel':


Version: 1.0, Sequence: 1, Endorsement Plugin: escc, Validation Plugin: vscc, Approvals:
[Org1MSP: true, Org2MSP: true]
===================== Query chaincode definition successful on peer0.org2 on channel
'mychannel' =====================
===================== Chaincode initialization is not required
=====================

Sample application¶
Next, let’s prepare the sample Asset Transfer Javascript application that will be used to interact with the
deployed chaincode.
 JavaScript application
Note that the sample application is also available in Go and Java at the links below:
 Go application
 Java application
Open a new terminal, and navigate to the application-javascript folder.
cd asset-transfer-basic/application-javascript
This directory contains sample programs that were developed using the Fabric SDK for [Link]. Run
the following command to install the application dependencies. It may take up to a minute to complete:
npm install
This process is installing the key application dependencies defined in the application’s [Link].
Once npm install completes, everything is in place to run the application. Let’s take a look at the sample
JavaScript application files we will be using in this tutorial. Run the following command to list the files
in this directory:
ls
You should see the following:
[Link] node_modules [Link] [Link]

38

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Let’s run the application and then step through each of the interactions with the smart contract functions.
From the asset-transfer-basic/application-javascript directory, run the following command:
node [Link]
First, the application enrolls the admin user¶
In the sample application code below, you will see that after getting reference to the common
connection profile path, making sure the connection profile exists, and specifying where to create the
wallet, enrollAdmin() is executed and the admin credentials are generated from the Certificate
Authority.
async function main() {
try {
// build an in memory object with the network configuration (also known as a connection profile)
const ccp = buildCCP();

// build an instance of the fabric ca services client based on


// the information in the network configuration
const caClient = buildCAClient(FabricCAServices, ccp);

// setup the wallet to hold the credentials of the application user


const wallet = await buildWallet(Wallets, walletPath);

// in a real application this would be done on an administrative flow, and only once
await enrollAdmin(caClient, wallet);

This command stores the CA administrator’s credentials in the wallet directory. You can find
administrator’s certificate and private key in the wallet/[Link] file.

If you scroll back up to the beginning of the output in your terminal, it should be similar to below:

Wallet path: /Users/<your_username>/fabric-samples/asset-transfer-basic/application-javascript/wallet


Successfully enrolled admin user and imported it into the wallet

Because the admin registration step is bootstrapped when the Certificate Authority is started, we only
need to enroll the admin.

Second, the application registers and enrolls an application user

Now that we have the administrator’s credentials in a wallet, the application uses the admin user to
register and enroll an app user which will be used to interact with the blockchain network

 // in a real application this would be done only when a new user was required to be added
 // and would be part of an administrative flow
 await registerAndEnrollUser(caClient, wallet, mspOrg1, org1UserId, 'org1.department1');

Scrolling further down in your terminal output, you should see confirmation of the app user registration
similar to this:
 Successfully registered and enrolled user appUser and imported it into the wallet

Third, the sample application prepares a connection to the channel and smart contract¶
You will notice that in the following lines of application code, the application is getting reference to the
Contract using the contract name and channel name via Gateway

// Create a new gateway instance for interacting with the fabric network.
39

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

// In a real application this would be done as the backend server session is setup for
// a user that has been verified.
const gateway = new Gateway();

try {
// setup the gateway instance
// The user will now be able to create connections to the fabric network and be able to
// submit transactions and query. All transactions submitted by this gateway will be
// signed by this user using the credentials stored in the wallet.
await [Link](ccp, {
wallet,
identity: userId,
discovery: {enabled: true, asLocalhost: true} // using asLocalhost as this gateway is using a fabric
network deployed locally
});

// Build a network instance based on the channel where the smart contract is deployed
const network = await [Link](channelName);

// Get the contract from the network.


const contract = [Link](chaincodeName);

When a chaincode package includes multiple smart contracts, on the getContract() API you can specify
both the name of the chaincode package and a specific smart contract to target. For example:
 const contract = await [Link]('chaincodeName', 'smartContractName');
Fourth, the application initializes the ledger with some sample data :
The submitTransaction() function is used to invoke the chaincode InitLedger function to populate the
ledger with some sample data. Under the covers, the submitTransaction() function will use service
discovery to find a set of required endorsing peers for the chaincode, invoke the chaincode on the
required number of peers, gather the chaincode endorsed results from those peers, and finally submit the
transaction to the ordering service.
Sample application 'InitLedger' call
// Initialize a set of asset data on the channel using the chaincode 'InitLedger' function.
// This type of transaction would only be run once by an application the first time it was started after it
// deployed the first time. Any updates to the chaincode deployed later would likely not need to run
// an "init" type function.
[Link]('\n--> Submit Transaction: InitLedger, function creates the initial set of assets on the
ledger');
await [Link]('InitLedger');
[Link]('*** Result: committed');

Chaincode 'InitLedger' function


async InitLedger(ctx) {
const assets = [
{
ID: 'asset1',
Color: 'blue',
Size: 5,
Owner: 'Tomoko',

40

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

AppraisedValue: 300,
},
{
ID: 'asset2',
Color: 'red',
Size: 5,
Owner: 'Brad',
AppraisedValue: 400,
},
{
ID: 'asset3',
Color: 'green',
Size: 10,
Owner: 'Jin Soo',
AppraisedValue: 500,
},
{
ID: 'asset4',
Color: 'yellow',
Size: 10,
Owner: 'Max',
AppraisedValue: 600,
},
{
ID: 'asset5',
Color: 'black',
Size: 15,
Owner: 'Adriana',
AppraisedValue: 700,
},
{
ID: 'asset6',
Color: 'white',
Size: 15,
Owner: 'Michel',
AppraisedValue: 800,
},
];

for (const asset of assets) {


[Link] = 'asset';
await [Link]([Link], [Link]([Link](asset)));
[Link](`Asset ${[Link]} initialized`);
}
}
The terminal output entry should look similar to below:
Submit Transaction: InitLedger, function creates the initial set of assets on the ledger

Fifth, the application invokes each of the chaincode functions¶

the sample application is just getting all the assets that we populated in the prior step when we
initialized the ledger with data. The evaluateTransaction() function is used when you’d like to query a
single peer, without submitting a transaction to the ordering service.

Sample application 'GetAllAssets' call


41

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

 // Let's try a query type operation (function).


 // This will be sent to just one peer and the results will be shown.
 [Link]('\n--> Evaluate Transaction: GetAllAssets, function returns all the current assets on
the ledger');
 let result = await [Link]('GetAllAssets');
 [Link](`*** Result: ${prettyJSONString([Link]())}`);

Chaincode 'GetAllAssets' function

// GetAllAssets returns all assets found in the world state.


async GetAllAssets(ctx) {
const allResults = [];
// range query with empty string for startKey and endKey does an open-ended query of all assets in
the chaincode namespace.
const iterator = await [Link]('', '');
let result = await [Link]();
while (![Link]) {
const strValue = [Link]([Link]()).toString('utf8');
let record;
try {
record = [Link](strValue);
} catch (err) {
[Link](err);
record = strValue;
}
[Link]({ Key: [Link], Record: record });
result = await [Link]();
}
return [Link](allResults);
}

The terminal output should look like this:


Evaluate Transaction: GetAllAssets, function returns all the current assets on the ledger
Result: [
{
"Key": "asset1",
"Record": {
"ID": "asset1",
"Color": "blue",
"Size": 5,
"Owner": "Tomoko",
"AppraisedValue": 300,
"docType": "asset"
}
},
{
"Key": "asset2",
"Record": {
"ID": "asset2",
"Color": "red",
"Size": 5,
"Owner": "Brad",
42

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

"AppraisedValue": 400,
"docType": "asset"
}
},
{
"Key": "asset3",
"Record": {
"ID": "asset3",
"Color": "green",
"Size": 10,
"Owner": "Jin Soo",
"AppraisedValue": 500,
"docType": "asset"
}
},
{
"Key": "asset4",
"Record": {
"ID": "asset4",
"Color": "yellow",
"Size": 10,
"Owner": "Max",
"AppraisedValue": 600,
"docType": "asset"
}
},
{
"Key": "asset5",
"Record": {
"ID": "asset5",
"Color": "black",
"Size": 15,
"Owner": "Adriana",
"AppraisedValue": 700,
"docType": "asset"
}
},
{
"Key": "asset6",
"Record": {
"ID": "asset6",
"Color": "white",
"Size": 15,
"Owner": "Michel",
"AppraisedValue": 800,
"docType": "asset"
}
}
]

Next, the sample application submits a transaction to create ‘asset13’.


Sample application 'CreateAsset' call
// Now let's try to submit a transaction.
43

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

// This will be sent to both peers and if both peers endorse the transaction, the endorsed proposal will be
sent
// to the orderer to be committed by each of the peer's to the channel ledger.
[Link]('\n--> Submit Transaction: CreateAsset, creates new asset with ID, color, owner, size, and
appraisedValue arguments');
await [Link]('CreateAsset', 'asset13', 'yellow', '5', 'Tom', '1300');
[Link]('*** Result: committed');

Chaincode 'CreateAsset' function


// CreateAsset issues a new asset to the world state with given details.
async CreateAsset(ctx, id, color, size, owner, appraisedValue) {
const asset = {
ID: id,
Color: color,
Size: size,
Owner: owner,
AppraisedValue: appraisedValue,
};
return [Link](id, [Link]([Link](asset)));
}
Terminal output:
Submit Transaction: CreateAsset, creates new asset with ID, color, owner, size, and appraisedValue
arguments
The sample application then evaluates a query for ‘asset13’.
Sample application 'ReadAsset' call
 [Link]('\n--> Evaluate Transaction: ReadAsset, function returns an asset with a given
assetID');
 result = await [Link]('ReadAsset', 'asset13');
 [Link](`*** Result: ${prettyJSONString([Link]())}`);
Chaincode 'ReadAsset' function
// ReadAsset returns the asset stored in the world state with given id.
async ReadAsset(ctx, id) {
const assetJSON = await [Link](id); // get the asset from chaincode state
if (!assetJSON || [Link] === 0) {
throw new Error(`The asset ${id} does not exist`);
}
return [Link]();
}
Terminal output:
Evaluate Transaction: ReadAsset, function returns an asset with a given assetID
Result: {
"ID": "asset13",
"Color": "yellow",
"Size": "5",
"Owner": "Tom",
"AppraisedValue": "1300"
}
Sample application 'AssetExists', 'UpdateAsset', and 'ReadAsset' calls

44

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

[Link]('\n--> Evaluate Transaction: AssetExists, function returns "true" if an asset with given
assetID exist');
result = await [Link]('AssetExists', 'asset1');
[Link](`*** Result: ${prettyJSONString([Link]())}`);

[Link]('\n--> Submit Transaction: UpdateAsset asset1, change the appraisedValue to 350');


await [Link]('UpdateAsset', 'asset1', 'blue', '5', 'Tomoko', '350');
[Link]('*** Result: committed');

[Link]('\n--> Evaluate Transaction: ReadAsset, function returns "asset1" attributes');


result = await [Link]('ReadAsset', 'asset1');
[Link](`*** Result: ${prettyJSONString([Link]())}`);

Chaincode 'AssetExists', 'UpdateAsset', and 'ReadAsset' functions


// AssetExists returns true when asset with given ID exists in world state.
async AssetExists(ctx, id) {
const assetJSON = await [Link](id);
return assetJSON && [Link] > 0;
}
// UpdateAsset updates an existing asset in the world state with provided parameters.
async UpdateAsset(ctx, id, color, size, owner, appraisedValue) {
const exists = await [Link](ctx, id);
if (!exists) {
throw new Error(`The asset ${id} does not exist`);
}

// overwriting original asset with new asset


const updatedAsset = {
ID: id,
Color: color,
Size: size,
Owner: owner,
AppraisedValue: appraisedValue,
};
return [Link](id, [Link]([Link](updatedAsset)));
}
// ReadAsset returns the asset stored in the world state with given id.
async ReadAsset(ctx, id) {
const assetJSON = await [Link](id); // get the asset from chaincode state
if (!assetJSON || [Link] === 0) {
throw new Error(`The asset ${id} does not exist`);
}
return [Link]();
}

Terminal Output:
Evaluate Transaction: AssetExists, function returns "true" if an asset with given assetID exist
Result: true

Submit Transaction: UpdateAsset asset1, change the appraisedValue to 350

Evaluate Transaction: ReadAsset, function returns "asset1" attributes


Result: {
"ID": "asset1",
"Color": "blue",
45

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

"Size": "5",
"Owner": "Tomoko",
"AppraisedValue": "350"
}
Sample application 'UpdateAsset' call
try {
// How about we try a transactions where the executing chaincode throws an error
// Notice how the submitTransaction will throw an error containing the error thrown by the chaincode
[Link]('\n--> Submit Transaction: UpdateAsset asset70, asset70 does not exist and should return
an error');
await [Link]('UpdateAsset', 'asset70', 'blue', '5', 'Tomoko', '300');
[Link]('******** FAILED to return an error');
} catch (error) {
[Link](`*** Successfully caught the error: \n ${error}`);
}

Chaincode 'UpdateAsset' function


// UpdateAsset updates an existing asset in the world state with provided parameters.
async UpdateAsset(ctx, id, color, size, owner, appraisedValue) {
const exists = await [Link](ctx, id);
if (!exists) {
throw new Error(`The asset ${id} does not exist`);
}

// overwriting original asset with new asset


const updatedAsset = {
ID: id,
Color: color,
Size: size,
Owner: owner,
AppraisedValue: appraisedValue,
};
return [Link](id, [Link]([Link](updatedAsset)));
}
Terminal output:

Submit Transaction: UpdateAsset asset70

2020-08-02T[Link].322Z - error: [Transaction]: Error: No valid responses from any peers. Errors:
peer=[Link], status=500, message=error in simulation: transaction returned
with failure: Error: The asset asset70 does not exist
peer=[Link], status=500, message=error in simulation: transaction returned
with failure: Error: The asset asset70 does not exist
Expected an error on UpdateAsset of non-existing Asset: Error: No valid responses from any peers.
Errors:
peer=[Link], status=500, message=error in simulation: transaction returned
with failure: Error: The asset asset70 does not exist
peer=[Link], status=500, message=error in simulation: transaction returned
with failure: Error: The asset asset70 does not exist

Sample application 'TransferAsset', and 'ReadAsset' calls


[Link]('\n--> Submit Transaction: TransferAsset asset1, transfer to new owner of Tom');
await [Link]('TransferAsset', 'asset1', 'Tom');
[Link]('*** Result: committed');
46

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

[Link]('\n--> Evaluate Transaction: ReadAsset, function returns "asset1" attributes');


result = await [Link]('ReadAsset', 'asset1');
[Link](`*** Result: ${prettyJSONString([Link]())}`);

Chaincode 'TransferAsset', and 'ReadAsset' functions


// TransferAsset updates the owner field of asset with given id in the world state.
async TransferAsset(ctx, id, newOwner) {
const assetString = await [Link](ctx, id);
const asset = [Link](assetString);
[Link] = newOwner;
return [Link](id, [Link]([Link](asset)));
}
// ReadAsset returns the asset stored in the world state with given id.
async ReadAsset(ctx, id) {
const assetJSON = await [Link](id); // get the asset from chaincode state
if (!assetJSON || [Link] === 0) {
throw new Error(`The asset ${id} does not exist`);
}
return [Link]();
}

Terminal output:
Submit Transaction: TransferAsset asset1, transfer to new owner of Tom
Evaluate Transaction: ReadAsset, function returns "asset1" attributes
Result: {
"ID": "asset1",
"Color": "blue",
"Size": "5",
"Owner": "Tom",
"AppraisedValue": "350"
}

A closer look¶
The application starts by bringing in scope two key classes from the fabric-
network module; Wallets and Gateway. These classes will be used to locate the appUser identity in the
wallet, and use it to connect to the network:
 const { Gateway, Wallets } = require('fabric-network');
First, the program sets up the gateway connection with the userId stored in the wallet and specifies
discovery options.
// setup the gateway instance
// The user will now be able to create connections to the fabric network and be able to
// submit transactions and query. All transactions submitted by this gateway will be
// signed by this user using the credentials stored in the wallet.
await [Link](ccp, {
wallet,
identity: userId,
discovery: {enabled: true, asLocalhost: true} // using asLocalhost as this gateway is using a fabric
network deployed locally
});

47

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

In [Link], ccpPath describes the path to the connection profile that our application will use to
connect to our network. The connection profile was loaded from inside the fabric-samples/test-
network directory and parsed as a JSON file:
const ccpPath = [Link](__dirname, '..', '..', 'test-
network','organizations','peerOrganizations','[Link]', '[Link]');
const channelName = 'mychannel';
const chaincodeName = 'basic';
const network = await [Link](channelName);
Within this channel, we can access the asset-transfer (‘basic’) smart contract to interact with the ledger:
const contract = [Link](chaincodeName);
Within asset-transfer (‘basic’) there are many different transactions, and our application initially uses
the InitLedger transaction to populate the ledger world state with data:
await [Link]('InitLedger');
Updating the ledger

Clean up¶
When you are finished using the asset-transfer sample, you can bring down the test network
using [Link] script.
./[Link] down

RESULT :
Deploying an asset-transfer app using blockchain. Learn app development within a Hyperledger
Fabric network was successfully performed.

48

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Use blockchain to track fitness club rewards. Build a web app


Ex : No : 5 that uses Hyperledger Fabric to track and trace member
rewards.
DATE :

AIM :
Use blockchain to track fitness club rewards. Build a web app that uses Hyperledger Fabric to track
and trace member rewards.

INTRODUCTION :
This is a sample web application that uses a Hyperledger Fabric blockchain to track and trace fitness
rewards.
One of the biggest challenges Fitness Clubs face is maintaining members. It is always cheaper to keep a
member than attract new members. To retain members, some clubs will offer loyalty programs, but
oftentimes, those are ineffective because they may provide future free months or potentially offer a
discount to friends and family. Sometimes, the program only rewards members when they refer friends
to the club. In order to make loyalty more effective, there are a few things that will improve the
programs:
 Rewards for working out incentivizes members to use the facilities
 Ability to use their rewards more frequently and for more valuable purchases
 Visibility into their rewards lends trust to the program
With Fitcoins, we even add a new feature to loyalty programs, community building. By bringing local
merchants into the program, we can facilitate commerce with those merchants that want to be affiliated
with the club loyalty program. This provides an easy way for members to transact with the stores using
digital currency. The store owners benefit by getting access to customers they may not have had. As the
store owners earn Fitcoins through purchases, those Fitcoins could potentially be exchanged for cash
from the club or used to maybe purchase advertising at the club. This creates a whole ecosystem around
the club and a sense of community.
PROCEDURE :
Functionality of the Fitcoin app

With the Fitcoin app, a Fitness Club can:


 add new members.
49

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

 For active members you can:


1. simulate those members receiving rewards points
2. redeeming rewards points
3. viewing their rewards points history.
 Clubs can also deactivate members to simulate members cancelling their memberships,
something we hope never happens.

Hyperledger Composer Model


I using a UML Use Case model to do an approach for a simplified visualization of the cto model
file of the fitcoin system.
Here are my used/defined UML sterotypes:
transaction is represented as an UML use case
participant is represented as an UML actor
UML association does represent the dependency inside an transaction to a participant.
UML generalization does represent the extend for an participant.

Architecture
The following image shows the architecture of the Fitcoin system, based on Blockchain.

The components fitcoin webappliction, Hyperledger Composer REST Server and Wolfpack Fitclub
Fitcoin Hyperledger Fabric Network.

1 Flow
You will install on your local machine and run a sample web application.
50

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

1. Install Hyperledger Fabric and Composer


2. Build and Deploy the Fitcoin Blockchain Network
3. Build and run the Fitcoin Angular Web App

The following steps do contain the steps to install the given technical pre-requisites to run the sample
locally on your PC.
Ubuntu
1. Login as a normal user, rather than root.
2. Do not su to root.
3. When installing prerequisites, use curl, then unzip using sudo.
4. Run [Link] as a normal user. It may prompt for root password as some of it's actions
are required to be run as root.
5. Do not use npm with sudo or su to root to use it.
6. Avoid installing node globally as root.
If you're running on Ubuntu, you can download the prerequisites using the following commands:

curl -O [Link]
chmod u+x [Link]

Next run the script - as this briefly uses sudo during its execution, you will be prompted for your
password.
./[Link]

Install Node
Install the latest (long term support) version of Node:
 nvm install –lts
 nvm use –lts
 node –version
The Blockchain sample is based on three major components
You have to follow later the different readmes in this github project.
1. Hyperledger Fabric and Hyperledger Composer
This sub-project obtains the Hyperledger Composer development tools (primarily used to create
Business Networks) and stand up a Hyperledger Fabric (primarily used to run/deploy your Business
Networks locally).
Note: The Business Networks you create can also be deployed to Hyperledger Fabric runtimes in
other environments e.g. on a cloud platform.
2. Fitcoin Blockchain Network Archive
This sub-project includes the definition of the Hyperledger Fabric and Composer blockchain
network. Hyperledger models consist of a few components.
3. Fitcoin Angular Web App
In that sub-project you can find the sample webapplication.
The users will interact with the blockchain through a web UI written using [Link] and Angular 2
(6.x) framework.

Install Hyperledger Fabric and Composer

51

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Step 1: Install the CLI tools


 touch .bash_profile
 nvm —-version
 nvm use --lts
 node –version (note: You not should use su or sudo for the following npm commands.)

Essential CLI tools:
 npm install -g composer-cli@0.20
 npm install -g composer-rest-server@0.20
Step 2: Install Playground
npm install -g composer-playground@0.20
Step 3: Download the Hyperledger Fabric Docker Containers
./[Link]
Controlling the Blockchain environment
Starting and stopping Hyperledger Fabric
./[Link]
./[Link]
./[Link]

Build the network archive (bna file)


cd ./wolfpack-fitclub-fitcoin
npm install
Deploy the blockchain business network archive
touch .bash_profile
nvm —-version
nvm use --lts
node –version

Install the network

cd ./wolfpack-fitclub-fitcoin/dist
composer network install --archiveFile [Link] --card PeerAdmin@hlfv1

This should be the result.


✔ Installing business network. This may take a minute...
Successfully installed business network wolfpack-fitclub-fitcoin, version 0.0.2

Command succeeded

Start the network


composer network start --networkName wolfpack-fitclub-fitcoin --networkVersion 0.0.2 --card
PeerAdmin@hlfv1 --networkAdmin admin --networkAdminEnrollSecret adminpw

This should be the result.

Starting business network wolfpack-fitclub-fitcoin at version 0.0.2

Processing these Network Admins:


userName: admin

52

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

✔ Starting business network definition. This may take a minute...


Successfully created business network card:
Filename: admin@[Link]

Command succeeded

Create the Composer Card to connect to the network


From the command line, enter
composer card create -n wolfpack-fitclub-fitcoin -p ../../fabric-dev-servers/DevServer_connection.json -
u admin -s adminpw
You should see this:
Successfully created business network card file to
Output file: admin@[Link]
Command succeeded
Import the Composer Card into your Composer Wallet
composer card import -f admin@[Link]
You should see this:
Successfully imported business network card
Card file: admin@[Link]
Card name: admin@wolfpack-fitclub-fitcoin
Command succeeded
Test the composer network is listening
From the command line, enter
composer network ping -c admin@wolfpack-fitclub-fitcoin
You should see something that looks like this
The connection to the network was successfully tested: wolfpack-fitclub-fitcoin
Business network version: 0.0.2
Composer runtime version: 0.20.0
participant: [Link]#admin
identity:
[Link]#6f8e156dde4d67f9c1c10cd4180b3fd5d9c7238b8039c306a7
dc26a87eb74521
Command succeeded
Start the Composer REST server
composer-rest-server -p 3020 -c admin@wolfpack-fitclub-fitcoin -n never
Swagger: skipping unknown type "ReceiveFitcoins".
Swagger: skipping unknown type "RedeemFitcoins".

53

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Swagger: skipping unknown type "ReceiveFitcoins".


Swagger: skipping unknown type "RedeemFitcoins".
Added schemas for all types to Loopback
Web server listening at: [Link]
Browse your REST API at [Link]
The following image shows the running API explorer:

Load some sample data


There is a transaction to setup the demo with some data including:
1. A Club called WolfPack Elite
2. A few members
3. A few stores and products
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d
'{"$class":"[Link]"}' '[Link]
Test that the data loaded
curl -X GET --header 'Accept: application/json' '[Link]
[{"$class":"[Link]","club":"resource:[Link]#CLUB_001","member
Status":"ACTIVE","personId":"MEMBER_001","personFirstName":"Chris","personLastName":"Tyler"
,"fitCoinWallet":"resource:[Link]#MEMBER_001"},{"$class":"[Link]
[Link]","club":"resource:[Link]#CLUB_001","memberStatus":"ACTIVE","perso
nId":"MEMBER_002","personFirstName":"Darrel","personLastName":"Pyle","fitCoinWallet":"resourc
e:[Link]#MEMBER_002"},{"$class":"[Link]","club":"res
ource:[Link]#CLUB_001","memberStatus":"ACTIVE","personId":"MEMBER_003","
personFirstName":"Ashley","personLastName":"Troggio","fitCoinWallet":"resource:[Link].
FitcoinWallet#MEMBER_003"}]
The Fitcoin Angular Web App
Install the web app
From the ./fitcoin-app directory, enter the following command to have all the components installed
locally.
 npm install
Run the web app
Ensure that you have started your Composer REST Server and that you have run the SetupDemo
transaction to load data. Enter the following command to start the web app.
npm start

54

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Redeeming Fitcoins

Viewing activity detail

RESULT :
Using blockchain to track fitness club rewards. Building a web app that uses Hyperledger
Fabric to track and trace member rewards was performed successfully.

55

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Car auction network: A Hello World example with


Ex : No : 6 Hyperledger Fabric Node SDK and IBM Blockcha in Starter
Plan. Use Hyperledger Fabric to invoke chain code while
DATE :
storing results and data in the starter plan

AIM :
To create an Car auction network: A Hello World example with Hyperledger Fabric Node SDK and
IBM Blockcha in Starter Plan. Use Hyperledger Fabric to invoke chain code while storing results and
data in the starter plan.
PROCEDURE :
the chaincode will check for two types of errors:
 If the owner of the car bids on their own item
 If the bidder has enough money in their account to make the bid
If both checks are passed, an offer is recorded on the ledger. Once the auction closes, we call the
closeBidding transaction. That will give the car to the highest bidder, and transfer funds from the buyer
to the seller. The buyer will gain ownership of the car.
To ensure that our auction has worked correctly, we can query the ledger at the end to ensure that the car
has the correct owner, and that the seller has been credited the correct amount in their account.
Lastly, we will check the logs of the peers on the IBM Blockchain Starter Plan, and also view the details
of the blocks to see how transactions are recorded.
When the reader has completed this Code Pattern, they will understand how to:
 Interact with IBM Blockchain Starter Plan
 Build a blockchain back-end using Hyperledger Fabric Node SDK
 Inspect and read logs from applications connected to IBM Blockchain Starter Plan

If you do not have an IBM Cloud account yet, you will need to create one. In your IBM Cloud accout,
create a Blockchain Starter Plan service on your IBM Cloud account
Step 1. Clone the repo
The first thing we need to do is clone the repo on your local computer.
$ git clone [Link]

56

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

$ cd carauction-network
Step 2. Enroll App
First, we need to generate the necessary keys and certs from the Certificate Authority to prove our
authenticity to the network. To do this, we will go into our new IBM Blockchain Starter Plan network,
and from the Overview Tab on the left, we will click on Connection Profile on the right-side of the page.
Then click on Raw JSON.
Open [Link] in an editor of your choice. I prefer VSCode.
Down around line 40 of the file, you will see a new instance of the Fabric_CA_Client. This is where we
need to give our application the necessary endpoints of our CA from our IBM Blockchain Starter Plan.
We will need 4 things from the Certificate Authority
1. enrollId - should be "admin"
2. enrollSecret - should be similar to "1dcab332aa"
3. url - should be similar to "nde288ef7dd7542d3a1cc824a02be67f1-org1-
[Link]"
4. caName - should be "org1CA"
Your code should look something like this when finished:
fabric_ca_client = new
Fabric_CA_Client('[Link]
[Link]', null ,"org1CA", crypto_suite);
Your code should look something like this when finished (note, this is just a small chunk of the code)
return fabric_ca_client.enroll({
enrollmentID: 'admin',
enrollmentSecret: '4252f3499a'
}).then((enrollment) =>
Save your file, and run npm install:
$ npm install
Then, run this command to enroll the admin:
$ node [Link]
If all went well, you should get a response like this.

carauction node [Link]


Store path:/Users/[Link]@[Link]/Workdir/blockchain/carauction/hfc-key-store
(node:86820)
Successfully enrolled admin user "admin"
Assigned the admin user to the fabric client
::{"name":"admin","mspid":"org1","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"sig
ningIdentity":"b*4d7843af972bcfb7dac51f641458af95a54b4904d98da67e5b1db934adf35a","identity":{
"certificate":"-----BEGIN CERTIFICATE-----
57

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

\nMIIB8TCCAZigAwIBAgIULHILXwt3DhxQSW7gdzNmziY18iAwCgYIKoZIzj0EAwIw\nbzELMA
kGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMRQwEgYDVQQK\nEwtIeXBlc
mxlZGdlcjEPMA0GA1UECxMGRmFicmljMSAwHgYDVQQDExdmYWJyaWMt\nY2Etc2VydmVyL
W9yZzFDQTAeF*0xODA5MTcxODMxMDBaFw0xOTA5MTcxODM2MDBa\nMCExDzANBgNVB
AsTBmNsaWVudDEOMAwGA1UEAxMFYWRtaW4wWTATBgcqhkjOPQIB\nBggqhkjOPQMBBw
NCAAQIDN3iZJeoQbFE7+3ShqlhQd6cYsxrOAWs3nGlv/SC+qQV\nQd33uwkkbcs8PTVlWgM6Fsm
oNZfMEhx5LH1pW+y0o2AwXjAOBgNVHQ8BAf8EBAMC\nB4AwDAYDVR0TAQH/BAIwADAd
BgNVHQ4EFgQUuI4+VTbgNTXcnYg+8qpGXf/mUmIw\nHwYDVR0jBBgwFoAUo/8jv0agwT3tol8
HsbOmorxdijkwCgYIKoZIzj0EAwIDRwAw\nRAIgTEJKJL6/U/wMgxqG25K5NW4A5+ie1vG9qi7zP
98wVVoCIB7hV0en6cV3nI9L\nMdWPTvgrB67CCL8Ay+yJ25B8hMO9\n-----END CERTIFICATE---
--\n"}}}
Step 3. Register Users
Now that we have generated our client side certificates, and stored them in htc-key-store, we need to
register our application so that the network recongnizes it.
Open [Link] in the editor of your choice. On line 42, we can see a new instance of the
Fabric_ca_client being created. We can simply copy our existing instance from [Link]. This is
very important your URL should be the same as in [Link] .
After you copy and paste, the code in [Link] should look like this on line 42, except your
credentials will be different than mine:
fabric_ca_client = new
Fabric_CA_Client('[Link]
[Link]', null ,"org1CA", crypto_suite);
Now, run this command to register and enroll user1. You can only register an identity once. If you get
errors, it is probably because that user is already registered - you can try it with a different name.
$ node [Link]
If successful, output should be something like this:

carauction node [Link]


Store path:/Users/[Link]@[Link]/Workdir/blockchain/carauction/hfc-key-store
Successfully loaded admin from persistence
Successfully registered user1 - secret:OnqVuU*tCwPU
Successfully enrolled member user "user1"User1 was successfully registered and enrolled and is ready
to interact with the fabric network
Step 4. Invoking Chaincode
Now, we need to download the connection profile, and move it to our current working directory. From
the Overview in IBM Blockchain Platform, click on Download. Go to your recent downloads, and move
the file to the carauction-network directory.
Next, we need to install the chaincode on the peers. Then, we will need to instantiate the chaincode.
From the Overview tab on the left, click on Install Code. Then, click on Install Chaincode on the right.
Chaincode ID: carauction
Chaincode Version: 1
Chaincode Type: Node
58

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Choose your chaincode files from the carauction directory. This is very important. You need to select
both [Link] and [Link].
Then click Submit.
Once the chaincode in installed, we need to instantiate it. From the same screen, click on the 3-dot
symbol under Actions. Then click Instantiate.
For Chaincode Type select Node. Then click Next. Next, leave the defaults on the next screen, which
show a simple endorsement policy. Just click Submit.
Next, let's click on the Channels tab on the left side. Then click on the defaultchannel. You should see
the total blocks and time since last transaction. If we click on the block number, we can see
our initLedger function being called, and the data that was written to the ledger.
Open [Link] in the editor of your choice. You'll see at the top of the fil
 var creds = require('./[Link]');
 $ node [Link]
If all went well, you should see something like this:

carauction node [Link]


Store path:/Users/[Link]@[Link]/Workdir/blockchain/carauction/hfc-key-store
Successfully loaded user1 from persistence
Assigning transaction_id: 812694fba979d495423a40701fed3b221e7d7add2eecde8f9dd9a64827c8aced
Transaction proposal was good
Successfully sent Proposal and received ProposalResponse: Status - 200, message - "OK"
The transaction has been committed on peer n9fb94659f16c4d85a20219df994288bb-org1-
[Link]
Send transaction promise and event listener promise have completed
Successfully sent transaction to the orderer.
Successfully committed the change to the ledger by the peer
If you look around line 60 of [Link] you should see this:
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'carauction',
fcn: 'initLedger',
args: [''],
chainId: 'mychannel',
txId: tx_id
};
Step 5. Running the app

59

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

Now that we have connected our app to the IBM Blockchain Platform, each update of the ledger will be
recorded and added as a block. Let's run our app and see what it can do. You can find all commands that
I run in this step at [Link] in this repo.
Go to line 60 of [Link] and copy and paste this code instead what was there before. We are now
going to call the makeOffer method and pass in 3 arguments as shown in the code below:
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'carauction',
fcn: 'makeOffer',
args: ['3000', 'ABCD', 'memberA@[Link]'],
chainId: 'mychannel',
txId: tx_id
};
Note that in initLedger we created a car and assigned the owner of the car to be memberA@[Link].
Our auction does not allow the owner of car to bid on his/her own car. Thus, this call should give us an
error. Let's try it. Save [Link] and then run this command to invoke our app. Note, this step will be
repeated 5 more times below, but will exclude it for the sake of repetition. So remember, every time you
want to invoke our app, you'll need to change the request variable, save the file, and then run the
command below:
$ node [Link]
You should get an error message like this:
Assigning transaction_id: 06c289642a2b8cfd6c0cff41411c5b6a6fa45472f4e5af56c6adee3f06d98b71
[ [ { Error: 2 UNKNOWN: error executing chaincode: transaction returned with failure: Error: owner
cannot bid on own item:
at...
Next, let's give a successful transaction. Copy and paste the code for the request as follows:
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'carauction',
fcn: 'makeOffer',
args: ['4000', 'ABCD', 'memberB@[Link]'],
chainId: 'mychannel',
txId: tx_id
};
This should work, and now we have an offer from MemberB coming in at $4,000. If we check the
channel in Starter Plan, we can see the data that was written to the ledger.
Next, let's give another successful offer. Copy and paste the code for the request as follows:
60

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'carauction',
fcn: 'makeOffer',
args: ['5000', 'ABCD', 'memberC@[Link]'],
chainId: 'mychannel',
txId: tx_id
};
This will create an offer from Member C coming in at $5,000, which is greater than the reserve price. If
we check the Starter Plan again, we can see this data being written to the ledger, and the block count
increasing by one.
Next, let's give an offer that is too high...that is the offer is greater than the balance in the account.
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'carauction',
fcn: 'makeOffer',
args: ['5001', 'ABCD', 'memberB@[Link]'],
chainId: 'mychannel',
txId: tx_id
};
Since our members are initialized with a balance of $5,000, this will not work. You should get an error
message as follows:
{ Error: 2 UNKNOWN: error executing chaincode: transaction returned with failure: Error: The bid is
higher than the balance in your account!
Lastly, let's close the bidding. Use this code as follows for the request:
var request = {
//targets: let default to the peer assigned to the client
chaincodeId: 'carauction',
fcn: 'closeBidding',
args: ['ABCD'],
chainId: 'mychannel',
txId: tx_id
};
Save the file and issue the following command, as we have been doing all along up to this point.
$ node [Link]
61

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

You should get a successful response. If you check the output of the block details, we can see that the
new owner of the car is MemberC. We also see that Member C now has $0 in their balance, since they
had $5,000 to start with, and their bid of $5,000 won the auction. That means that the new owner is
Member C, and that Member A, the original owner of the car, will be credited $5,000. This is reflected
on the ledger - Member A now has a balance of $10,000. Lastly, if we check the vehicle listing, we can
see that the status is SOLD.
Step 6. Querying the Ledger
Now that we have submitted transactions on the ledger, we can query the ledger at any point, using the
key corresponding to that object. So first, let's query Member A. This is the member that just won the
auction, so they should have $10,000 in their account. To query, open up [Link] in the editor of your
choice. Just like [Link] there is a request variable that allows us to pass in a key to query the ledger.
Let's pass in memberA@[Link] for the key. The request variable on line 55, should as follows:
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'carauction',
fcn: 'query',
args: ['memberA@[Link]']
};
Our response should look something like this:
Response is {"balance":10000,"firstName":"Amy","lastName":"Williams"}
We can query memberB as follows, but this is not too interesting since memberB did not win the
auction. The output for querying memberB is as follows:
Response is {"balance":5000,"firstName":"Billy","lastName":"Thompson"}
Now, if we query memberC, we should see that their balance is 0. The request should look as follows
for memberC:
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'carauction',
fcn: 'query',
args: ['memberC@[Link]']
};
With the response being:
Response is {"balance":0,"firstName":"Tom","lastName":"Werner"}
Now if we query the vehicle number, we should see the owner be memberC. Let's do that with the
following request:
const request = {
//targets : --- letting this default to the peers assigned to the channel

62

Downloaded by sudarsan R (sudarsansrs@[Link])


lOMoARcPSD|23170297

chaincodeId: 'carauction',
fcn: 'query',
args: ['1234']
};
The response:
Response is {"owner":"memberC@[Link]"}
Lastly, and most interestingly, let's query our vehicle listing. It should show up as being SOLD, and
should have no offers.
The request:
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'carauction',
fcn: 'query',
args: ['ABCD']
};
The response:
Response is {"description":"Arium
Nova","listingState":"SOLD","offers":null,"reservePrice":3500,"vehicle":"1234"}

Conclusion
That's it! I showed you how to register your application and then register users to your application using
certificates provided by the Certificate Authority. Next, I showed you how to download your connection
profile and use it to create a channel and add peers and an orderer to that channel. After that, we used
the IBM Blockchain Starter Plan to install our chaincode on the peers, and then instantiated our network
on the defaultchannel. Next, we invoked our chaincode and created some offers on the network. We
closed the bidding and saw our ledger being updated as Member C won the auction. Lastly, we learned
how to query the ledger to ensure that our data looks how we intend it to look.

RESULT :
Creating an Car auction network: A Hello World example with Hyperledger Fabric Node SDK and IBM
Blockcha in Starter Plan. Using Hyperledger Fabric to invoke chain code while storing results and data
in the starter plan was performed.

63

Downloaded by sudarsan R (sudarsansrs@[Link])

Common questions

Powered by AI

Setting up a Hyperledger Fabric network using Fabric CA involves several steps: first, bring down any existing network with './network.sh down', then use './network.sh up -ca' to start the network with Certificate Authorities, which includes defining TLS and MSP configuration paths. Utilizing Fabric CA allows for dynamic network enrollment and identity management, enhancing security by leveraging cryptographic identity material generated on-demand rather than relying on the static creation by tools like 'cryptogen' .

Chaincode in Hyperledger Fabric acts as the business logic or smart contracts that define the transactions, including creating or modifying assets. It is deployed using the command './network.sh deployCC' with the necessary parameters, such as chaincode name and path. Once deployed, it can be invoked using the 'peer chaincode invoke' command, specifying functions like 'InitLedger' or 'TransferAsset' to perform operations on the blockchain .

Asset transfer in a Hyperledger Fabric network is performed through chaincode execution. Using valid transactions, the chaincode 'TransferAsset', for instance, changes the owner of an asset. This process involves 'peer chaincode invoke' command execution with transaction parameters reflecting the updated asset state—including new ownership details. This operation verifies the update across network nodes, maintaining immutability and consensus, which is integral for trust and reliability in distributed networks .

The 'purchaseProduct' function in Solidity allows a user to purchase a product by submitting the product ID and transferring Ether to complete the purchase. The function is marked 'payable', enabling Ethereum transfer, and updates the product's 'purchased' status. It involves modifying stored product data's 'owner' to the buyer's address, implicating that ownership transfer is captured on-chain. This enforces immutability and transparency in digital transactions, fundamental to the blockchain's secure transaction model .

Setting environment variables in Hyperledger Fabric is essential to configure the peer CLI for correct operation within a given organization's context. This includes enabling TLS, specifying MSP IDs, root certificates, MSP configuration paths, and peer network addresses. This ensures that CLI commands, like 'peer chaincode invoke' and 'peer chaincode query', interact with the correct network peers as intended, critical for executing and verifying blockchain operations .

Deploying smart contracts using Truffle offers streamlined processes for compilation, deployment, and testing, leveraging frameworks like Mocha and Chai for testing. This allows for efficient development environments, comprehensive testing, and lifecycle management. However, challenges include the learning curve for framework specifics, the need for additional environment setup, and potential dependencies dealings, which require detailed configuration management .

You can create multiple channels in a Hyperledger Fabric network using the command './network.sh createChannel' with the '-c' flag to specify different channel names, such as './network.sh createChannel -c channel1' and './network.sh createChannel -c channel2'. This allows each set of transaction participants to operate in isolated estate, ensuring privacy and confidentiality of transaction data that is relevant only for specific channel members .

A sample application like the asset transfer application using JavaScript serves as an interface to test interactions with the blockchain network. It initiates operations such as querying and updating the ledger via chaincode function calls, demonstrating the practical application of blockchain features. It facilitates understanding of real-world interactions, offering developers insights to design robust applications, ensuring efficient resource utilization within the network .

Mappings in Solidity smart contracts function like associative arrays or hash tables to store data against unique keys. For example, to store Product data, a mapping like 'mapping(uint => Product) public products' is used, enabling quick retrieval of product information by ID. This structure is significant because it allows efficient storage and retrieval of dynamic data structures, essential for operations like tracking assets in decentralized applications .

Testing smart contracts is crucial because these contracts define the unalterable rules once deployed on the blockchain. Testing ensures their correctness before production. In Solidity, contracts can be tested using frameworks such as Mocha and Chai that allow simulation of interactions through JavaScript. This involves asserting functions, events, and conditions in the contract's behavior, ensuring that each function outputs the expected result before deploying to the live environment .

You might also like