This tutorial aims to guide you through the process of building a permissioned blockchain network with Hyperledger Fabric.
By the end of this tutorial, you will have a clear understanding of the key features of Hyperledger Fabric and will be able to use them to create secure, efficient, and flexible permissioned blockchain networks.
Prerequisites:
- Basic understanding of blockchain technology
- Familiarity with JavaScript
- Node.js and npm installed on your system
- Docker and Docker Compose installed on your system
First, we need to install Hyperledger Fabric on our system. You can do this by cloning the fabric-samples
repository from GitHub using the following command:
git clone https://github.com/hyperledger/fabric-samples.git
Navigate to the fabric-samples
directory:
cd fabric-samples
Then, run the script to download the Docker images for Hyperledger Fabric:
./scripts/bootstrap.sh
A typical network in Hyperledger Fabric consists of the following components:
Peer Nodes: These are the fundamental elements of the network, responsible for maintaining the ledger and running smart contracts (chaincode).
Ordering Service: This ensures the consistency of the blockchain by ordering the transactions into a block and distributing them to peer nodes.
Certificate Authority (CA): This provides the network with an identity, issuing and managing digital certificates.
Let's create a basic network with two organizations (Org1 and Org2), each with one peer node, and a single ordering service.
Navigate to the test-network
directory:
cd test-network
Then, run the following command to create the network:
./network.sh up createChannel -ca -s couchdb
This command creates the network, a channel, and starts the network with a Certificate Authority and CouchDB as the state database.
Chaincode is the smart contract that runs on the nodes of a Hyperledger Fabric network. It is written in chaincode language.
Here is a simple example of a chaincode that initializes a ledger with test data:
const { Contract } = require('fabric-contract-api');
class FabCar extends Contract {
async initLedger(ctx) {
console.info('============= START : Initialize Ledger ===========');
const cars = [
{
color: 'blue',
make: 'Toyota',
model: 'Prius',
owner: 'Tomoko',
},
// more cars can be added here
];
for (let i = 0; i < cars.length; i++) {
cars[i].docType = 'car';
await ctx.stub.putState('CAR' + i, Buffer.from(JSON.stringify(cars[i])));
console.info('Added <--> ', cars[i]);
}
console.info('============= END : Initialize Ledger ===========');
}
}
This chaincode contains a single function initLedger
which initializes the ledger with an array of cars.
In this tutorial, we learned about Hyperledger Fabric and how to create a basic network with it. We've covered the installation process, the key components of the network, and we've also looked at a simple example of chaincode.
Solution: You can add a function createCar
to the FabCar
class:
async createCar(ctx, carNumber, make, model, color, owner) {
console.info('============= START : Create Car ===========');
const car = {
color,
docType: 'car',
make,
model,
owner,
};
await ctx.stub.putState(carNumber, Buffer.from(JSON.stringify(car)));
console.info('============= END : Create Car ===========');
}
This function takes the car details as parameters, creates a new car object, and adds it to the ledger.
Solution: You can add a function queryCar
to the FabCar
class:
async queryCar(ctx, carNumber) {
const carAsBytes = await ctx.stub.getState(carNumber);
if (!carAsBytes || carAsBytes.length === 0) {
throw new Error(`${carNumber} does not exist`);
}
console.log(carAsBytes.toString());
return carAsBytes.toString();
}
This function retrieves the car details from the ledger using the car number.
Keep practicing and try to explore more complex scenarios. Happy coding!