Blockchain chaincode for Java developers
How to write chaincode for Hyperledger Fabric v0.6 using the Java language
You've probably heard about blockchain, but maybe you're not sure how it applies to you as a Java™ developer. This tutorial will clear up any confusion. In a step-by-step approach, I'll show you how to use the Hyperledger Fabric v0.6 to build, run, and execute smart contracts, or chaincode, written in the Java language. You'll install tools, define your local blockchain network, and finally, build and run a chaincode smart contract.
For an overview of blockchain, see "What is blockchain? A Primer on Distributed Ledger Technology" on the developerWorks blog.
Prerequisites
For this tutorial, I'll assume that you have the following prerequisites:
- You've heard of blockchain or the Hyperledger Fabric framework
- You have intermediate Java programming knowledge and experience with both the language and platform
- You are familiar with or (ideally) proficient in using:
- Eclipse IDE
- Docker and Docker Compose
- Gradle
- Linux command line
- SoapUI or another HTTP client software, such as Postman
You should also be comfortable installing software on your computer with minimal guidance. In the interest of space, I'm not including detailed installation instructions for all the software you need; the websites where you can obtain the software provide installation instructions.
Before we dive into the meat of the tutorial, I want to talk a little about blockchain.
Blockchain basics
A lot of hype surrounds blockchain, but it's well deserved. Not only is the technology itself cool, it's disruptive and has the potential to revolutionize the way business is done on the Internet.
How? Well, let's think about the fundamental attributes of a successful business deal:
- Trust: We have a deal, but can I really trust you to honor it (or you me)?
- Transparency: Allows a look "behind the curtain" (which can both build trust and lessen the need for it).
- Accountability: Defines criteria to determine whether or not all parties agree that the deal has been honored.
The health of any business relationship between two or more parties will mean varying levels of the three attributes above (for example, more trust means less transparency required, and vice versa), but some of all of them must be present, or there will be problems.
“Blockchain technology is rapidly making its way to a software development project near you. Will you be ready? ”
How does blockchain help? First of all, through the use of a common framework, business partners can establish an upfront network of trust. Then, through the use of a ledger that is visible to all business parties, blockchain provides transparency. Finally, through the use of consensus from all parties in the form of smart contracts (or chaincode), there is accountability.
So what does this mean for you as a Java developer?
The rapid growth of the Hyperledger community and the Hyperledger Fabric means that blockchain technology is rapidly making its way to a software development project near you. Will you be ready?
The blockchain technology landscape
Sometimes development technology can get in the way of solving the business problem. My main goal is in this tutorial is to show you how to write Java chaincode, so I've chosen the simplest development stack for that purpose.
That said, there are other choices for the components of the stack. For this tutorial, I'll use Docker as the network container environment, but another option is Vagrant with VirtualBox. If you've never used Vagrant, you should at least try it out.
Whereas Docker is a container environment, Vagrant uses virtualization. When combined with VirtualBox, a virtualization environment provides a different level of control over the computing environment that some developers prefer (which makes it an ideal choice for fabric developers).
If you want to learn more about containerization versus virtualization, check out "What is Docker? A Primer on the Benefits of Containers for Applications" on the developerWorks blog.
IBM® Bluemix® is a choice for developers who just want to write code and not have to worry about containers, virtualization, or any infrastructure, for that matter. And although Bluemix supports running a full IBM Blockchain network, it does not yet support chaincode development using the Java language. I expect this to change very soon, so stay tuned.
If you are getting the impression that the blockchain technology landscape is very fluid at the moment, you're correct. However, this means you're getting into blockchain and chaincode at just the right time: on the ground floor. As this technology matures, your investment in learning it at this early stage will pay handsome dividends down the road.
Blockchain is one of those disruptive technologies that has the potential to revolutionize the way everyone does business. Not just B2B, but B2C, and eventually C2C. This is a very exciting time, indeed.
Let's get started!
Set up your development environment
In order to run chaincode, you first need to set up your development environment.
Once you've completed this section, you'll be ready to run one of the Hyperledger Java chaincode examples, where you'll deploy and invoke transactions on real chaincode. After that, I'll show you how to write a new chaincode program from scratch (well, almost).
In this section you will:
- Set up the network environment — to run your local blockchain network.
- Install the build software — to build your chaincode.
- Install an HTTP client — to invoke transactions on your chaincode.
- Start the blockchain network.
- Build the Java shim client JAR.
I won't lie to you; there is quite a bit of setup work to be done in order to write chaincode. But if you follow these instructions and apply a little diligence, it will be worth it.
Set up the network environment
In this tutorial, you'll use Docker, along with pre-built blockchain network component images from Docker Hub, to run your local blockchain network. You could build the fabric from scratch if you wanted to (it's open source, after all), but at this stage, it's easier to use the pre-built Hyperledger Fabric images available in Docker Hub.
As I mentioned in the introduction, another option (and one you may see in the Hyperledger docs) is to use Vagrant and VirtualBox. Vagrant is a great choice for fabric developers, though as chaincode developers, we're more concerned with building, running, and testing our chaincode than working with the fabric itself.
If you already have Docker version 1.12 or higher installed, you can skip to the next section ("Install the build software") In the instructions that follow, I'll assume you do not have Docker installed (that is, you are not upgrading from a previous version of Docker). The Docker installation will also install Docker Compose, a tool for defining and running applications that require multiple containers, as the local Hyperledger blockchain network you will run in this tutorial does.
Install Docker
Installation instructions for Mac, Windows, and Linux can be found here:
Install Docker on Mac, Windows, and Linux
Verify Docker installation
To test your Docker installation, open a terminal window (or command prompt on Windows) and type the following commands:
docker -v
docker-compose -vYou should get output like this:
$ docker -v
Docker version 1.13.1, build 092cba3
$ docker-compose -v
docker-compose version 1.11.1, build 7c5d5e4If you want to see Docker in action, you can run the hello-world image like this:
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
78445dd45222: Pull complete
Digest: sha256:c5515758d4c5e1e838e9cd307f6c6a0d620b5e07e6f927b07d05f6d12a1ac8d7
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://cloud.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/Install the build software
For the build system, the Hyperledger Fabric uses Gradle, and you will use that for this tutorial as well. Gradle is a build automation system that combines simple syntax to specify build components, along with the best features of Apache Ant and Apache Maven to create a powerful build system that's easy to use. It's no wonder so many developers are switching their projects over to Gradle.
Read more about Gradle (and some of its high-profile users) on the Gradle main page.
Install Gradle
To install Gradle, follow the instructions here:
Install Gradle on Mac, Windows, and Linux
Verify Gradle installation
To verify your Gradle installation, open a terminal window and execute this command:
gradle -v
You should see output like this:
$ gradle -v
------------------------------------------------------------
Gradle 3.3
------------------------------------------------------------
Build time: 2017-01-03 15:31:04 UTC
Revision: 075893a3d0798c0c1f322899b41ceca82e4e134b
Groovy: 2.4.7
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_102 (Oracle Corporation 25.102-b14)
OS: Mac OS X 10.12.3 x86_64Install an HTTP client
Next up is the HTTP client software, which allows your chaincode to
communicate with the Hyperledger blockchain fabric's REST interface. Your
browser can issue an HTTP GET, but to interact with the
fabric you need to be able to POST messages. This means you
need an HTTP client.
The HTTP client I've chosen for this tutorial is SoapUI, which provides a free community edition that's powerful, easy to use, and contains many features.
Install SoapUI
To install SoapUI, follow the instructions here:
Install SoapUI for Mac OS, Windows, and Linux
Verify SoapUI installation
To verify that SoapUI is installed, start the application on your computer. On Mac OS, SoapUI should open to the SoapUI Starter Page, shown in Figure 1.
Figure 1. SoapUI on Mac OS X

Start the blockchain network
Now that you have installed the necessary software to develop and test your chaincode, it's time to start your local blockchain network. The first step is to define the network's configuration.
First, create a directory that will serve as the root of all of the source code you'll use for chaincode development. In this tutorial I'll use ~/home/mychaincode (or C:\home\chaincode on Windows).
Next, set the GOPATH environment variable to this path. We
won't be compiling any Go code, nor building Golang packages or other
binaries, but Golang terminology is baked into Hyperledger, so it's a good
idea to get comfortable with thinking in terms of the Go language and
GOPATH.
On Linux, you would execute this command:
export GOPATH=~/home/mychaincode
Or on Windows, you might use something like:
SET GOPATH=C:\home\mychaincode
Next, you must tell Docker Compose how to compose and run the blockchain
peer network. The definition of the network is in YAML, and you should name it
docker-compose.yml. You can call the file something else, but when you
start Docker Compose, you must specify the -f flag. I
recommend sticking with the default, which is docker-compose.yml.
Create the docker-compose.yml file in the root of your GOPATH.
Paste in the following contents:
membersrvc:
image: hyperledger/fabric-membersrvc
ports:
- "7054:7054"
command: membersrvc
vp0:
image: hyperledger/fabric-peer
ports:
- "7050:7050"
- "7051:7051"
- "7053:7053"
environment:
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_VM_ENDPOINT=unix:///var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=vp0
- 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
- CORE_SECURITY_ENROLLID=test_vp0
- CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT
links:
- membersrvc
command: sh -c "sleep 5; peer node start --peer-chaincodedev"There is a lot going on here, much of which is beyond the scope of this tutorial, but I want to explain a few things.
- This file tells Docker Compose to define two services:
membersrvc: The member services node that provides membership services, specifically a certificate authority (CA), which is responsible for handling all of the cryptographic logistics (such as issuing and revoking certificates). The pre-built Docker image you'll use for this is calledhyperledger/fabric-membersrvc.vp0: The lone validating peer node in the network. For development purposes, we don't need an extravagant validating peer network; a single peer will do. The pre-built Docker image you will use for this is calledhyperledger/fabric-peer.
- A number of environment variables are set by the vp0 peer. Notice the
CORE_LOGGING_LEVELvariable is set toDEBUG. This produces a large amount of output, which can be handy at times. However, if you want less output, change the level toINFO. See "Logging Control" in the Hyperledger Setup docs for more information about the logging levels.More information can be found about the Docker Compose YML file definition on Docker's website.
Next, notice that the CORE_SECURITY_ENABLED value is
false. This means the fabric will not require you to send any
type of end-user credentials. Security is beyond the scope of this
tutorial.
Finally, a word of caution: Changing any of these values from their defaults (especially the port values) may cause the examples in this tutorial to fail to work. A blockchain network is a set of distributed software components that require precisely coordinated communication. I highly recommend you do not change the port values from their default values until you understand how all the components of the fabric interoperate.
Now that the blockchain network definition is in place, you're ready to
start your local blockchain network. To do this, run Docker Compose.
Navigate to your $GOPATH and execute this command:
docker-compose up
You should get output in the terminal window like this:
$ docker-compose up
.
.
Pulling membersrvc (hyperledger/fabric-membersrvc:latest)...
latest: Pulling from hyperledger/fabric-membersrvc
.
.
Status: Downloaded newer image for hyperledger/fabric-membersrvc:latest
Pulling vp0 (hyperledger/fabric-peer:latest)...
latest: Pulling from hyperledger/fabric-peer
.
.
Status: Downloaded newer image for hyperledger/fabric-peer:latest
Creating mychaincode_membersrvc_1
Creating mychaincode_vp0_1
Attaching to mychaincode_membersrvc_1, mychaincode_vp0_1
vp0_1 | 19:30:03.773 [logging] LoggingInit -> DEBU 001 Setting default logging level to DEBUG for command 'node'
vp0_1 | 19:30:03.773 [nodeCmd] serve -> INFO 002 Running in chaincode development mode
.
.
.
vp0_1 | 19:30:04.146 [peer] chatWithSomePeers -> DEBU 07c Starting up the first peer of a new network
vp0_1 | 19:30:04.146 [consensus/statetransfer] verifyAndRecoverBlockchain -> DEBU 07d Validating existing blockchain, highest validated block is 0, valid through 0
vp0_1 | 19:30:04.146 [consensus/statetransfer] blockThread -> INFO 07e Validated blockchain to the genesis block
vp0_1 | 19:30:04.146 [consensus/handler] 1 -> DEBU 07f Starting up message thread for consenter
vp0_1 | 19:30:04.146 [nodeCmd] serve -> INFO 080 Starting peer with ID=name:"vp0" , network ID=dev, address=172.17.0.3:7051, rootnodes=, validator=true
vp0_1 | 19:30:04.146 [rest] StartOpenchainRESTServer -> INFO 081 Initializing the REST service on 0.0.0.0:7050, TLS is disabled.
vp0_1 | 19:30:04.147 [peer] ensureConnected -> DEBU 082 Starting Peer reconnect service (touch service), with period = 6s
.
.This output tells you the network is up and running, and ready to accept chaincode registration requests.
Note: The highlighted lines should only appear the first time you run your blockchain network, because Docker has to download the images from Docker Hub. Once they are downloaded to your computer, Docker will only pull them if the images from Docker Hub are newer than the ones you have on your computer.
Now you're ready to build the Java shim client JAR, which allows your Java language chaincode to communicate with the Hyperledger Fabric framework.
Build the Java shim client JAR
Before you can run the chaincode examples, you need to get the latest source code from Hyperledger's GitHub repository.
First, you will need to clone the Hyperledger Fabric on your local machine in order to build your chaincode (Note: This is a temporary measure; at some point the Java shim client JAR should be accessible from the central Maven repository).
Note: Recall from earlier that you set your
GOPATH to ~/home/mychaincode on Linux (or Mac) or
C:\home\mychaincode on Windows.
Execute this command to create the directory structure the fabric build scripts expect:
mkdir -p $GOPATH/src/github.com/hyperledger
Next, navigate to the bottom of the new directory structure you created:
cd $GOPATH/src/github.com/hyperledger
From here you need to retrieve the Hyperledger source code so you can build the Java shim client JAR.
There are two ways to access the Hyperledger source.
- Without git:
Navigate to the Hyperledger GitHub mirror and click on the Clone or download button, then Download ZIP (see Figure 2). A ZIP file called fabric-master.zip will be downloaded to your computer, which you can extract to
$GOPATH/src/github.com/hyperledger. Note: make sure to change the name of the root directory from fabric-master to fabric when you extract the file. - With git:
Navigate to
$GOPATH/src/github.com/hyperledger, copy the URL from the text field in the "Clone with HTTPS" box (see Figure 2), and execute this command using the copied URL:
git clone https://github.com/hyperledger/fabric.git -b v0.6
You should see terminal window output like this from the git
command:
$ git clone https://github.com/hyperledger/fabric.git -b v0.6
Cloning into 'fabric'...
remote: Counting objects: 29272, done.
remote: Compressing objects: 100% (128/128), done.
remote: Total 29272 (delta 55), reused 0 (delta 0), pack-reused 29142
Receiving objects: 100% (29272/29272), 44.95 MiB | 5.67 MiB/s, done.
Resolving deltas: 100% (16671/16671), done.Figure 2. Hyperledger GitHub mirror

Now you're ready to build the Java chaincode shim client JAR. Navigate to
$GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java
and run these two commands:
gradle -b build.gradle clean
gradle -b build.gradle buildThe Gradle build output should look like this:
$ cd $GOPATH/src/github.com/hyperledger/fabric/core/chaincode/shim/java
$ gradle -b build.gradle clean
Starting a Gradle Daemon (subsequent builds will be faster)
:core:chaincode:shim:java:clean
BUILD SUCCESSFUL
Total time: 5.422 secs
$ gradle -b build.gradle build
:core:chaincode:shim:java:copyProtos UP-TO-DATE
:core:chaincode:shim:java:extractIncludeProto
:core:chaincode:shim:java:extractProto UP-TO-DATE
:core:chaincode:shim:java:generateProto UP-TO-DATE
:core:chaincode:shim:java:compileJava
:core:chaincode:shim:java:processResources
:core:chaincode:shim:java:classes
:core:chaincode:shim:java:jar
:core:chaincode:shim:java:assemble
:core:chaincode:shim:java:extractIncludeTestProto
:core:chaincode:shim:java:extractTestProto UP-TO-DATE
:core:chaincode:shim:java:generateTestProto UP-TO-DATE
:core:chaincode:shim:java:compileTestJava UP-TO-DATE
:core:chaincode:shim:java:processTestResources UP-TO-DATE
:core:chaincode:shim:java:testClasses UP-TO-DATE
:core:chaincode:shim:java:test UP-TO-DATE
:core:chaincode:shim:java:check UP-TO-DATE
:core:chaincode:shim:java:build
:core:chaincode:shim:java:copyToLib
:core:chaincode:shim:java:generatePomFileForMavenJavaPublication
:core:chaincode:shim:java:publishMavenJavaPublicationToMavenLocal
:core:chaincode:shim:java:publishToMavenLocal
BUILD SUCCESSFUL
Total time: 4.521 secsThe last thing the build does is add the shim client JAR to your local Maven repository. At this point, you're ready to build your chaincode. Unless you update your fabric source code at some point in the future, or just want to rebuild the shim client JAR again for some reason, you won't have to run the Java shim client JAR build again.
Deploy and run a Java chaincode example
Now that you've defined and started your local blockchain network, and have built and installed the Java shim client JAR to your local Maven repository, you're ready to build, register, and invoke transactions on one of the Java chaincode examples that ship with the Hyperledger Fabric that you downloaded earlier.
Here are the steps you'll follow:
- Build the example using Gradle.
- Register the example with the validating peer network, by running a script that is created for you by the Gradle build.
- Deploy the example to the local blockchain network using SoapUI.
- Invoke transactions on the example chaincode using SoapUI.
Build the example
Navigate to the
$GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example
directory.
Next, launch the Gradle build via the command line using this command:
gradle -b build.gradle build
You should see output like this:
$ cd GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example
$ gradle -b build.gradle build
Starting a Gradle Daemon (subsequent builds will be faster)
:examples:chaincode:java:Example:compileJava
:examples:chaincode:java:Example:processResources UP-TO-DATE
:examples:chaincode:java:Example:classes
:examples:chaincode:java:Example:jar
:examples:chaincode:java:Example:startScripts
:examples:chaincode:java:Example:distTar
:examples:chaincode:java:Example:distZip
:examples:chaincode:java:Example:assemble
:examples:chaincode:java:Example:compileTestJava UP-TO-DATE
:examples:chaincode:java:Example:processTestResources UP-TO-DATE
:examples:chaincode:java:Example:testClasses UP-TO-DATE
:examples:chaincode:java:Example:test UP-TO-DATE
:examples:chaincode:java:Example:check UP-TO-DATE
:examples:chaincode:java:Example:build
:examples:chaincode:java:Example:copyToLib
BUILD SUCCESSFUL
Total time: 6.935 secsThe build creates a standalone distribution that's located within the directory build/distributions in two forms: a TAR file and a ZIP file, and each of these files contains everything you need to run the chaincode, including a script to drive it called Example.
The Example chaincode is now ready to be registered with the local blockchain network.
Register the example
Make sure your local blockchain network is running. If not, you'll need to start it up. See the section titled "Start the blockchain network" if you need a refresher.
If you're not already there, navigate to
$GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example.
Next, extract Example.zip (or Example.tar) in the build/distributions directory:
$ cd $GOPATH/src/github.com/hyperledger/fabric/examples/chaincode/java/Example
$ cd build/distributions/
$ unzip Example.zip
Archive: Example.zip
inflating: Example/lib/chaincode.jar
inflating: Example/lib/grpc-all-0.13.2.jar
inflating: Example/lib/commons-cli-1.3.1.jar
inflating: Example/lib/shim-client-1.0.jar
inflating: Example/lib/grpc-netty-0.13.2.jar
inflating: Example/lib/grpc-auth-0.13.2.jar
inflating: Example/lib/grpc-protobuf-nano-0.13.2.jar
inflating: Example/lib/grpc-core-0.13.2.jar
inflating: Example/lib/grpc-protobuf-0.13.2.jar
inflating: Example/lib/grpc-okhttp-0.13.2.jar
inflating: Example/lib/grpc-stub-0.13.2.jar
inflating: Example/lib/protobuf-java-3.0.0.jar
inflating: Example/lib/netty-tcnative-boringssl-static-1.1.33.Fork21-osx-x86_64.jar
inflating: Example/lib/netty-codec-http2-4.1.0.CR3.jar
inflating: Example/lib/google-auth-library-oauth2-http-0.3.0.jar
inflating: Example/lib/guava-18.0.jar
inflating: Example/lib/protobuf-javanano-3.0.0-alpha-5.jar
inflating: Example/lib/jsr305-3.0.0.jar
inflating: Example/lib/okio-1.6.0.jar
inflating: Example/lib/okhttp-2.5.0.jar
inflating: Example/lib/netty-codec-http-4.1.0.CR3.jar
inflating: Example/lib/netty-handler-4.1.0.CR3.jar
inflating: Example/lib/google-auth-library-credentials-0.3.0.jar
inflating: Example/lib/google-http-client-1.19.0.jar
inflating: Example/lib/google-http-client-jackson2-1.19.0.jar
inflating: Example/lib/netty-codec-4.1.0.CR3.jar
inflating: Example/lib/netty-buffer-4.1.0.CR3.jar
inflating: Example/lib/netty-transport-4.1.0.CR3.jar
inflating: Example/lib/httpclient-4.0.1.jar
inflating: Example/lib/jackson-core-2.1.3.jar
inflating: Example/lib/netty-common-4.1.0.CR3.jar
inflating: Example/lib/netty-resolver-4.1.0.CR3.jar
inflating: Example/lib/httpcore-4.0.1.jar
inflating: Example/lib/commons-logging-1.1.1.jar
inflating: Example/lib/commons-codec-1.3.jar
inflating: Example/bin/Example
inflating: Example/bin/Example.bat"Why so many files?" you may wonder. The distribution contains everything you need to run the chaincode standalone (in its own process), along with all dependent JARs.
To register the chaincode example, within the build/distributions folder, execute the following script:
./Example/bin/Example
This runs a standalone process that registers the chaincode example with the local blockchain network. You should see terminal window output like this:
$ ./Example/bin/Example
Hello world! starting [Ljava.lang.String;@7ef20235
Feb 22, 2017 10:05:08 AM example.Example main
INFO: starting
Feb 22, 2017 10:05:08 AM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 22, 2017 10:05:08 AM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@3dd7b80b(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 22, 2017 10:05:14 AM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@3dd7b80b(/127.0.0.1:7051) for /127.0.0.1:7051 is readyTake a look at the console for your local blockchain network, and you should see lines of output that look like this:
.
.
vp0_1 | 16:05:14.048 [chaincode] HandleChaincodeStream -> DEBU 06d Current context deadline = 0001-01-01 00:00:00 +0000 UTC, ok = false
vp0_1 | 16:05:14.065 [chaincode] processStream -> DEBU 06e []Received message REGISTER from shim
vp0_1 | 16:05:14.065 [chaincode] HandleMessage -> DEBU 06f []Handling ChaincodeMessage of type: REGISTER in state created
vp0_1 | 16:05:14.065 [chaincode] beforeRegisterEvent -> DEBU 070 Received REGISTER in state created
vp0_1 | 16:05:14.065 [chaincode] registerHandler -> DEBU 071 registered handler complete for chaincode hello
vp0_1 | 16:05:14.065 [chaincode] beforeRegisterEvent -> DEBU 072 Got REGISTER for chaincodeID = name:"hello" , sending back REGISTERED
.
.Make a note of the chaincodeID name in the registration log
output (hello for the Example; see line 8 in
the preceding). You'll need that later for the JSON message when you
deploy the Example chaincode through the fabric's REST interface.
The preceding output indicates that the Example chaincode is running and has been registered with the local blockchain validating peer network, and is ready to be deployed.
Deploy the example
The Hyperledger Fabric provides a REST web service interface that you use to interact with the fabric. The first interaction with the fabric is to deploy your chaincode. Make sure your local blockchain network is running, then start SoapUI, and click the REST button to create a new REST project. You should see a dialog box like Figure 3, where you enter the based URL used for all REST requests:
Figure 3. SoapUI New REST project dialog

Enter http://localhost:7050 as the URL, then click
OK. Port 7050 is the default REST port
used by the fabric, and since your blockchain network is running on your
local computer, you will use localhost as the host name.
When SoapUI comes up, you can do a quick smoke test to make sure it can
communicate with your local blockchain network. Expand the new REST
resource you just created until you see Request 1, then open
it in the Editor window. Use GET for the method, and under
resource enter /chain. Make sure to
click the JSON option on the output tab, then run the
request (by clicking on the arrow icon). When you execute
this request, it simply returns the current block hash in the output tab,
located on the right-hand side of the editor window, as you can see in
Figure 4:
Figure 4. Blockchain smoke test

If you see a JSON message that looks similar to the one in Figure 4 (the
currentBlockHash value for your network will be different, of
course), then you're ready to deploy the Example chaincode.
Right-click on the endpoint under
REST Project 1 (http://localhost:7050) and choose New
Resource; you should see a "New REST Resource" dialog box
(see Figure 5) with a Resource Path field:
Figure 5. SoapUI New Resource dialog

Enter /chaincode as the resource path,
then click OK, and you should see the new resource show
up in your SoapUI Projects panel. Open up the request for this resource
(by default it will be called Request 1), change the
method to POST, and paste this JSON into the request area,
located in the lower left corner of the request editor window:
{
"jsonrpc": "2.0",
"method": "deploy",
"params": {
"type": 1,
"chaincodeID":{
"name": "hello"
},
"CtorMsg": {
"args": [""]
}
},
"id": 1
}Three things to note:
- Line 3: The method value must be
deploy. - Lines 6-7: The
chaincodeID.namein the JSON message must match thechaincodeIDwhen you registered the Example chaincode in the previous section (hellofor the Example chaincode). - Line 13: The
idvalue is used to coordinate requests. You don't need to worry about it so much for this tutorial, but notice that it is always sent back on the response (see the next listing).
When you submit this request, the JSON output should look like this:
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "hello"
},
"id": 1
}Figure 6 shows a screenshot of what this looks like in SoapUI. The JSON output message will appear in the output tab, which is located on the right-hand side of the request editor.
Figure 6. SoapUI Chaincode deploy request

The network log output in the terminal window should include lines that look like this:
.
.
vp0_1 | 20:48:39.482 [rest] ProcessChaincode -> INFO 0c4 REST processing chaincode request...
vp0_1 | 20:48:39.482 [rest] processChaincodeDeploy -> INFO 0c5 REST deploying chaincode...
vp0_1 | 20:48:39.483 [devops] Deploy -> DEBU 0c6 Creating deployment transaction (hello)
vp0_1 | 20:48:39.483 [devops] Deploy -> DEBU 0c7 Sending deploy transaction (hello) to validator
vp0_1 | 20:48:39.483 [peer] sendTransactionsToLocalEngine -> DEBU 0c8 Marshalling transaction CHAINCODE_DEPLOY to send to local engine
vp0_1 | 20:48:39.483 [peer] sendTransactionsToLocalEngine -> DEBU 0c9 Sending message CHAIN_TRANSACTION with timestamp seconds:1487796519 nanos:483661510 to local engine
vp0_1 | 20:48:39.483 [consensus/noops] RecvMsg -> DEBU 0ca Handling Message of type: CHAIN_TRANSACTION
vp0_1 | 20:48:39.483 [consensus/noops] broadcastConsensusMsg -> DEBU 0cb Broadcasting CONSENSUS
vp0_1 | 20:48:39.483 [peer] Broadcast -> DEBU 0cc Broadcast took 1.135s
vp0_1 | 20:48:39.483 [consensus/noops] RecvMsg -> DEBU 0cd Sending to channel tx uuid: hello
vp0_1 | 20:48:39.483 [rest] processChaincodeDeploy -> INFO 0ce Successfully deployed chainCode: hello
vp0_1 | 20:48:39.484 [rest] ProcessChaincode -> INFO 0cf REST successfully deploy chaincode: {"jsonrpc":"2.0","result":{"status":"OK","message":"hello"},"id":1}
.
.Lines 3-4 show the output indicating the network has received the deploy message and the fabric is deploying your chaincode. Lines 13-14 show that your chaincode has been deployed successfully.
Take note of output like this in the terminal window running your chaincode:
$ ./build/distributions/Example/bin/Example
Hello world! starting [Ljava.lang.String;@7ef20235
Feb 22, 2017 2:44:43 PM example.Example main
INFO: starting
Feb 22, 2017 2:44:43 PM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 22, 2017 2:44:43 PM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@46adccd3(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 22, 2017 2:44:48 PM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@46adccd3(/127.0.0.1:7051) for /127.0.0.1:7051 is ready
Feb 22, 2017 2:48:40 PM example.Example run
INFO: In run, function:
Feb 22, 2017 2:48:40 PM example.Example runI've included all of the output for context, and you should see lines like 11-13 when you send the deploy message to your blockchain network.
Invoke a transaction on the example
Finally, you will invoke the hello method and watch it show up
in the log messages of the terminal window running your chaincode.
Under the chaincode resource in SoapUI, right-click on
Method 1 and choose Clone Method.
Call the method Invoke, and click OK. Open
Request 1 under your new Invoke method
and paste in this JSON request:
{
"jsonrpc": "2.0",
"method": "invoke",
"params": {
"type": 1,
"chaincodeID":{
"name": "hello"
},
"CtorMsg": {
"args": ["hello"]
}
},
"id": 2
}When you run the request, you should see this JSON response:
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "1c1811d0-a958-4c58-ab1d-e1df550c18a3"
},
"id": 2
}Figure 7 shows a screenshot of what this looks like in SoapUI.
Figure 7. SoapUI Chaincode invoke request

The network log output should include lines that look like this:
.
.
vp0_1 | 21:44:35.143 [rest] ProcessChaincode -> INFO 555 REST processing chaincode request...
vp0_1 | 21:44:35.143 [rest] processChaincodeInvokeOrQuery -> INFO 556 REST invoke chaincode...
vp0_1 | 21:44:35.143 [devops] invokeOrQuery -> INFO 557 Transaction ID: 1c1811d0-a958-4c58-ab1d-e1df550c18a3
vp0_1 | 21:44:35.143 [devops] createExecTx -> DEBU 558 Creating invocation transaction (1c1811d0-a958-4c58-ab1d-e1df550c18a3)
vp0_1 | 21:44:35.143 [devops] invokeOrQuery -> DEBU 559 Sending invocation transaction (1c1811d0-a958-4c58-ab1d-e1df550c18a3) to validator
vp0_1 | 21:44:35.143 [peer] sendTransactionsToLocalEngine -> DEBU 55a Marshalling transaction CHAINCODE_INVOKE to send to local engine
vp0_1 | 21:44:35.143 [peer] sendTransactionsToLocalEngine -> DEBU 55b Sending message CHAIN_TRANSACTION with timestamp seconds:1487799875 nanos:143438691 to local engine
vp0_1 | 21:44:35.143 [consensus/noops] RecvMsg -> DEBU 55c Handling Message of type: CHAIN_TRANSACTION
vp0_1 | 21:44:35.143 [consensus/noops] broadcastConsensusMsg -> DEBU 55d Broadcasting CONSENSUS
vp0_1 | 21:44:35.143 [peer] Broadcast -> DEBU 55e Broadcast took 1.249s
vp0_1 | 21:44:35.143 [consensus/noops] RecvMsg -> DEBU 55f Sending to channel tx uuid: 1c1811d0-a958-4c58-ab1d-e1df550c18a3
vp0_1 | 21:44:35.143 [rest] processChaincodeInvokeOrQuery -> INFO 560 Successfully submitted invoke transaction with txid (1c1811d0-a958-4c58-ab1d-e1df550c18a3)
vp0_1 | 21:44:35.143 [rest] ProcessChaincode -> INFO 561 REST successfully submitted invoke transaction: {"jsonrpc":"2.0","result":{"status":"OK","message":"1c1811d0-a958-4c58-ab1d-e1df550c18a3"},"id":2}
.
.And the chaincode log output like this:
$ ./build/distributions/Example/bin/Example
Hello world! starting [Ljava.lang.String;@7ef20235
Feb 22, 2017 3:26:57 PM example.Example main
INFO: starting
Feb 22, 2017 3:26:57 PM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 22, 2017 3:26:57 PM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@765e4953(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 22, 2017 3:27:02 PM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@765e4953(/127.0.0.1:7051) for /127.0.0.1:7051 is ready
Feb 22, 2017 3:27:24 PM example.Example run
INFO: In run, function:
Feb 22, 2017 3:27:24 PM example.Example run
SEVERE: No matching case for function:
Feb 22, 2017 3:30:55 PM example.Example run
INFO: In run, function:hello
hello invokedOnce again, I've shown all the chaincode output. You can see where the
hello function was invoked (line 16).
Now you've seen how to build, deploy, and run Java chaincode on your local blockchain network. In the next section, you'll write a chaincode program (almost) from scratch using the Eclipse IDE, build the chaincode program using Gradle, and exercise it using SoapUI.
Write your first Java chaincode program
In the previous section, you got familiar with how to build, run, deploy, and invoke chaincode, but you haven't yet written any Java code.
In this section, you'll use the Eclipse IDE, a plugin for Gradle that works with Eclipse, and a skeleton Java chaincode project called ChaincodeTutorial to write your first Java chaincode program. You'll get the skeleton code from a GitHub repo I created for this tutorial, import that code into Eclipse, add code to make the chaincode smart contract function according to the requirements, and build that code using Gradle from within your Eclipse IDE.
Here are the steps you'll follow:
- Install the Gradle Buildship plugin for Eclipse.
- Clone the ChaincodeTutorial project from GitHub.
- Import the project into Eclipse.
- Explore the chaincode skeleton project.
- Write the Java chaincode.
- Build the Java chaincode.
When you've completed this section, your chaincode will be ready to run on your local blockchain network.
Install the Gradle Buildship plugin for Eclipse
You can use any IDE you like, but the instructions in this tutorial are for Eclipse. Note: The Buildship Gradle plugin helps integrate Gradle with Eclipse, but you will still need to have installed Gradle on your computer.
If you've been following along with the tutorial, you should already have Gradle installed on your computer; if it's not installed, do that now. Refer to the "Install the build software" section to see how to install Gradle on your computer.
To install the Buildship Gradle plugin for Eclipse, which helps your Gradle installation work with Eclipse, within Eclipse, go to Help > Eclipse Marketplace... In the Eclipse Marketplace dialog, enter buildship in the Find text field and click the Go button. You should see something like Figure 8, showing the Buildship Gradle Integration 2.0 plugin as the first result of the search:
Figure 8. Eclipse Marketplace: Gradle Buildship plugin

Under Buildship Gradle Integration, click the Install button and follow the prompts. When you click Finish, the Buildship Gradle plugin for Eclipse will be installed, and you'll be asked to restart Eclipse.
When Eclipse reopens, Gradle should be fully integrated with your Eclipse IDE. You are now ready to clone the ChaincodeTutorial repository from GitHub.
Clone the ChaincodeTutorial project from GitHub
Now that you have your Eclipse IDE configured to work with Gradle, you will
clone the ChaincodeTutorial code from GitHub and import the code into
Eclipse. Open a command prompt or terminal window, navigate to your
$GOPATH, and execute this command:
git clone https://github.com/makotogo/ChaincodeTutorial.git
Your command output should look something like this:
$ export GOPATH=/Users/sperry/home/mychaincode
$ cd $GOPATH
$ git clone https://github.com/makotogo/ChaincodeTutorial.git
Cloning into 'ChaincodeTutorial'...
remote: Counting objects: 133, done.
remote: Compressing objects: 100% (90/90), done.
remote: Total 133 (delta 16), reused 118 (delta 1), pack-reused 0
Receiving objects: 100% (133/133), 9.39 MiB | 1.95 MiB/s, done.
Resolving deltas: 100% (16/16), done.
$ cd ChaincodeTutorial
$ pwd
/Users/sperry/home/mychaincode/ChaincodeTutorialThis command clones the Blockchain ChaincodeTutorial repo from GitHub to
your $GOPATH. It consists of a skeleton Java chaincode
project you can build, run, and experiment with in your local blockchain
network.
But before you can do any of that, you need to import the code into Eclipse.
Import the project into Eclipse
In Eclipse, go to File > Import... > Gradle > Existing Gradle project. A wizard dialog box should open (see Figure 9).
Figure 9. Eclipse Import Wizard: Gradle Project

Click Next. On the dialog box that comes up next in the
wizard (see Figure 10), browse to $GOPATH/ChaincodeTutorial,
and click Finish to import the project.
Figure 10. Eclipse Import Wizard: Gradle Project (Project root directory)

When the project has finished importing, make sure to select the Java Perspective, and the ChaincodeTutorial project you just imported will show up in the Project Explorer view.
Now that you have the code imported into your Eclipse workspace, you are ready to write your chaincode.
Explore the chaincode skeleton project
In this section you'll explore the chaincode project so you understand how it is supposed to function before you write any Java code.
As developers, we love to write code, so I don't want to deprive you of the opportunity to write Java code. However, the project setup can be complex, and I don't want that to get in the way of the main point of this tutorial. To that end, I've provided most of the code you will need.
Before you jump in, let's take a quick look at the base class, called
AbstractChaincode, which is located in the
com.makotojava.learn.blockchain.chaincode package, and shown
in Listing 1.
Listing 1. The AbstractChaincode
class
package com.makotojava.learn.blockchain.chaincode;
import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperledger.java.shim.ChaincodeBase;
import org.hyperledger.java.shim.ChaincodeStub;
public abstract class AbstractChaincode extends ChaincodeBase {
private static final Log log = LogFactory.getLog(AbstractChaincode.class);
public static final String FUNCTION_INIT = "init";
public static final String FUNCTION_QUERY = "query";
protected abstract String handleInit(ChaincodeStub stub, String[] args);
protected abstract String handleQuery(ChaincodeStub stub, String[] args);
protected abstract String handleOther(ChaincodeStub stub, String function, String[] args);
@Override
public String run(ChaincodeStub stub, String function, String[] args) {
String ret;
log.info("Greetings from run(): function -> " + function + " | args -> " + Arrays.toString(args));
switch (function) {
case FUNCTION_INIT:
ret = handleInit(stub, args);
break;
case FUNCTION_QUERY:
ret = handleQuery(stub, args);
default:
ret = handleOther(stub, function, args);
break;
}
return ret;
}
@Override
public String query(ChaincodeStub stub, String function, String[] args) {
return handleQuery(stub, args);
}
}The first thing I want to point out is that AbstractChaincode
is a subclass of ChaincodeBase, which is from the fabric shim
client (lines 7, 10).
Lines 17-19 show the methods you need to implement in the
ChaincodeLog class (which is a subclass of
AbstractChaincode) to handle the initialization, ledger
query, and log functions, respectively.
Lines 22-36 show the run() method of the
ChaincodeBase class (from the chaincode shim client), where
we figure out what function has been invoked and to which handler the call
should be delegated. The class is extensible in that any other functions
than init and query (such as the
log function) are handled by handleOther(),
which you must also implement.
Now, open the ChaincodeLog class in the
com.makotojava.learn.blockchain.chaincode package.
I've provided only a skeleton for you to flesh out — that is, I've provided just enough code so that it compiles. You'll have to write the rest of the code. You should run the JUnit tests and see that they fail (because you haven't written the implementation yet), and why. In other words, you can use the JUnit tests as a guide for properly implementing the code.
Now, if this feels a little over your head, don't worry; I've provided the
solution, which is located in
com.makotojava.learn.blockchain.chaincode.solution, in case
you get stuck (or if you just want a reference to guide you through the
implementation).
Write the Java chaincode
First, a little background on what you need to know in order to implement
the chaincode methods in ChaincodeLog. The
ChaincodeStub class is how your Java chaincode communicates
with the Hyperledger Fabric framework, and recall that the ledger is at
the core of the transparency aspect of blockchain technology. What makes a
smart contract (accountability) work is the state of the ledger, and your
chaincode accesses the ledger's state through the
ChaincodeStub. By accessing the ledger state, you're able to
implement a smart contract (a.k.a., chaincode).
There are a number of methods on ChaincodeStub that allow you
to store, retrieve, and remove items from the ledger's current state, but
I'll limit our discussion in this tutorial to two methods, which store and
retrieve the ledger state:
putState(String key, String value)— Stores the
specified state value in the ledger, mapped according to
the specified key.
getState()— Gets the state value
associated with the specified key and returns it as a
String
When writing the code for this tutorial, you will use the
putState() and getState() functions whenever you
need to store or retrieve state values from the ledger, respectively. The
ChaincodeLog class only stores and retrieves values from the
ledger to implement its smart contract, so this is all you need to know to
implement the methods. More complicated chaincode would make use of some
of the other methods in ChaincodeStub (but those are also
beyond the scope of this tutorial).
I'm a big fan of test-driven development (TDD), so in TDD fashion, I've written the unit tests first. Go ahead and run them and watch them fail. After that, you'll write code that follows the specifications until the unit tests pass. The job of the unit tests is to ensure the expected behavior, and by studying the unit tests, you should have enough information to implement the methods.
However, I have also written javadoc comments at the top of each method
that might help (in case you're new to TDD or JUnit). Between the code in
the JUnit tests and the javadoc comments in the skeleton
ChaincodeLog, you should have everything you need to
implement the chaincode after you complete this section of the
tutorial.
From the Project Explorer view (in the Java perspective) navigate to the
ChaincodeLogTest class, right-click on it and choose
Run As > Gradle Test. When it runs, you should see
something like Figure 11, showing the tree of all Gradle tasks that ran.
Tasks that completed successfully are indicated with check marks next to
them.
Figure 11. Eclipse: Gradle Executions view

The exclamation icons in the Gradle Executions tab indicate the Gradle tasks corresponding to the unit tests that failed (there are four and they all failed, just as we expected).
Because of the way I've written the JUnit test cases, each test method
corresponds to a method in ChaincodeLog that you'll have to
correctly implement as part of this tutorial.
Implement getChaincodeID()
First, you need to implement getChaincodeID(). Its contract is
to return the unique identifier for your chaincode. I've defined a
constant called CHAINCODE_ID at the top of the
ChaincodeLog class that you should use. Feel free to change
its value, but if you change the chaincode id returned by
getChaincodeID(), make sure it is unique within your network,
and don't forget to change the ChaincodeID.name attribute of
your JSON messages as well.
/**
* Returns the unique chaincode ID for this chaincode program.
*/
@Override
public String getChaincodeID() {
return null;// ADD YOUR CODE HERE
}Exercise: Complete the getChaincodeID()
method. If you need a reference, look in the
com.makotojava.learn.blockchain.chaincode.solution
package.
Implement handleInit()
Next, implement the handleInit() method. Its contract is to
handle initializing your chaincode program, which in this case means that
it will add a message (specified by the caller) to the ledger and return
that message to the caller if the call succeeds.
/**
* Handles initializing this chaincode program.
*
* Caller expects this method to:
*
* 1. Use args[0] as the key for logging.
* 2. Use args[1] as the log message.
* 3. Return the logged message.
*/
@Override
protected String handleInit(ChaincodeStub stub, String[] args) {
return null;// ADD YOUR CODE HERE
}Exercise: Complete the handieInit() method.
If you need a reference, look in the
com.makotojava.learn.blockchain.chaincode.solution
package.
Implement handleQuery()
Next up is the handleQuery() method. Its contract is to query
the ledger, which it does by taking the specified key(s), querying the
ledger for the value(s) that matches the key(s), and returning the
value(s) to the caller. If multiple keys are specified, the values that
are returned should be separated by commas.
/**
* Handles querying the ledger.
*
* Caller expects this method to:
*
* 1. Use args[0] as the key for ledger query.
* 2. Return the ledger value matching the specified key
* (which should be the message that was logged using that key).
*/
@Override
protected String handleQuery(ChaincodeStub stub, String[] args) {
return null;// ADD YOUR CODE HERE
}Be sure to write code to output the results of the query call, so you can see the results in the console output (take a peek at the solution if you want to see how I did it).
Exercise: Complete the handleQuery() method.
If you need a reference, look in the
com.makotojava.learn.blockchain.chaincode.solution
package.
Implement handleOther()
Finally, you need to implement the handleOther() method, whose
contract is to handle other messages (which is pretty wide open, but
that's why it's extensible). This is where you will implement the
log function, whose contract is to add a message specified by
the caller to the ledger, and return that message to the caller if the
call was successful. This looks very similar to what happens in the
init function, so perhaps you could leverage that in your
implementation.
/**
* Handles other methods applied to the ledger.
* Currently, that functionality is limited to these functions:
* - log
*
* Caller expects this method to:
* Use args[0] as the key for logging.
* Use args[1] as the log message.
* Return the logged message.
*/
@Override
protected String handleOther(ChaincodeStub stub, String function, String[] args) {
// TODO Auto-generated method stub
return null;// ADD YOUR CODE HERE
}Exercise: Complete the handleOther() method.
If you need a reference, look in the
com.makotojava.learn.blockchain.chaincode.solution
package.
If the code you wrote for each of the preceding exercises meets the requirements as I've laid them out in this section (and in the code comments), then your JUnit tests should all pass, and your chaincode should work fine when it is deployed and running in your local blockchain network.
Remember, I've provided a solution in case you get stuck (but you owe it to yourself to try to implement the methods on your own before peeking at the solution).
Build the Java chaincode
Now that you've written your Java chaincode and all your JUnit tests pass, it's time for you to build your chaincode using Eclipse and the Gradle Buildship plugin for Eclipse. Pull up the Gradle Tasks view by going to Window > Show View > Other... then search for gradle, select Gradle Tasks, and click OK. (See Figure 12.)
Figure 12. Eclipse: Show View: Gradle Tasks view

When the Gradle Tasks view opens, expand the ChaincodeTutorial > build node, and select build and clean. (See Figure 13.)
Figure 13. Eclipse: Gradle Tasks view

Right-click on build and clean, then choose Run Gradle Tasks (Gradle will figure out the correct order to run these). Your Gradle Executions view should show a clean build, as shown in Figure 14, where you have only check marks next to each item.
Figure 14. Eclipse: Gradle Executions view: clean build

When the build finishes, you should have a directory immediately
subordinate to your $GOPATH/ChaincodeTutorial directory
(where you cloned the code from GitHub earlier) called
build/distributions that contains your chaincode (this should
look familiar, as you did this earlier in the tutorial for the hello
example).
Now that you have built your Java chaincode, you are ready to deploy, run, and invoke transactions on it in your local blockchain network.
Deploy and run your Java chaincode
In this section, you will start and register your chaincode, deploy it, and invoke transactions on it via the Hyperledger Fabric REST interface, as you did earlier in the tutorial with the hello example. Make sure your local blockchain is running (see the section, "Start the blockchain network" for a refresher on this).
Here are the steps you will follow:
- Register your Java chaincode.
- Deploy your Java chaincode.
- Invoke transactions on your Java chaincode.
Register your Java chaincode
You will need to extract the build/distributions/ChaincodeTutorial.zip file and run the chaincode script, exactly as you did earlier in this tutorial when running the hello example (see the section, "Register the example").
When you run the ChaincodeTutorial script, the output should look something like this:
$ ./ChaincodeTutorial/bin/ChaincodeTutorial
Feb 28, 2017 4:18:16 PM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 28, 2017 4:18:16 PM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@10bf86d3(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 28, 2017 4:18:21 PM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@10bf86d3(/127.0.0.1:7051) for /127.0.0.1:7051 is readyNow your Java chaincode is registered with your local blockchain network, and you're ready to deploy and test your chaincode.
Deploy your Java chaincode
As you did with the hello example chaincode, you will use the fabric's REST interface to deploy and invoke transactions on your Java chaincode.
Open SoapUI. If you are comfortable doing so, you can create a new REST
project and all of its requests yourself, or you can import the SoapUI
REST project that I have included in the GitHub project you cloned
earlier. The SoapUI project is located in the
$GOPATH/ChaincodeTutorial directory.
To deploy your chaincode, navigate to the ChaincodeLog Deploy
request, as shown in Figure 15, and submit the request.
Figure 15. SoapUI: ChaincodeLog Deploy request

If you are not using the SoapUI project from GitHub (or are using a different HTTP client), the JSON request you should submit looks like this:
{
"jsonrpc": "2.0",
"method": "deploy",
"params": {
"type": 4,
"chaincodeID":{
"name": "ChaincodeLogSmartContract"
},
"ctorMsg": {
"args": ["init", "KEY-1", "Chaincode Initialized"]
}
},
"id": 1
}Submit the request. If it succeeds you should get a JSON response like this one:
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "ChaincodeLogSmartContract"
},
"id": 1
}Now your chaincode is deployed and ready to run.
Invoke transactions on your Java chaincode
Now that your Java chaincode is deployed and initialized, you can invoke
transactions on it. In this section, you will invoke the log
and query functions as transactions.
To invoke the log function, open the
ChaincodeLog Log request and submit the request. (See Figure
16.)
Figure 16. SoapUI: ChaincodeLog log request

If you're not using the SoapUI project from GitHub (or are using a different HTTP client), the JSON request you should submit looks like this:
{
"jsonrpc": "2.0",
"method": "invoke",
"params": {
"type": 1,
"chaincodeID":{
"name": "ChaincodeLogSmartContract"
},
"CtorMsg": {
"args": ["log", "KEY-2", "This is a log message."]
}
},
"id": 2
}If the request succeeds, you should get a JSON response like this one:
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "a6f7a4fc-2980-4d95-9ec2-114dd9d0e4a5"
},
"id": 2
}To invoke the query function, open the
ChaincodeLog Query request and submit the request. (See
Figure 17.)
Figure 17. SoapUI: ChaincodeLog Query request

If you are not using the SoapUI project from GitHub (or are using a different HTTP client), the JSON request you should submit looks like this:
{
"jsonrpc": "2.0",
"method": "invoke",
"params": {
"type": 1,
"chaincodeID":{
"name": "ChaincodeLogSmartContract"
},
"ctorMsg": {
"args": ["query", "KEY-1", "KEY-2"]
}
},
"id": 3
}If the request succeeds, you should get a JSON response like this one:
{
"jsonrpc": "2.0",
"result": {
"status": "OK",
"message": "84cbe0e2-a83e-4edf-9ce9-71ae7289d390"
},
"id": 3
}The terminal window output of the solution code looks like this:
$ ./ChaincodeTutorial/bin/ChaincodeTutorial
Feb 28, 2017 4:18:16 PM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnection
INFO: Inside newPeerCLientConnection
Feb 28, 2017 4:18:16 PM io.grpc.internal.TransportSet$1 call
INFO: Created transport io.grpc.netty.NettyClientTransport@10bf86d3(/127.0.0.1:7051) for /127.0.0.1:7051
Feb 28, 2017 4:18:21 PM io.grpc.internal.TransportSet$TransportListener transportReady
INFO: Transport io.grpc.netty.NettyClientTransport@10bf86d3(/127.0.0.1:7051) for /127.0.0.1:7051 is ready
Feb 28, 2017 4:34:52 PM com.makotojava.learn.blockchain.chaincode.AbstractChaincode run
INFO: Greetings from run(): function -> init | args -> [KEY-1, Chaincode Initialized]
Feb 28, 2017 4:34:52 PM com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog handleLog
INFO: *** Storing log message (K,V) -> (ChaincodeLogSmartContract-CLSC-KEY-1,Chaincode Initialized) ***
Feb 28, 2017 4:50:27 PM com.makotojava.learn.blockchain.chaincode.AbstractChaincode run
INFO: Greetings from run(): function -> log | args -> [KEY-2, This is a log message.]
Feb 28, 2017 4:50:27 PM com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog handleLog
INFO: *** Storing log message (K,V) -> (ChaincodeLogSmartContract-CLSC-KEY-2,This is a log message.) ***
Feb 28, 2017 5:02:13 PM com.makotojava.learn.blockchain.chaincode.AbstractChaincode run
INFO: Greetings from run(): function -> query | args -> [KEY-1, KEY-2]
Feb 28, 2017 5:02:13 PM com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog handleQuery
INFO: *** Query: For key 'ChaincodeLogSmartContract-CLSC-KEY-1, value is 'Chaincode Initialized' ***
Feb 28, 2017 5:02:13 PM com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog handleQuery
INFO: *** Query: For key 'ChaincodeLogSmartContract-CLSC-KEY-2, value is 'This is a log message.' ***Congratulations! You've just taken the first step into your future.
I encourage you to play around with the ChaincodeTutorial project, add methods to it, change the implementations, and so forth. Get comfortable with writing chaincode. Good luck, and have fun!
Conclusion
This tutorial gave you a brief overview of blockchain technology and of the smart contract, which is implemented as a chaincode program, and the current technology landscape with respect to blockchain.
We went through the steps to set up your Java chaincode development environment, including the software you need to install, how to define and run your local blockchain network, and how to deploy and invoke transactions against one of the example Java chaincode programs from the Hyperledger Fabric project in GitHub.
You learned how to use Eclipse, JUnit, and Gradle to write and build your first Java chaincode program, and then deploy and invoke transactions against your Java chaincode program.
You've taken a hands-on look at blockchain technology and smart contracts, and are positioned perfectly to write more complex Java chaincode as blockchain technology matures and proliferates in the marketplace.
So where you do you go from here?
Next steps
Here are a few suggestions to help you build on what you've learned so far:
- Dive deeper into the Hyperledger Fabric architecture
- Build the Hyperledger Fabric itself
- Join one of the Hyperledger Mailing Lists
Downloadable resources
Related topics
- What is blockchain?
- What is Docker?
- Learn Chaincode
- Hyperledger Fabric documentation
- Hyperledger Community
- Blockchain Developer Center
- Blockchain 101: Quickstart for Developers
- IBM Blockchain courses for developers (free)
- IBM Blockchain videos on developerWorks TV
- IBM Blockchain service on Bluemix


