This tutorial aims to guide you through the process of developing smart contracts using Hyperledger Composer. We will be learning how to define business networks that use blockchain technology, and how to write smart contracts, or chaincode, to interact with the blockchain.
By the end of this tutorial, you will be able to:
- Understand the basic concepts of Hyperledger Composer
- Write your own smart contracts using Hyperledger Composer
- Deploy your smart contracts on a blockchain business network
Before starting this tutorial, you should have a basic understanding of blockchain technology, JavaScript programming, and Node.js. Familiarity with Hyperledger Fabric is beneficial but not a strict requirement.
Before we can start writing our smart contracts, we need to install the necessary tools. This includes Node.js, npm, Docker, and the Hyperledger Composer CLI.
npm install -g composer-cli
This command installs the Hyperledger Composer command line interface.
A business network in Hyperledger Composer is defined by a set of models (the assets, participants, and transactions) and scripts (the business logic, or smart contracts). We define these in the models
and lib
directories, respectively.
For example, we might define an asset Car
and a transaction TradeCar
in our model file (models/org.example.mynetwork.cto
).
asset Car identified by vin {
o String vin
--> Member owner
}
transaction TradeCar {
--> Car car
--> Member newOwner
}
In the lib
directory, we then define the business logic for the TradeCar
transaction in a script file (lib/logic.js
).
function tradeCar(trade) {
trade.car.owner = trade.newOwner;
return getAssetRegistry('org.example.mynetwork.Car')
.then(function (assetRegistry) {
return assetRegistry.update(trade.car);
});
}
/* Define an asset 'SampleAsset' with a string property 'value' */
asset SampleAsset identified by assetId {
o String assetId
o String value
}
/* Define a transaction 'SampleTransaction' that changes the 'value' of a 'SampleAsset' */
transaction SampleTransaction {
--> SampleAsset asset
o String newValue
}
/* In your script file, write the function that implements the transaction */
function sampleTransaction(tx) {
tx.asset.value = tx.newValue;
return getAssetRegistry('org.example.mynetwork.SampleAsset')
.then(function (assetRegistry) {
return assetRegistry.update(tx.asset);
});
}
In this tutorial, we learned how to set up our development environment for Hyperledger Composer, how to define assets and transactions in a business network, and how to write the business logic for these transactions in the form of smart contracts.
As next steps, you might want to explore more complex business networks, with multiple types of assets and participants, and more complex transactions. You can also learn how to test your business network and how to deploy it on a real blockchain.
Define a business network for a simple supply chain, with assets Product
and Shipment
, and a transaction DeliverShipment
.
Write a transaction that changes the ownership of a car from one member to another.
Write a transaction that splits a shipment into two smaller shipments.
asset Product identified by productId {
o String productId
o String description
o Double price
}
asset Shipment identified by shipmentId {
o String shipmentId
--> Product[] products
--> Member owner
}
transaction DeliverShipment {
--> Shipment shipment
--> Member newOwner
}
transaction ChangeOwner {
--> Car car
--> Member newOwner
}
function changeOwner(tx) {
tx.car.owner = tx.newOwner;
return getAssetRegistry('org.example.mynetwork.Car')
.then(function (assetRegistry) {
return assetRegistry.update(tx.car);
});
}
transaction SplitShipment {
--> Shipment shipment
o Product[] productsOne
o Product[] productsTwo
}
function splitShipment(tx) {
var shipmentOne = factory.newResource('org.example.mynetwork', 'Shipment', 'SHIP1');
shipmentOne.products = tx.productsOne;
shipmentOne.owner = tx.shipment.owner;
var shipmentTwo = factory.newResource('org.example.mynetwork', 'Shipment', 'SHIP2');
shipmentTwo.products = tx.productsTwo;
shipmentTwo.owner = tx.shipment.owner;
return getAssetRegistry('org.example.mynetwork.Shipment')
.then(function (assetRegistry) {
return assetRegistry.addAll([shipmentOne, shipmentTwo]);
});
}