CCS Lab Manual: Blockchain & Docker Guide
CCS Lab Manual: Blockchain & Docker Guide
ANNA UNIVERSITY
ANNA UNIVERSITY
UNIVERSITY COLLEGE OF ENGINEERING – DINDIGUL
DINDIGUL – 62422
BONAFIDE CERTIFICATE
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
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.
4. docker images
1. docker ps
2. docker ps -a
3. docker ps -l
6. docker rm youthful_curie
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
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.
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 :
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:
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:
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 :
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 :
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
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
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
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:
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:
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
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
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
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:
4. We’ll create a client side website with [Link] and [Link] so that users can talk to the smart
contracts
12
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:
13
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.
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
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"
$ npm install
require('babel-register');
require('babel-polyfill');
15
[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).
contract Marketplace {
string public name;
16
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.
[Link] = function(deployer) {
[Link](Marketplace);
};
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:
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
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]
before(async () => {
marketplace = await [Link]()
})
})
})
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
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:
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:
19
);
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
uint id,
string name,
uint price,
address owner,
bool purchased
);
constructor() public {
name = "Dapp University Marketplace";
}
require('chai')
.use(require('chai-as-promised'))
.should()
before(async () => {
marketplace = await [Link]()
})
before(async () => {
result = await [Link]('iPhone X', [Link]('1', 'Ether'), { from: seller })
productCount = await [Link]()
})
22
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
24
25
// 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')
let price
price = [Link]('1', 'Ether')
price = new [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
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
27
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
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:
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 let's render it out on the page. First, delete all the old Navbar code, and replace it with this:
29
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:
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.')
}
}
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
// 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
);
}
}
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
// ...
[Link] = [Link](this)
}
[Link]
with the following code:
import React, { Component } from 'react';
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
<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>
);
}
}
Go back to [Link] and import the newly created component at the top of the file like this:
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
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:
Replace all of the code inside the <tbody> tag with this:
</button>
: null
}
</td>
</tr>
)
})}
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
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.
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
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
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();
// 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:
Because the admin registration step is bootstrapped when the Certificate Authority is started, we only
need to enroll the admin.
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
// 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);
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');
40
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,
},
];
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.
"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"
}
}
]
// 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');
44
[Link]('\n--> Evaluate Transaction: AssetExists, function returns "true" if an asset with given
assetID exist');
result = await [Link]('AssetExists', 'asset1');
[Link](`*** Result: ${prettyJSONString([Link]())}`);
Terminal Output:
Evaluate Transaction: AssetExists, function returns "true" if an asset with given assetID exist
Result: true
"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}`);
}
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
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
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
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
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
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.
51
cd ./wolfpack-fitclub-fitcoin/dist
composer network install --archiveFile [Link] --card PeerAdmin@hlfv1
Command succeeded
52
Command succeeded
53
54
Redeeming Fitcoins
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
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
$ 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.
\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:
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:
59
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
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
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
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
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 .