A Java developer approaching the blockchain (II)

Here I am again with my journey in the blockchain world. So, let's resume from where I left last time, on the tools needed to actually get started in coding the distributed application.

The editor / IDE

I'm not spending too much words on Solidity: as previously mentioned, I'm leaving this topic for future posts. In any case, I actually didn't need any change to the contract that I choose for my first example, so a plain text editor has been enough for me here.
For the rest of the application, if you're really looking for something more than an editor, I'd say the choice is really among the usual and well known IDEs (like Eclipse and Intellij IDEA), which come with extensions/plugins for most languages. I'm a long time user of Eclipse, so that's what I chose, especially considering I opted for a Java based architecture... basically allowing me to avoid walking away too much from my day-to-day development confort zone ;-)

The DAPP architecture

Right, few considerations on the architecture of a distributed application. The idea of not relying on a central server clearly affects the application architecture; a direct communication channel between the GUI and the blockchain layer has to be established without calling into any centralized server or cloud service. One of the most common solutions for that is to rely on Web3.js, which is a JavaScript API for interacting with Ethereum. JavaScript code is embedded into HTML pages, effectively allowing the Ethereum network client to run within the user browser / mobile application.

However, as I mentioned in the former post, I was looking for a possible overlap of the Ethereum blockchain with the technologies that I currently work on (essentially Java). After a bit of investigation, I ended up playing with Web3j, a lightweight, reactive and type safe Java and Android library for integrating with nodes on Ethereum blockchains. I would have created a Java service for calling into the ballot contract, then I would have exposed that as a REST resource using RESTEasy (which incidentally I work on ;-)). Finally, I would have created a fat jar distribution, with an embedded HTTP server (Tomcat) running the afore mentioned JAX-RS application.

I started the DAPP development by creating a JavaBallot Maven project; the pom.xml file includes the most common plugins and declares dependencies to Web3J and RESTEasy:

<dependencies>
  <dependency>
    <groupId>org.web3j</groupId>
    <artifactId>core</artifactId>
    <version>3.0.1</version>
  </dependency>
  <dependency>
    <groupId>org.web3j</groupId>
    <artifactId>crypto</artifactId>
    <version>3.0.1</version>
  </dependency>
  <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>3.1.4.Final</version>
  </dependency>
  <dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-multipart-provider</artifactId>
    <version>3.1.4.Final</version>
  </dependency>
</dependencies>

Speaking of plugins, one of the cool features of Web3j is that it has a plugin that can compile a given Solidity contract and automatically generate Java stub around it. So I added such a plugin and bound its execution to the process-resources Maven phase:

<plugin>
  <groupId>org.web3j</groupId>
  <artifactId>web3j-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>gs</id>
      <phase>process-resources</phase>
      <goals>
        <goal>generate-sources</goal>
      </goals>
      <inherited>false</inherited>
      <configuration>
      <packageName>it.onchain.javaballot.model</packageName>
      <sourceDestination>src/main/java</sourceDestination>
      <soliditySourceFiles>
         <directory>src/main/resources</directory>
         <includes>
            <include>**/*.sol</include>
         </includes>
      </soliditySourceFiles>
      </configuration>
    </execution>
  </executions>
</plugin>

This creates Java classes mapping the contract and allowing building the actual service with the logic for deploying the contract and interacting with it.

The Tomcat plugin is used to create the fat jar:

<plugin>
  <groupid>org.apache.tomcat.maven</groupid>
  <artifactid>tomcat7-maven-plugin</artifactid>
  <version>2.0</version>
  <executions>
    <execution>
      <id>tomcat-run</id>
      <goals>
        <goal>exec-war-only</goal>
      </goals>
      <phase>package</phase>
      <configuration>
        <path>/</path>
        <enablenaming>false</enablenaming>
        <finalname>webapp.jar</finalname>
        <charset>utf-8</charset>
      </configuration>
    </execution>
  </executions>
</plugin>

The service

The service for my simple application is initialized with a reference to a given wallet file and the corresponding password, which are used to create Web3j credentials and client.
Relying on them, the service also offers methods for:
  • deploying a new contract, given few data including the number of proposals and the ballot cap;
  • voting for a given proposal;
  • getting the winning proposal.
Further smart contract functionalities will be covered in the future.

The REST API

The quickest solution to expose the afore mentioned service is to create a plain JAX-RS resource with an operation for each service method, annotated as follows:

@POST
@Path("/vote")
@Consumes("multipart/form-data")
public Response vote(MultipartFormDataInput input) throws Exception
{
  ...
}
 
The resource processes multipart/form-data content that's posted (uploaded) from a web form.

The web page

Finally I created a simple html page with a form for each service functionality. A form with a file type input allows the user telling the application which account to use to perform the Ethereum transactions.
I didn't allow setting gas limit and gas price (they're hardcoded in the service code), just to make the example quick and easy.

In the my next post I'll show the distributed app in action and tell a bit about straightforward improvements as well as pros and cons of alternative architectures.

Thanks for reading, stay tuned!

Comments

Popular Posts