Write the blockchain smart contract chain code for Hyperledger Fabric (Super Ledger) in Java

Source: Internet
Author: User
Tags log log stub soapui hyperledger fabric

Write the first Java chain code program

In the previous section, you are already familiar with how to build, run, deploy, and invoke chain code, but have not yet written any Java code.

In this section, you will use the Eclipse IDE, a Gradle plug-in for Eclipse, and a Java chain Code framework project called Chaincodetutorial to write the first Java chain Code program. You'll get the skeleton code from the GitHub repository I created for this tutorial, import that code into Eclipse, add code to make the chain Code wisdom contract work as required, and build the code using Gradle within the Eclipse IDE.

You will perform the following steps:

    • Install the Gradle buildship plugin for Eclipse.
    • Clone the Chaincodetutorial project from GitHub.
    • Import the project into Eclipse.
    • Explore the Chain Code framework project.
    • Write the Java chain code.
    • Build the Java chain code.
      After this section, your chain code can be run on the local blockchain network.
1. Install the Gradle buildship plugin for Eclipse

You use any of your favorite Ides, but the instructions in this tutorial are for Eclipse. Note : The buildship Gradle plugin helps integrate Gradle with Eclipse, but still requires Gradle to be installed on your computer.

If you have been following the tutorial, you should have installed Gradle on your computer, and install it now if it is not already installed. See the "Installing the Build Software" section to learn how to install Gradle on your computer.

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 will be asked to restart Eclipse.

After you reopen eclipse, Gradle should already be fully integrated with the Eclipse IDE. You are now ready to clone the Chaincodetutorial repository from GItHub.

Cloning Chaincodetutorial project from GitHub

After configuring the Eclipse IDE and Gradle integration, you will clone the Chaincodetutorial code from GitHub and import it into Eclipse. Open a command prompt or terminal window, navigate to $GOPATH and execute the following command:

git clone https://github.com/makotogo/ChaincodeTutorial.git

The command output should look like this:

$ export GOPATH=/Users/sperry/home/mychaincode$ cd $GOPATH$ git clone https://github.com/makotogo/ChaincodeTutorial.gitCloning 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 0Receiving 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/ChaincodeTutorial

This command clones the Blockchain chaincodetutorial repository from GitHub to the $GOPATH. It contains a Java chain code framework project that you can build, run, and test on your local blockchain network.

But before you perform all of these operations, you need to import that code into Eclipse.

3. Import the project into Eclipse

In Eclipse, go to File > import...> Gradle > Existing Gradle Project. This opens a wizard dialog box (see Figure 9).

Click Next. In the dialog box that appears in the wizard (see Figure 10), browse to $GOPATH/chaincodetutorial, and then click Finish to import the project.

When you are finished importing the project, make sure that Java perspectiveis selected and that the Chaincodetutorial project you just imported appears in Project Explorer view.

Once the code is imported into the Eclipse workspace, you can write the chain code.

4. Explore the Chain Code framework Project

In this section, you'll explore the chain code project to understand how it should work before you write any Java code.

As a developer, we like to write code, so I don't want you to lose the chance to write Java code. However, project settings can be complex, and I don't want these settings to hinder the main purpose of implementing this tutorial. To do this, I have provided most of the code you need.

First let's take a quick look at the base class Abstractchaincode, which is in the Com.makotojava.learn.blockchain.chaincode package, as shown in Listing 1.

Listing 1. 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 (Abstrac   Tchaincode.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 1th I would like to point out is that Abstractchaincode is a subclass of Chaincodebase, which comes from the shim client of the structure ( lines 7th, 10 ).

The第17-19 line shows the methods that need to be implemented in the Chaincodelog class (subclasses of Abstractchaincode), which are used to implement initialization, ledger querying, and logging functions, respectively.

The第22-36 line shows the run () method of the Chaincodebase class (from the chain Code shim Client), where we can see which function was called and which handler the call should be delegated to. The class is extensible, because any function other than init and query (such as the log function) is handled by Handleother (), so you must also implement it.

Now open the Chaincodelog class in the Com.makotojava.learn.blockchain.chaincode package.

I only provided a framework for you to populate-that is, I only provided the code needed to compile it. You need to write the remaining code. You should perform the JUnit test, and you will see that the test failed (because the implementation has not been written yet) and why it failed. In other words, you can use JUnit testing as a guide to implement code correctly.

Now, if it's hard to understand, don't worry; I've provided a solution in com.makotojava.learn.blockchain.chaincode.solution in case you're stuck (or want to help with the implementation by reference).

Writing the Java chain code

Let's start by introducing some of the background you need to know to implement the chain code approach in Chaincodelog. The Java chain code communicates with the Hyperledger Fabric framework through the Chaincodestub class, and it is also important to remember that the ledger is at the core of the transparency of blockchain technology. It is the state of the ledger that makes the smart contract (the responsibility) work, and the chain code evaluates the state of the ledger by Chaincodestub. By accessing the ledger status, you can implement a smart contract (also known as a chain code).

There are many ways to store, retrieve, and delete data items in the current state of the ledger, but this tutorial discusses only two methods, which are used to store and retrieve ledger status: Chaincodestub

Putstate (string key, String value)-stores the specified state value in the ledger, which is mapped appropriately to the specified key.

GetState ()-Gets the state value associated with the specified key and returns it as a string.

When you write code for this tutorial, you only need to store or retrieve the status value in the ledger, using the Putstate () or getState () function. The Chaincodelog class only stores and retrieves values in the ledger to implement its smart contract, so implementing these methods requires only knowing the value. More complex chain codes will use some of the other methods in Chaincodestub (but these methods are not covered in this tutorial).

I like test-driven development (TDD) very much, so I write unit tests first, in the way TDD does. Continue to run them and observe their failure processes. After that, write code that conforms to the specification until the unit tests are passed. Unit testing is done to ensure that you get the expected behavior, and by studying unit tests, you get enough information to implement these methods.

However, I've also written Javadoc comments at the top of each method, which may help (in case you're not familiar with TDD or JUnit). After completing this section, you should know that there is all the information needed to implement the chain code between the code in the JUnit test and the Javadoc comment in the framework chaincodelog.

From the Project Explorer view (in the Java perspective), navigate to the Chaincodelogtest class, right-click it and select Run as > Gradle Test. As it runs, you will see the results shown in 11, which shows the tree structure of all the Gradle tasks that are running. A successfully completed task is indicated by a check mark next to it.

The exclamation point in the Gradle executions tab represents the Gradle task that corresponds to the failed unit test (all 4 unit tests failed, as we expected).

Because of the way we write JUnit test cases, each test method corresponds to one of the methods in Chaincodelog, and you need to implement them correctly in this tutorial.

Implement Getchaincodeid ()
First, you need to implement Getchaincodeid (). Its contract requires a unique identifier that returns the chain code. I've defined a constant named chaincode_id at the top of the Chaincodelog class, and you'll use it. You can freely change its value, but if you want to change the chain code ID returned by Getchaincodeid (), make sure it is unique across your network and do not forget to change the Chaincodeid.name property of the JSON message.

/** * Returns the unique chaincode ID for this chaincode program. */@Overridepublic String getChaincodeID() {  return null;// ADD YOUR CODE HERE}

Exercise: Complete the Getchaincodeid () method. If you need a reference, see the Com.makotojava.learn.blockchain.chaincode.solution package.

Implement Handleinit ()

The next step is to implement the Handleinit () method. Its contract requires processing the initialization of the chain Code program, which in this case means that it adds a message (specified by the caller) to the ledger and returns the message to the caller when 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. */@Overrideprotected String handleInit(ChaincodeStub stub, String[] args) {  return null;// ADD YOUR CODE HERE}

Exercise: Complete the Handieinit () method. If you need a reference, see the Com.makotojava.learn.blockchain.chaincode.solution package.

Implement Handlequery ()

The next step is to implement the Handlequery () method. Its contract requires querying the ledger, for which it obtains the specified key, queries the ledger for a value that matches this (these) keys, and then returns the value to the caller. If more than one key is specified, the returned value 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). */@Overrideprotected String handleQuery(ChaincodeStub stub, String[] args) {  return null;// ADD YOUR CODE HERE}

Make sure that you write the code to output the results of the query call so that you can see the results in the console output (see the solution if you want to know how I did it).

Exercise: Complete the Handlequery () method. If you need a reference, see the Com.makotojava.learn.blockchain.chaincode.solution package.

Implement Handleother ()

Finally, the Handleother () method needs to be implemented, and its contract requires the processing of other messages (which is completely open, but because of this it is extensible). You will implement the log function here, whose contract requires that a message specified by the caller be added to the ledger and returned to the caller when the call succeeds. This looks very similar to what happened in the init function, so you might be able to take advantage of this function in the 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. */@Overrideprotected 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, see the Com.makotojava.learn.blockchain.chaincode.solution package.

If the code you write for each of the previous exercises meets the requirements set for them in this section (and in the code comments), the JUnit tests should all pass, and they should work when you deploy the chain code in the local blockchain network and run.

Keep in mind that if you encounter a hindrance, I provide a solution (but you must implement these methods yourself before looking at the solution).

Building Java Chain Code

Now that you have written the Java chain code and passed all JUnit tests, it is time to build the chain code using Eclipse and the Gradle buildship plugin for Eclipse. By going to Window > Show View > Other ... bring up Gradle Tasks view, then search Gradle, select Gradle tasks and click OK. (see Figure 12.) )

Gradle the Tasks view opens, expand the chaincodetutorial > Build node and select build and clean. (see Figure 13.) )

Right-click build and clean, and then select Run Gradle Tasks(Gradle will determine the correct order in which to run them). Your Gradle executions view should show a clean build, shown in 14, where there is only one check mark next to each item.

Once the build is complete, $GOPATH the/chaincodetutorial directory (which you have previously cloned from GitHub to here) has a subdirectory build/distributions, which contains your chain code (which should look familiar because the previous tutorial This has been done in the Hello example).

Once the Java chain code is built, it can be deployed and run on the local blockchain network, and transactions are invoked on top of it.

Deploy and run the Java chain code

In this section, you will start and register your chain code, deploy it, and invoke transactions over the chain code through the Hyperledger Fabric REST interface, just as you did for the hello example earlier in this tutorial. Ensure that the local blockchain is running (if you want to review the relevant content, see the "starting the Blockchain Network" section).

You will perform the following steps:

    • Register the Java chain code.
    • Deploy the Java chain code.
    • Call the transaction on the Java chain code.
1. Registering the Java chain code

You need to extract the Build/distributions/chaincodetutorial.zip file and run the chain code script just as you would when you ran the hello example earlier in this tutorial (see the "Registration Sample" section).

When you run the chaincodetutorial script, the output should resemble the following:

$ ./ChaincodeTutorial/bin/ChaincodeTutorialFeb 28, 2017 4:18:16 PM org.hyperledger.java.shim.ChaincodeBase newPeerClientConnectionINFO: Inside newPeerCLientConnectionFeb 28, 2017 4:18:16 PM io.grpc.internal.TransportSet$1 callINFO: Created transport [email protected](/127.0.0.1:7051) for /127.0.0.1:7051Feb 28, 2017 4:18:21 PM io.grpc.internal.TransportSet$TransportListener transportReadyINFO: Transport [email protected](/127.0.0.1:7051) for /127.0.0.1:7051 is ready

Now that your Java chain code is registered with the local blockchain network, you are ready to deploy and test the chain code.

2. Deploying Java Chain Code

Just as you do with the Hello sample chain code, the Java chain code is deployed with the REST interface of the structure and the transaction is invoked on top of it.

Open SoapUI. If you want, you can create a new rest project and all of its requests yourself, or you can import the SoapUI REST project that I included in the previously cloned GitHub project. The SoapUI project is located in the $GOPATH/chaincodetutorial directory.

To deploy the chain code, you can navigate to the Chaincodelog deploy request (15) and submit the request.

If you do not use the SoapUI project from GitHub (or use a different HTTP client), then the JSON request that should be submitted is as follows:

{"jsonrpc": "2.0",  "method": "deploy",  "params": {    "type": 4,    "chaincodeID":{        "name": "ChaincodeLogSmartContract"    },    "ctorMsg": {        "args": ["init", "KEY-1", "Chaincode Initialized"]    }  },  "id": 1}

Submit the request. If the request is processed successfully, you get the following JSON response:

{   "jsonrpc": "2.0",   "result":    {      "status": "OK",      "message": "ChaincodeLogSmartContract"   },   "id": 1}

Your chain code is now deployed and ready to run.

3. Invoking transactions on the Java chain code

Once you have deployed and initialized the Java chain code, you can invoke the transaction on top of it. In this section, the log and query functions are called for trading.

To call the log function, you can open the Chaincodelog log request and commit it. (see Figure 16.) )

If you do not use the SoapUI project from GitHub (or use a different HTTP client), then the JSON request that should be submitted is as follows:

{"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 is processed successfully, you get the following JSON response:

{   "jsonrpc": "2.0",   "result":    {      "status": "OK",      "message": "a6f7a4fc-2980-4d95-9ec2-114dd9d0e4a5"   },   "id": 2}

To invoke the query function, you can open the Chaincodelog query request and submit it. (see Figure 17.) )

If you do not use the SoapUI project from GitHub (or use a different HTTP client), then the JSON request that should be submitted is as follows:

{"jsonrpc": "2.0",  "method": "invoke",  "params": {    "type": 1,    "chaincodeID":{        "name": "ChaincodeLogSmartContract"    },    "ctorMsg": {        "args": ["query", "KEY-1", "KEY-2"]    }  },  "id": 3}

If the request is processed successfully, you get the following JSON response:

{   "jsonrpc": "2.0",   "result":    {      "status": "OK",      "message": "84cbe0e2-a83e-4edf-9ce9-71ae7289d390"   },   "id": 3}

The terminal window output of the solution code is similar to the following:

$./chaincodetutorial/bin/chaincodetutorialfeb 4:18:16 PM org.hyperledger.java.shim.ChaincodeBase Newpeerclientconnectioninfo:inside Newpeerclientconnectionfeb 4:18:16 PM io.grpc.internal.transportset$1 callinfo:created Transport [email protected] (/127.0.0.1:7051) For/127.0.0.1:7051feb, 4:18:21 PM Io.grpc.internal.transportset$transportlistener Transportreadyinfo:transport [email protected] (/ 127.0.0.1:7051) for/127.0.0.1:7051 is Readyfeb, 4:34:52 PM Com.makotojava.learn.blockchain.chaincode.AbstractChaincode runinfo:greetings from Run (): function, init | Args--[KEY-1, Chaincode Initialized]feb, 4:34:52 PM Com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog handleloginfo: * * * Storing log message (K,V), Chaincodelogsmartcontract-clsc-key-1,chaincode Initialized) ***feb, 4:50:27 PM Com.makotojava.learn.blockchain.chaincode.AbstractChaincode runinfo:greetings from Run (): function--Log | Args --[KEY-2, this is a log message.] Feb 4:50:27 PM com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog handleloginfo: * * * Storing log Message (K,V)-(Chaincodelogsmartcontract-clsc-key-2,this is a log message.) ***feb 5:02:13 PM Com.makotojav A.learn.blockchain.chaincode.abstractchaincode runinfo:greetings from Run (): function--Query | Args--[KEY-1, Key-2]feb 5:02:13 PM Com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog Handlequeryinfo: * * * query:for key ' chaincodelogsmartcontract-clsc-key-1, value is ' Chaincode Initialized ' ***feb 28, 201 7 5:02:13 PM Com.makotojava.learn.blockchain.chaincode.solution.ChaincodeLog handlequeryinfo: * * * query:for key ' Chaincodelogsmartcontract-clsc-key-2, value is ' a log message. ' * * *

Congratulations to you! You have taken the first step towards the future.

You are encouraged to modify the Chaincodetutorial project, add methods to it, change the implementation, and so on. You are also free to write the chain code. Good luck and good coding!

Conclusion

This tutorial provides a brief overview of blockchain technology and smart contracts (implemented as chain code programs) and the latest developments in blockchain technology.

We describe the steps to set up the Java Chain Code development environment, including the software that needs to be installed, how to define and run the local blockchain network, and how to deploy a Java Chain code sample program from the Hyperledger Fabric project in GitHub and invoke the transaction on top of it.

You learned how to write and build the first Java chain Code program using Eclipse, JUnit, and Gradle, and then deploy the Java Chain Code program and invoke the transaction on top of it.

You've seen blockchain technology and smart contracts yourself, and as blockchain technology matures and market size expands, you'll have more skills to write more complex Java chain code.

So what are you going to do next?

Follow-up action

The following recommendations will help you to continue your research based on the knowledge you are currently learning:

In-depth study of Hyperledger fabric architecture

Thanks

Thank you very much for Du Yu carefully review this article, to provide constructive advice and correction.

Share two tutorials by the way:
1. Blockchain Novice Ethereum Dapp introductory Combat
2. Blockchain advanced Ethereum e-commerce platform combat

J Steven Perry

Write the blockchain smart contract chain code for Hyperledger Fabric (Super Ledger) in Java

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.