blockchain hyperledger lab

51
Hands-on Lab Getting Started With Hyperledger Fabric (Blockchain) Benjamin Fuentes, IBM Nitesh Thakrar, IBM

Upload: devevents

Post on 05-Apr-2017

34 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Blockchain Hyperledger Lab

Hands-on Lab Getting Started With Hyperledger Fabric (Blockchain) Benjamin Fuentes, IBM Nitesh Thakrar, IBM

Page 2: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 2 of 51

© Copyright IBM Corporation 2017 IBM, the IBM logo and ibm.com are trademarks of International Business Machines Corp., registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is available on the Web at “Copyright and trademark information” at www.ibm.com/legal/copytrade.shtml. This document is current as of the initial date of publication and may be changed by IBM at any time. The information contained in these materials is provided for informational purposes only, and is provided AS IS without warranty of any kind, express or implied. IBM shall not be responsible for any damages arising out of the use of, or otherwise related to, these materials. Nothing contained in these materials is intended to, nor shall have the effect of, creating any warranties or representations from IBM or its suppliers or licensors, or altering the terms and conditions of the applicable license agreement governing the use of IBM software. References in these materials to IBM products, programs, or services do not imply that they will be available in all countries in which IBM operates. This information is based on current IBM product plans and strategy, which are subject to change by IBM without notice. Product release dates and/or capabilities referenced in these materials may change at any time at IBM’s sole discretion based on market opportunities or other factors, and are not intended to be a commitment to future product or feature availability in any way.

Page 3: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 3 of 51

Table of Contents Pre requisites 4

Part 1 - Use Blockchain as a Service on Bluemix Cloud and start a network locally 5

a) Use Blockchain as a Service on the Cloud 5

b) Start a network locally 7

Part 2 - Create a smart contract in Java 14

a) Create a contract 15

1. Implementing overridden methods 22

2. Implementing initialization and invocation methods 24

b) Deployment and testing 27

1. Local testing 27

2. Deployment 28

3. Interact more with your chaincode 30

Part 3 – Develop the client side application 33

a) Initialization 33

b) Deployment 42

c) Queries 44

d) Invocations 45

e) Testing it ! 46

Page 4: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 4 of 51

Pre requisites For Part 1:

• Bluemix account: https://console.ng.bluemix.net/registration • Docker: https://docs.docker.com/engine/installation/#platform-support-

matrix • Docker compose: https://docs.docker.com/compose/install • Postman: https://www.getpostman.com

For Part 2:

• Java 8: http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html

• Eclipse: https://www.eclipse.org/downloads • Eclipse Maven plugin: (you can use the one embedded on Eclipse) • Eclipse Gradle plugin: (depending on the version, it can be already

included or https://projects.eclipse.org/projects/tools.buildship)

For Part 3:

• (same as part2)

Page 5: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 5 of 51

Part 1 - Use Blockchain as a Service on Bluemix Cloud and start a network locally

a) Use Blockchain as a Service on the Cloud You can go to Bluemix and use a Blockchain as a Service If you do not have a Bluemix access yet, please register for a free 30 days account here (https://console.ng.bluemix.net/registration) Go to Bluemix console > Catalog (https://console.ng.bluemix.net/catalog)

And search for service named “Blockchain” on the filter area

Page 6: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 6 of 51

Click on the service, give it a unique name and click on Create button

When finished, click on Launch Dashboard

Bluemix has created for you a Blockchain network of 4 peers to let you focus on developing smart contract applications on top of it. Scroll the menu to explore:

- Network: 4 validating peers + Certificate Authority - Blockchain: local view on the Blockchain for peer 0 - Demo Chaincode: Ready to deploy demos

Page 7: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 7 of 51

- APIs: Swagger-like HTTP call interactions with Blockchain network/peers

- Logs: server logs on each peer - Service Status: service info to let you know maintenance and service

upgrades - Support: helpful links

Now that you have a blockchain network running, go to the menu Demo Chaincode to play with one demo

b) Start a network locally Now that you have tested a Blockchain on the Cloud, let’s do the same on your machine. We will explain a little bit more the way to deploy your own Blockchain network Install Docker on your machine: https://docs.docker.com/engine/installation/#platform-support-matrix

Page 8: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 8 of 51

We will use Hyperledger official Docker images to start a Blockchain network of 4 peers + 1 CA (Certificate Authority) Images are available here : https://hub.docker.com/u/hyperledger If you encounter any problem during this lab, you can find links at the end of this document pointing to the correction. There you can verify if you have done any mistake. All commands below are for Unix machines (Linux, MacOs, Debian, Ubuntu, etc… ). If you use another OS like Windows, just transcript the command. We are using very basic commands that exists on all OS.

1. Create a Docker file from the official image. Open a console and type theses commands (choose any workspace folder on your machine)

mkdir baseimage touch baseimage/Dockerfile echo "FROM hyperledger/fabric-peer:x86_64-0.6.1-preview" > baseimage/Dockerfile

2. Create the file for Docker compose touch four-peer-ca.yaml

3. Open this new file on an editor (can double click on it from the file

explorer) and type the beginning of the file version: '2' services: baseimage: build: ./baseimage image: hyperledger/fabric-baseimage:latest membersrvc: image: hyperledger/fabric-membersrvc:x86_64-0.6.1-preview extends: file: base/membersrvc.yaml service: membersrvc vp0: image: hyperledger/fabric-peer:x86_64-0.6.1-preview extends: file: base/peer-unsecure-base.yaml service: peer-unsecure-base

Page 9: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 9 of 51

ports: - "7050:7050" # REST - "7051:7051" # Grpc - "7053:7053" # Peer callback events environment: - CORE_PEER_ID=vp0 links: - membersrvc volumes: - /Users/benjaminfuentes/git:/chaincode Save the file and leave it open As you can see we refer to the base image, we declare a membersrvc peer that is the Certificate Authority and only 1 peer named vp0. We will write the file base/membersrvc.yaml on the next steps Now, have a look on the peer vp0 configuration:

- We are going to write the base file for all validating peer on base/peer-unsecure-base.yaml. We are not going to use security enabled for this demo in order to simplify all API requests, also we will use the NOOPS consensus (i.e autovalidating consensus for development). You can have a look on Fabric options to enable security and configure PBFT (see http://hyperledger-fabric.readthedocs.io/en/v0.6/Setup/Network-setup )

- We are translating inside containers ports to outside using “ports:” You can read it like this “insidePort:outsidePort”

- We name the first peer vp0 (for the block section and the parameter CORE_PEER_ID)

- Finally, we add a dependency on service named membersrvc (which need to be started before)

- Parameter volumes will be used for vp0 only in order to deploy chaincode based on a file path. Please change /Users/benjaminfuentes/git path with our own workspace path!

YAML files are really boring strict with space indentation, be very careful. Copy/paste from correction files on links at the end of this document if you have any problem

4. Now that you have understood the configuration, you can add 3 more peers at the end of this file four-peer-ca.yaml: vp1, vp2, and vp3. Copy paste vp0 block, rename peer name, CORE_PEER_ID, and translate outside ports with 1000 offset (i.e. vp1 from 8050 to 8053, vp2 from 9050 to 9053 and vp4 from 10050 to 10053). Inside ports are kept the same obviously. You do not need to mount a volume as we will deploy chaincode only on vp0.

Page 10: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 10 of 51

Also you will need to add this on the environment section to refer to the first node : - CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051 Finally on the links section, add a dependency to vp0 - vp0 Save and close file.

5. As that the main file is done, let’s create the common peer file base/peer-unsecure-base.yaml

mkdir base touch base/peer-unsecure-base.yaml and edit the file version: '2' services: peer-unsecure-base: volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - CORE_PEER_DISCOVERY_PERIOD=300s - CORE_PEER_DISCOVERY_TOUCHPERIOD=301s - CORE_PEER_ADDRESSAUTODETECT=true - CORE_VM_ENDPOINT=unix:///var/run/docker.sock - CORE_LOGGING_LEVEL=DEBUG - CORE_PEER_PKI_ECA_PADDR=membersrvc:7054 - CORE_PEER_PKI_TCA_PADDR=membersrvc:7054 - CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054 - CORE_SECURITY_ENABLED=false command: sh -c "sleep 10; peer node start" Save and close Here we have mounted Docker socket to dialog with Docker deamon and set security enabled to false

6. Create the file for the Certificate Authority touch base/membersrvc.yaml and then edit it version: '2' services:

Page 11: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 11 of 51

membersrvc: ports: - "7054:7054" command: membersrvc environment: - MEMBERSRVC_CA_LOGGING_SERVER=INFO - MEMBERSRVC_CA_LOGGING_CA=INFO - MEMBERSRVC_CA_LOGGING_ECA=INFO - MEMBERSRVC_CA_LOGGING_ECAP=INFO - MEMBERSRVC_CA_LOGGING_ECAA=INFO - MEMBERSRVC_CA_LOGGING_ACA=INFO - MEMBERSRVC_CA_LOGGING_ACAP=INFO - MEMBERSRVC_CA_LOGGING_TCA=INFO - MEMBERSRVC_CA_LOGGING_TCAP=INFO - MEMBERSRVC_CA_LOGGING_TCAA=INFO - MEMBERSRVC_CA_LOGGING_TLSCA=INFO Save and close file

7. All is set now, let’s start the network using the command docker-compose -f four-peer-ca.yaml up To see containers running, open another terminal and send command docker ps

8. If you want to stop the network, escape the running docker compose (Ctrl + C) or use the command

docker-compose -f four-peer-ca.yaml stop This will stop all containers To see containers stopped: docker ps -a

9. If you want to destroy all containers, just run. (if case you did a mistake and want to start from scratch from the docker-compose config files)

docker-compose -f four-peer-ca.yaml down Finally test your Blockchain network with Postman.

Page 12: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 12 of 51

To install Postman : https://www.getpostman.com Launch it from the menu bar and import the file (that you will download at this URL) : https://github.com/zamrokk/JavaCDD/blob/master/postman.json

Click on Raw

Page 13: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 13 of 51

Save the page (Ctrl+S)

Import the file on Postman. Click on Import

Page 14: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 14 of 51

Drop the file, or browse folder On the Collections tab, click on the first line named CHAIN V0.6. Click on button Send, you should have a response 200 OK with chain height equals to 1

Part 2 - Create a smart contract in Java In the following sections you will discover how Blockchain technology can be used to sign contract between a farmer and an insurer and then to trigger changes on the contract’s state. CDD derivative is an insurance for farmers to hedge against poor harvests caused by failing rains during the growing

Page 15: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 15 of 51

period, excessive rain during harvesting, high winds in case of plantations or temperature variabilities in case of greenhouse crops. In a CDD case, every time the average day degree passes under a threshold, a client could receive a payment, smoothing earnings.

• Creating a contract between a farmer and an insurer • Executing a contract based on a specific location • Querying the contract State to know if the farmer has received

a payment

In this business scenario each participant has entered into a business agreement with each other and all parties are known and trusted by each other. For each contract deployment, one instance of the java project is running on the Blockchain. For our example, we will create only one contract between two people, but you can do as many as you want. This demo has been simplified in the way:

• No security has been enabled and configured. • We trust and assume that calls to Weather API will send back always

the same value for each peer. We also trust Weather API data as a trustable oracle. (This is NOT deterministic => Bad bad bad!)

• We can do unlimited calls. Normally in a real case, the contract should be executed once relatively to a period corresponding to the average temperature of the previous month

• The contract should contain a start and end date validity. You can do it as an extra exercise

a) Create a contract In the following section you will code a CDD derivative chaincode contract in Java using Hyperledger.

Farmer Insurer

Page 16: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 16 of 51

Install Eclipse : https://www.eclipse.org/downloads

1. Open Eclipse and create a new Maven Project

Click next

Page 17: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 17 of 51

2. You need to copy some configuration files and pojos java class to help you start and let us focus on the important files. Recreate the project structure as it:

Page 18: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 18 of 51

To create the com.ibm package, you do it like this:

Copy theses files from the project url into its correct folder (https://github.com/zamrokk/JavaCDD):

• build.gradle • pom.xml

Page 19: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 19 of 51

• /src/main/java/com/ibm/ContractRecord.java • /src/main/java/com/ibm/WeatherObservationResponse.java • /src/test/java/com/ibm/JavaCDDTest.java

3. Have a look on the project structure. You have the choice to use Maven or Gradle for development but Gradle will be mandatory when the code will be deployed as Gradle file will be only run by Hyperledger on version V0.6.1

At the moment, you have 2 POJOs class files:

• ContractRecord • WeatherObservationResponse

You have a test class available: JavaCDDTest You will be asked to code a JavaCDD class file that extends ChaincodeBase

4. Create a new class JavaCDD on package com.ibm that’s extends ChaincodeBase. You will write later a main method. You can see that some methods need to be implemented too.

5. Look at dependencies to see from which package is coming

ChaincodeBase class. The fabric-sdk-java jar will be downloaded automatically during compilation. Open pom.xml and build.gradle

Maven

<dependency> <groupId>org.hyperledger.fabric-sdk-java</groupId> <artifactId>fabric-sdk-java</artifactId> <version>0.6</version> </dependency>

Gradle compile 'org.hyperledger.fabric-sdk-java:fabric-sdk-java:0.6'

This jar is available on m2 central repository so no problem J 6. Click on the red cross of the class, and click on Add unimplemented

methods. Now you can do a maven compile or gradle compileJava. Both should compile fine.

Page 20: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 20 of 51

To do so, open Run Configurations…

For Maven

Page 21: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 21 of 51

For Gradle

Now your project should not have any red errors. Compilation is done

Page 22: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 22 of 51

1. Implementing overridden methods

Eclipse TIP: To auto-indent files, go to top menu Source > Format (Shift+Ctrl+F)

1. First step is to start a main thread and name your chaincode. Edit it as follow:

private static Log log =LogFactory.getLog(JavaCDD.class); public static void main(String[] args) throws Exception { new JavaCDD().start(args); } @Override public String getChaincodeID() { return "JavaCDD"; }

2. Start coding the entry point method run. It is the dispatcher entry point

for INVOKE and DEPLOY API. init function is used while deployment only and all others for normal invocations.

@Override /** * Entry point of invocation interaction * * @param stub * @param function * @param args */ public String run(ChaincodeStub stub, String function, String[] args) { log.info("In run, function:" + function); switch (function) { case "init": init(stub, function, args); break; case "executeContract": String re = executeContract(stub, args); log.info("Return of executeContract : " + re); return re; default: String warnMessage = "{\"Error\":\"Error function " + function + " not found\"}"; log.warn(warnMessage); return warnMessage;

Page 23: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 23 of 51

} return null; }

3. Last overridden method is query. We will have to retrieve the contract

state and return it back to the client. Do it as below

/** * This function can query the current State of the contract * @param stub * @param function * @param args * client name * @return total amount received for this client */ @Override public String query(ChaincodeStub stub, String function, String[] args) {

if (args.length != 1) { return "{\"Error\":\"Incorrect number of arguments. Expecting name of the client to query\"}"; } String clientName = stub.getState(args[0]); log.info("Called " + function + " on client : " + clientName); if (clientName != null && !clientName.isEmpty()) { try { ObjectMapper mapper = new ObjectMapper(); ContractRecord contractRecord = mapper.readValue(clientName, ContractRecord.class); return "" + contractRecord.totalAmountReceived; } catch (Exception e) { return "{\"Error\":\"Failed to parse state for client " + args[0] + " : " + e.getMessage() + "\"}"; } } else { return "{\"Error\":\"Failed to get state for client " + args[0] + "\"}"; } }

Page 24: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 24 of 51

2. Implementing initialization and invocation methods

1. At deployment we will need to initialize the contract. Copy the code below

/** * This function initializes the contract * @param stub * @param function * @param args * client name, temperature threshold, amount received when * contract is activated * @return */ public String init(ChaincodeStub stub, String function, String[] args) { if (args.length != 3) { return "{\"Error\":\"Incorrect number of arguments. Expecting 3 : client name, temperature threshold, amount received when contract is activated \"}"; } try { ContractRecord contractRecord = new ContractRecord(args[0], Integer.parseInt(args[1]),Integer.parseInt(args[2])); stub.putState(args[0], contractRecord.toString()); } catch (NumberFormatException e) { return "{\"Error\":\"Expecting integer value for temperature threshold and amount received\"}"; } return null; }

2. Then, here is the main piece. We are coding the contract for a specific

location passed as parameters. We have an API call to Weather API that will return the current temperature and will compare it against the threshold of the contract. If the temperature is below, then the client will have its account credited with the redemption agreement amount of the contract, otherwise nothing happens.

(Credentials of the service API have been hardcoded, you can change this value with your own credentials on Bluemix)

Page 25: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 25 of 51

/** * This function calls Weather API to check if the temperature on a location * is inferior to the contract's threshold. If yes, the client is redeemed * for the value agreed on the contract * * @param stub * @param args * client name, postal Code, country Code * @return */ public String executeContract(ChaincodeStub stub, String[] args) { log.info("in executeContract");

Boolean contractExecuted = false; if (args.length != 3) { String errorMessage = "{\"Error\":\"Incorrect number of arguments. Expecting 3: client name, postal Code, country Code\"}"; log.error(errorMessage); return errorMessage; } ObjectMapper mapper = new ObjectMapper(); ContractRecord contractRecord; try { contractRecord = mapper.readValue(stub.getState(args[0]), ContractRecord.class); } catch (Exception e1) { String errorMessage = "{\"Error\":\" Problem retrieving state of client contract : " + e1.getMessage()+ " \"}"; log.error(errorMessage); return errorMessage; } String postalCode = args[1]; String countryCode = args[2]; // weather service String url = "https://twcservice.mybluemix.net/api/weather/v1/location/" + postalCode + "%3A4%3A" + countryCode + "/observations.json?language=en-GB"; HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet(url); SSLSocketFactory sf; try { SSLContext sslContext = SSLContext.getInstance("TLS");

Page 26: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 26 of 51

sslContext.init(null, null, null); sf = new SSLSocketFactory(sslContext); } catch (Exception e1) { String errorMessage = "{\"Error\":\" Problem with SSLSocketFactory : " + e1.getMessage() + " \"}"; log.error(errorMessage); return errorMessage; } sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); Scheme sch = new Scheme("https", sf, 443); httpclient.getConnectionManager().getSchemeRegistry().register(sch); ((AbstractHttpClient) httpclient).getCredentialsProvider().setCredentials( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), new UsernamePasswordCredentials("dfa7551a-2613-4f5c-bff7-339649770aa5", "gvbmK5JsGO")); HttpResponse response; try { response = httpclient.execute(httpget); log.info("Called Weather service"); int statusCode = response.getStatusLine().getStatusCode(); HttpEntity httpEntity = response.getEntity(); String responseString = EntityUtils.toString(httpEntity); if (statusCode == HttpStatus.SC_OK) { log.info("Weather service call OK"); WeatherObservationResponse weatherObservationResponse = mapper.readValue(responseString,WeatherObservationResponse.class); if (weatherObservationResponse.getObservation().getTemp() < contractRecord.temperatureThreshold) { // then please redeem the client contractRecord.totalAmountReceived += contractRecord.amountReceivedWhenContractIsActivated;

Page 27: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 27 of 51

stub.putState(contractRecord.clientName, contractRecord.toString()); log.info("Contract condition valid " + weatherObservationResponse.getObservation().getTemp() + " < " + contractRecord.temperatureThreshold); contractExecuted=true; } else { log.info("Contract condition invalid " + weatherObservationResponse.getObservation().getTemp()+ " > " + contractRecord.temperatureThreshold); } } else { String errorMessage = "{\"Error\":\"Problem while calling Weather API : " + statusCode + " : "+ responseString + "\"}"; log.error(errorMessage); return errorMessage; } } catch (Exception e) { String errorMessage = "{\"Error\":\"Problem while calling Weather API : " + e.getMessage() + "\"}"; log.error(errorMessage); try { log.error(new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(e.getStackTrace())); } catch (JsonProcessingException e2) { e2.printStackTrace(); } return errorMessage; } return contractExecuted.toString(); }

b) Deployment and testing

1. Local testing We will use Mockito to mock the Blockchain and detect any problem in our code before deploying it.

Page 28: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 28 of 51

For more info about mockito : http://site.mockito.org

3. On your project, go to folder /src/test/java. You will find a class named JavaCDDTest There are two Junit test cases on it. Nice test case should always execute the contract but not increment the client’s account Fairbanks should increment (as it is very cold there!)

Logs and Eclipse debug mode should be enough for you to check if the redeem amount has changed.

4. Launch the Junit tests. Right click on project or test file and click Run

as > JUnit Test or Debug as > JUnit Test All tests should have passed green. Check then the logs, to see if scenarios have run as expected. If you are not sure, run on debug mode and add breakpoints to your code

2. Deployment

As your chaincode is running correctly locally with a mocked Blockchain, it is time to deploy it on the real one. To deploy a chaincode we will use the HTTP API with Postman

1. Open Postman and run DEPLOY V0.6

Page 29: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 29 of 51

(Optional) Be sure that your Blockchain network is running (see Part 1) Also check that your project name is corresponding to the mounted path /chaincode/JavaCDD. Use docker to list files on mounted folder (replace in red by your vp0 container id) [Remember this path as you will need it in Part 3 too]. docker exec -i PEERVP0CONTAINERID /bin/bash ls /chaincode

(Optional) There is another way to deploy a chaincode using not a path by an url, just replace the path value by the url. You should have a 200 OK

In the returned Json, copy the value of result>message. It is the unique identifier of your chaincode, you will need it for after

The deployment is asynchronous. Even if Hyperledger send you back a correct response, it just means that your request was correct and has been processed. To be sure that the new smart contract has been started, go to a console and do a docker ps. If you see a container name containing the chaincode ID of your request, it means the smart contract is running. Speed depends on the performance of your machine and the size of the code, it can take from 2s to few minutes

2. Call the query you coded to see if the default amount has been initialized

Page 30: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 30 of 51

You should have a zero amount on the message returned

On the request body, do not forget to change params>chaincodeID>name by the one returned on the previous step

3. Interact more with your chaincode

1. Run INVOKE V0.6

Page 31: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 31 of 51

Do not forget to change the chaincodeID as step before, let the default parameters pointing to Fairbanks and you should have a response 200 OK. For information, the data result>message on the response corresponds to the transaction ID Let’s call the query again to check the result

Page 32: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 32 of 51

You should have an amount with value 42 on the message returned. This confirms that your farmer has been credited of 42$.

Page 33: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 33 of 51

Part 3 – Develop the client side application

a) Initialization We will now use the Java SDK to interact with our blockchain instead of the HTTP API. HTTP API will be deprecated on V1.0 of Hyperledger so we will need to use GRPC channel to communicate with the network, it on what is based the SDK. We want to use a real java client app to keep our wallet safe, so we choose to use a simple spring boot project and build an API over it for testing (You could do it with any other java application using JavaFx, Swing or whatever support the SDK which is built on java 8)

1. Create a new maven Project in Eclipse named JavaCDDWeb

Page 34: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 34 of 51

Skip the archetype selection, use the default workspace location

Page 35: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 35 of 51

you can edit as above, but we will override it on the next step anyway

2. Edit pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ibm</groupId> <artifactId>JavaCDDWeb</artifactId> <version>0.0.1-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version> </parent> <packaging>war</packaging> <dependencies>

Page 36: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 36 of 51

<dependency> <groupId>me.reactiv.fabric-java-sdk</groupId> <artifactId>fabric-java-sdk</artifactId> <version>0.6.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.5.RELEASE</version>

Page 37: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 37 of 51

<scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> </project> This is the simplest configuration that we can have to have a REST API ready You maybe have noticed that we have changed the SDK dependency. It is because, we will need the last version of the Git branch 0.6 and it has not been released officially yet on Maven Central.

3. Create a controller class named MyController on the package com.ibm.controller

Page 38: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 38 of 51

Create new java package and a new class MyController

Page 39: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 39 of 51

4. Edit MyController.java @RestController @EnableAutoConfiguration public class MyController { private static Log logger =

Page 40: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 40 of 51

LogFactory.getLog(MyController.class); private Member registrar; private String chainCodeID; private Chain chain; public static void main(String[] args) throws Exception { SpringApplication.run(MyController.class, args); } } For the moment, you can run MyController as a Java Application but does nothing more than starting a server and exposing the controller on http://localhost:8080 TIP: If you start Spring Boot application and you have the port 8080 already in use, please kill the other process like this : lsof -i tcp:8080 kill mypidijustfoundwiththepreviouscommand TIP: If you have any problem with JRE, just check you are using JDK8 on your project. Right click on your project, click on buildpath and see with JDK you are using.

Page 41: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 41 of 51

It is not JDK 8, remove the library, then click on the right panel to add library

Then select JDK8 library and confirm

Page 42: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 42 of 51

Also sometimes Eclipse complains about JDK compliance, you can right click on project, Prperties and filter “compliance”. You should have Java compiler compliance >= 1.7

b) Deployment

1. Write the Constructor and deploy function public MyController() throws Exception { logger.info("In MyController constructor ..."); chain = new Chain("javacdd"); chain.setDeployWaitTime(60*5); try { chain.setMemberServicesUrl("grpc://localhost:7054", null); // create FileKeyValStore Path path = Paths.get(System.getProperty("user.home"), "/test.properties"); if (Files.notExists(path)) Files.createFile(path);

Page 43: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 43 of 51

chain.setKeyValStore(new FileKeyValStore(path.toString())); chain.addPeer("grpc://localhost:7051", null); registrar = chain.getMember("admin"); if (!registrar.isEnrolled()) { registrar = chain.enroll("admin", "Xurw3yU9zI0l"); } logger.info("registrar is :" + registrar.getName() + ",secret:" + registrar.getEnrollmentSecret()); chain.setRegistrar(registrar); chain.eventHubConnect("grpc://localhost:7053", null); chainCodeID = deploy(); } catch (CertificateException | IOException e) { logger.error(e.getMessage(), e); throw new Exception(e); } logger.info("Out MyController constructor."); } Chain object will represent the chaincode deployed. We are configuring MemberServices url in order to register a user admin and get the signing & encryption certificates that we will store in our local wallet saved under test.properties file. We are configuring the peer to whom we will discuss with We are enrolling the user admin the first time to get the keys, but next time we will retrieve it from the local wallet on the machine. Be careful in case you failed storing the keys the first time because the CA will consider that the user has been enrolled and we no more deliver the keys. You will need to clean all CA database so we recommend to destroy the full network with docker-compose and redo a new one. We are connecting to peer eventhub to catch all failures and success messages after we call invocation methods. As the system is asynchronous, it is the only way to know if the grpc call finally succeeded. Finally, we are deploying our chaincode and get the chaincodeID back

Page 44: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 44 of 51

2. Write the deploy function now. Use your path setting from Part 2 for

the setChaincodePath (e.g. “workspace”,”JavaCDD”). String deploy() throws ChainCodeException, NoAvailableTCertException, CryptoException, IOException { DeployRequest deployRequest = new DeployRequest(); ArrayList<String> args = new ArrayList<String>(); args.add("init"); args.add("farmer"); args.add("10"); args.add("42"); deployRequest.setArgs(args); deployRequest.setChaincodePath(Paths.get(System.getProperty("user.home"), "git", "JavaCDD").toString()); deployRequest.setChaincodeLanguage(ChaincodeLanguage.JAVA); deployRequest.setChaincodeName(chain.getName()); ChainCodeResponse chainCodeResponse = registrar.deploy(deployRequest); return chainCodeResponse.getChainCodeID(); } We are building a DeployRequest and the registrar is submitting it to the peer (the SDK signing under the hood) Finally we return the chaincodeID that needs to be used later

c) Queries Let’s write our query to obtain the total redeemed amount of a client @RequestMapping(method = RequestMethod.GET, path = "/query", produces = { MediaType.APPLICATION_JSON_VALUE }) @ResponseBody String query(@RequestParam String clientName) throws JsonProcessingException { logger.info("Calling /query ..."); QueryRequest queryRequest = new QueryRequest(); ArrayList<String> args = new ArrayList<String>();

Page 45: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 45 of 51

args.add("query"); args.add(clientName); queryRequest.setArgs(args); queryRequest.setChaincodeLanguage(ChaincodeLanguage.JAVA); queryRequest.setChaincodeID(chainCodeID); try { ChainCodeResponse chainCodeResponse = registrar.query(queryRequest); logger.info("End call /query."); return new ObjectMapper().writeValueAsString(chainCodeResponse); } catch (ChainCodeException | NoAvailableTCertException | CryptoException | IOException e) { logger.error("Error", e); return new ObjectMapper().writeValueAsString(e); } } We are exposing a GET API under /query and we need the client name on input. We are building a QueryRequest object that will be submitted by the registrar, etc … the response will be sent on the body of the message on JSON format

d) Invocations Same as above but for the invocation function of the chaincode @RequestMapping(method = RequestMethod.GET, path = "/executeContract", produces = { MediaType.APPLICATION_JSON_VALUE }) @ResponseBody String executeContract(@RequestParam String clientName, @RequestParam String postalCode, @RequestParam String countryCode) throws JsonProcessingException { logger.info("Calling /executeContract ...");

Page 46: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 46 of 51

InvokeRequest invokeRequest = new InvokeRequest(); ArrayList<String> args = new ArrayList<String>(); args.add("executeContract"); args.add(clientName); args.add(postalCode); args.add(countryCode); invokeRequest.setArgs(args); invokeRequest.setChaincodeLanguage(ChaincodeLanguage.JAVA); invokeRequest.setChaincodeID(chainCodeID); invokeRequest.setChaincodeName(chain.getName()); try { ChainCodeResponse chainCodeResponse = registrar.invoke(invokeRequest); logger.info("End call /executeContract."); return new ObjectMapper().writeValueAsString(chainCodeResponse); } catch (ChainCodeException | NoAvailableTCertException | CryptoException | IOException e) { logger.error("Error", e); return new ObjectMapper().writeValueAsString(e); } } We are exposing a GET API under /executeContract and we need the client name, postal code and country code on input. We are building an InvokeRequest object that will be submitted by the registrar, etc … the response will be sent on the body of the message on JSON format

e) Testing it !

1. So you have now a client application that runs on a secured network. Let’s do some modifications on the work done on Part1 to make it secure. Remember the file /base/peer-unsecure-base.yaml, edit now this property: - CORE_SECURITY_ENABLED=true

Page 47: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 47 of 51

Also, the peers will need to be authenticated on the network, not only the users, so for each peer on the file four-peer-ca.yaml, add these new properties on the block environment For vp0: - CORE_SECURITY_ENROLLID=test_vp0 - CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT For vp1: - CORE_SECURITY_ENROLLID=test_vp1 - CORE_SECURITY_ENROLLSECRET=5wgHK9qqYaPy For vp2: - CORE_SECURITY_ENROLLID=test_vp2 - CORE_SECURITY_ENROLLSECRET=vQelbRvja7cJ For vp3: - CORE_SECURITY_ENROLLID=test_vp3 - CORE_SECURITY_ENROLLSECRET=9LKqKH5peurL

2. Now that the network runs with security enabled, you will need to add extra security jars to your JDK.

Download this zip, and extract it on the folder ${java.home}/jre/lib/security/ : http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

3. You will have to solve an issue due to official Hyperledger images. It refers to a Docker javaenv image named hyperledger/fabric-javaenv:latest .Sadly this image does not exist so here is the trick :

docker pull hyperledger/fabric-javaenv:x86_64-0.6.1-preview docker tag hyperledger/fabric-javaenv:x86_64-0.6.1-preview hyperledger/fabric-javaenv:latest

4. You will need to destroy your network and rebuild it with docker-

compose docker-compose -f four-peer-ca.yaml down docker-compose -f four-peer-ca.yaml up

5. Now you can start you Spring Boot Application

Page 48: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 48 of 51

6. Open again Postman and select QUERY CLIENT V0.6, click on SEND You should have the API responding SUCCESS with message “0” if the client has not been redeemed yet

Page 49: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 49 of 51

7. Now select INVOKE CLIENT V0.6, click on SEND You should have the API responding SUCCESS

8. Try again QUERY CLIENT V0.6, click on SEND You should have the API responding SUCCESS with message “42” because the client has been redeemed

Page 50: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 50 of 51

Page 51: Blockchain Hyperledger Lab

Getting Started With Hyperledger Fabric (Blockchain)

Page 51 of 51

CONGRATULATIONS !!! You have successfully invoked your chaincode and incremented the client account. You know can now:

• Change location parameters while invoking chaincode • Change the code adding begin and end date validity

checks • Plug another temperature feed from an external API

service or IoT device • Make the code more deterministic !

Correction links here :

https://github.com/zamrokk/JavaCDDNetwork https://github.com/zamrokk/JavaCDD https://github.com/zamrokk/JavaCDDWeb