Set up a network on the IBM Blockchain Platform and deploy a decentralized energy smart contract on the network.
Hyperledger Fabric sample Decentralized Energy on IBM Blockchain Platform
This code pattern demonstrates setting up a network on the IBM Blockchain Platform and deploying the Decentralized smart contract on the network. Next, we generate client-side certificates so the developer can subsequently enroll an application identity and then submit transactions on the smart contract. The application is setup with a Node.js server using the Fabric Node SDK to process requests to the network.
A key application of Blockchain being currently explored is a Decentralized Energy network. The idea stems from a neighborhood where certain Residents are producing energy through Solar panels or other means, and can sell excess energy to Residents needing energy. The transactions would be based on coins in each Resident's account. As per a pre-determined contract and rate, the coins would be debited from the consumer and credited to the producer, for a certain billing period. Each transaction would need to be atomic and added to a Blockchain ledger for trust and verification. The network can include Banks to transact coins for Fiat currency (USD). The network can have Utility Company who can buy or provide energy through the network.
The network consists of Residents, Banks and Utility Companies. Residents can exchange coins for energy among each other. The application assumes a pre-paid system where transactions occur after the energy is consumed and the values are updated. The Resident can exchange coins for Fiat money (USD) with Banks on the network. The Residents can also transact coins for energy with a Utility company on the network.
The code pattern demonstrates how a Node.js smart contract can be packaged using the IBM Blockchain Platform Extension for VS Code. Then, using the extension, you can set up a local instance of the Hyperledger Fabric network, on which you can install and instantiate the contract. Lastly, the application is setup with a Node.js server using the Fabric Node SDK to process transactions that communicate with the network.
When you have completed this code pattern, you will understand how to:
Follow these steps to set up and run this code pattern. The steps are described in detail below.
Clone this repository in a folder your choice:
git clone https://github.com/IBM/decentralized-energy-fabric-on-IBP20
We will use the IBM Blockchain Platform extension to package the smart contract.
Open Visual Studio code and open the contract
folder from Decentralized Energy repository that was cloned earlier.
Press the F1
key to see the different VS code options. Choose IBM Blockchain Platform: Package Open Project
.
IBM Blockchain Platform
extension button on the left. This will show the packaged contracts on top and the blockchain connections on the bottom.
Next, right click on the packaged contract (in this case, select [email protected]) to export it and choose Export Package
.
Choose a location on your machine and save .cds
file. We will deploy this smart contract package on the IBM Blockchain Platform service in a later step.
Now, we will start creating our Hyperledger Fabric network on the IBM Cloud.
Catalog
. For this code pattern, we can use the Free
cluster, and give it a name. Note, that the IBM Cloud allows one instance of a free cluster which expires after 30 days. Note: it could take 20 minutes for the IBM Cloud Kubernetes Service setup to complete.
Catalog
, and give it a name.
We will build a network as provided by the IBM Blockchain Platform documentation. This will include creating a channel with a single peer organization with its own MSP and CA (Certificate Authority), and an orderer organization with its own MSP and CA. We will create the respective identities to deploy peers and operate nodes.
Org1 CA
and click Next.admin
and CA Administrator Enroll Secret of adminpw
, then click Next.
admin
and an Enroll secret of adminpw
. Use the default value of Org1 CA Identity
for the Identity display name.
admin
identity that was created for the CA is visible in the table.org1admin
, and Enroll Secret of org1adminpw
. Set the Type for this identity as client
. We can specify to Use root affiliation or uncheck this field and select from any of the affiliated organizations from the drop-down list. We will leave the Maximum enrollments field blank. Click Next.peer1
, and Enroll Secret of peer1pw
. Set the Type for this identity as peer
. We can specify to Use root affiliation or uncheck this field and select from any of the affiliated organizations from the drop-down list. Click Next.
Org1MSP
and an MSP ID of Org1MSP
.Org1 CA
as the root CA for the organization.org1admin
and org1adminpw
. Then, give the Identity name as Org1 Admin
.
Peer Org1
and click Next.Org1 CA
as the Certificate Authority. Then, give the Peer enroll ID and Peer enroll secret for the peer identity that you created for your peer, that is, peer1
, and peer1pw
. Select the Organization MSP as Org1MSP
, from the drop-down list. Leave the TLS CSR hostname blank. Click Next.Org1 Admin
and click Next.
Orderer CA
and click Next.admin
and CA Administrator Enroll Secret of adminpw
, then click Next.
admin
and an Enroll secret of adminpw
. Use the default value of Orderer CA Identity
for the Identity display name.
admin
identity that was created for the CA is visible in the table.ordereradmin
, and Enroll Secret of ordereradminpw
. Set the Type for this identity as client
. We can specify to Use root affiliation or uncheck this field and select from any of the affiliated organizations from the drop-down list. We will leave the Maximum enrollments field blank. Click Next.orderer1
, and Enroll Secret of orderer1pw
. Set the Type for this identity as orderer
. We can specify to Use root affiliation or uncheck this field and select from any of the affiliated organizations from the drop-down list. Click Next.
OrdererMSP
and an MSP ID of OrdererMSP
.Orderer CA
as the root CA for the organization.ordereradmin
and ordereradminpw
. Then, give the Identity name as Orderer Admin
.
Orderer
and click Next.Orderer CA
as the Certificate Authority. Then, give the Ordering service enroll ID and Ordering service enroll secret for the peer identity that you created for your orderer, that is, orderer1
, and orderer1pw
. Select the Organization MSP as OrdererMSP
, from the drop-down list. Leave the TLS CSR hostname blank. Click Next.Orderer Admin
and click Next.
Org1MSP
, as this is the MSP that represents the peer's organization "Org1".
mychannel
.Orderer
from the Ordering service drop-down list.Org1MSP (Org1MSP)
from the drop-down list to add the organization "Org1" as a member of this channel. Click Add button. Set the permissions for this member as Operator.Org1MSP (Org1MSP)
from the dropdown as the Channel creator MSP and select Org1 Admin
from the dropdown under Identity.
Orderer
as the Ordering service and click Next.mychannel
and click Next.Peer Org1
.
[email protected]
), which we packaged earlier using the IBM Blockchain Platform extension for Visual Studio code.
mychannel
on which to instantiate the smart contract. Click Next.Org1MSP
. Click Next.
Connect with SDK
from the overflow menu on the right side of the row.Org1MSP
.Org1 CA
.
app-admin
and Enroll Secret of app-adminpw
. Set the Type for this identity as client
. We can specify to Use root affiliation or uncheck this field and select from any of the affiliated organizations from the drop-down list. We will leave the Maximum enrollments field blank. Click Next.hf.Registrar.Roles
= *
. This will allow this identity to act as a registrar and issue identities for our app. Click Add attribute.
app-admin
and app-adminpw
.Org1MSP
.{ enabled: true, asLocalhost: false }
to connect to IBP.Once all this is done, your config.json should look something like this:
{
"connection_file": "mychannel_decentralizedenergy_profile.json",
"channel_name": "mychannel",
"smart_contract_name": "decentralizedenergy",
"appAdmin": "app-admin",
"appAdminSecret": "app-adminpw",
"orgMSPID": "Org1MSP",
"caName": "169.46.208.151:30404",
"userName": "user1",
"gatewayDiscovery": { "enabled": true, "asLocalhost": false }
}
First, navigate to the web-app
directory, and install the node dependencies.
cd web-app/server
npm install
Run the enrollAdmin.js
script
node enrollAdmin.js
You should see the following in the terminal:
msg: Successfully enrolled admin user app-admin and imported it into the wallet
From the server
directory, start the server.
npm start
In a new terminal, open the web client folder and install the dependencies.
cd web-app/angular-app
npm install
Start the client:
npm start
You can find the app running at http://localhost:4200/ Click on the green "Authorized Access" button to authorize access. Once that is done, you will be able to register Participants such as Residents, Banks and Utility Companies as well as post transactions between these participants.
You can go to the IBM Blockchain Platform v2 console to monitor your network and get information on your channel.
Navigate to the application
directory, and install the node dependencies.
cd application
npm install
Run the enrollAdmin.js
script
node enrollAdmin.js
You should see the following in the terminal:
msg: Successfully enrolled admin user app-admin and imported it into the wallet
Now let's register each of our participants. We will register R1
as resident, B1
as bank, U1
as utility company. Navigate to add-participants
folder and register the resident identity:
cd add-participants
node registerResident.js
You should see the following in the terminal:
Successfully registered and enrolled user "R1" and imported it into the wallet
Similarly register bank and utility company on the network.
node registerBank.js
node registerUtilityCompany.js
Now add the participants on the state. The contract stores the id of the identity creating the participant as their participantId
. Let's add our resident:
node addResident.js
You should see the following in the terminal:
2019-02-27T06:38:29.252Z - info: [TransactionEventHandler]: _strategySuccess: strategy success for transaction "c092df4098775057a7b712db402e45f3c8420d98fc022dfc331accb580448d4a"
...
Similarly add bank and utility company on the network.
node addBank.js
node addUtilityCompany.js
Now let's perform the EnergyTrade
and CashTrade
transactions. These transactions will verify the sender's id, as the id on the world state before updating the state. In our case that is our resident R1:
cd ../invoker-tx/
node energy-trade.js
You should see the following in the terminal followed by updated state of the resident and utility company:
2019-02-27T06:38:29.252Z - info: [TransactionEventHandler]: _strategySuccess: strategy success for transaction "c092df4098775057a7b712db402e45f3c8420d98fc022dfc331accb580448d4a"
...
Similarly, let's do the CashTrade
transaction between resident and bank.
node cash-trade.js
You should see the following in the terminal followed by updated state of the resident and the bank:
2019-02-27T06:38:29.252Z - info: [TransactionEventHandler]: _strategySuccess: strategy success for transaction "c092df4098775057a7b712db402e45f3c8420d98fc022dfc331accb580448d4a"
...
If you receive the following error on submitting transaction:
error: [Client.js]: Channel not found for name mychannel
It is safe to ignore this error because the ibp2.0 beta has service discovery enabled. (In order to use service discovery to find other peers please define anchor peers for your channel in the ui). If you really want the message to go away you can add the channels section to the connection profile, but it is a warning rather than a true error telling the user the channel is found but not in the connection profile
As an example you can manually add the following json and updated the IP address and ports manually:
"channels": {
"mychannel": {
"orderers": [
"169.46.208.151:32078"
],
"peers": {
"169.46.208.151:31017": {}
}
}
},
This code pattern is licensed under the Apache Software License, Version 2. Separate third-party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 (DCO) and the Apache Software License, Version 2.