21. Creating a Blockchain Client

In the previous chapter, I discussed how to build Application BlockChain Interface (ABCI) applications to handle the business logic of a blockchain. That allows us to develop complex logic to process, transform, and validate transactions to be recorded in the blockchain. For each transaction, the ABCI application can apply rules, compute its persistent effects (e.g., changes to account balances for a monetary transaction), and save results in an off-chain database. Since the ABCI application can be written in any language and on any software stack and can support arbitrary transactional logic, it allows us to build a variety of different blockchains with specific purposes and optimizations. Each ABCI application is a blockchain.

However, with all its power, the ABCI application is still designed around transactions. In traditional enterprise software terms, the ABCI application is middleware providing business or transactional logic. It does not provide user interface or high-level application logic. Similar to Ethereum, the ABCI applications also require a decentralized dapp (dapp) layer to be accessible to end users. The dapp utilizes data and functions provided by the blockchain (i.e., the ABCI application), and hence the dapp is a client to the blockchain.

Note

The Tendermint dapp is different from the Ethereum dapp covered in earlier chapters of the book. An Ethereum dapp is a client for smart contracts deployed on the blockchain. It is limited to invoking public methods exposed by the contract. A Tendermint dapp, on the other hand, has full access to the transaction records stored in the blockchain, as well as off-chain databases maintained by the ABCI application. It is a “dapp on steroids.”

In this chapter, I will demonstrate how to build a dapp on the Tendermint platform, using the facts example from the previous chapter. We will build a web application, but the principle is the same for any type of modern user interface.

Overview of the Approach

The simplest approach to a dapp is to build an external application that interacts with the blockchain application programming interface (API). As described in earlier chapters, the API commands are sent via TCP/IP port 46657 to any node on the blockchain network. The application sends in transactions and queries via the /broadcast_tx_commit and /abci_query API methods, respectively. The dapp exists outside of the blockchain. It is not aware of the inner workings of the ABCI application. This is truly a blockchain as a service setup (Figure 21.1).

image

Figure 21-1 The dapp with blockchain as a service

However, this type of dapp is just another web site or mobile app. It is typically created and managed by a central entity. It accesses the blockchain through a predefined custom data protocol and lacks in-depth access of the underlying data structure.

An alternative is to build a distributed application that runs on each node. This application could be deeply integrated with the ABCI application, with local access to databases (Figure 21.2). The advantage of this approach is a higher level of decentralization and a more efficient application architecture. The disadvantages are that it creates a software dependency on the applications at the node level, and it increases the potential security risks for the blockchain, as nodes are serving application services via the Internet. Those disadvantages increase the difficulties of application deployment and management.

image

Figure 21-2 A tightly integrated dapp architecture

Note

Even in a decentralized architecture, where the dapp software runs on every node, there still needs to be a centralized entry point. For example, if the dapp is a web app, it still needs a URL. In this case, a lightweight centralized load balancer is needed to direct traffic to the blockchain nodes.

The Sample Application

The sample application shown here is a web app user interface (UI) based on the facts application in Chapter 20. It allows the user to enter facts, with sources and statements, on a web page. And the same page displays the current tally of statements by sources (Figure 21.3).

image

Figure 21-3 The dapp web app for facts

In the next two sections, I will demonstrate how to create this web application in PHP and Java. The PHP application is a simple web application that used the Blockchain API as a back end. The Java application is tightly integrated with the ABCI application.

PHP

We developed a PHP web app to utilize the blockchain API via the TCP socket connection. The blockchain runs Tendermint Core and the facts ABCI application described in Chapter 20.

The PHP code first checks whether this request is a submission of the form, and if it is, the PHP code will send the transaction to the blockchain and wait until it commits.

$source = $_REQUEST['source'];
$stmt = $_REQUEST['stmt'];
if (empty($source) or empty($stmt)) {
  // Not valid entry
} else {
  $transaction_req = 'localhost:46657/broadcast_tx_commit?tx="'
        . urlencode($source) . ':'
        . urlencode($stmt) . '"';
  $ch = curl_init($transaction_req);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  curl_exec($ch);
  curl_close($ch);
}

Next, the PHP code queries the blockchain via its custom query API to check for the tally of facts based on the source. The query is passed to the ABCI application. As discussed, the ABCI application is responsible for parsing the query, creating a response, and sending the response via the blockchain. The ABCI response is in a structured JavaScript Object Notation (JSON) message. The value field in the response message contains the results encoded in hex characters. The PHP code will parse the hex content and then display the results in a table.

<?php
  ... ...
  $query_req = 'localhost:46657/abci_query?data="all"';
  $ch = curl_init($query_req);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  $json_str = curl_exec($ch);
  $json = json_decode($json_str, true);
  $result = hex2str($json['result']['response']['value']);
  curl_close($ch);
  $entries = explode(",", $result);
?>
... ...
<table class="table table-bordered table-striped">
  <thead>
    <tr>
      <th>Source</th>
      <th># of statements</th>
    </tr>
  </thead>
  <tbody>
<?php
  foreach ($entries as $entry) {
    list($s, $c) = explode(":", $entry);
?>
    <tr>
      <td><b><?= $s ?></b></td>
      <td><?= $c ?></td>
    </tr>
<?php
  }
?>
  </tbody>
</table>

Java

The Java web application accomplishes the same functionalities as the PHP application, but it is directly integrated with the ABCI application’s data store. In fact, the ABCI application runs inside the same JVM as the Java web application. Let’s look into how this works.

In the Java web application’s web.xml file, we specify that a servlet will run as soon as the application loads in Tomcat.

<servlet>
  <servlet-name>StartupServlet</servlet-name>
  <servlet-class>
    com.ringful.blockchain.facts.servlets.StartupServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

That servlet loads and runs the ABCI application.

public class StartupServlet extends GenericServlet {
  public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);
    try {
      // This starts the ABCI listener sockets
      FactsApp app = new FactsApp ();
      getServletContext().setAttribute("app", app);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

Next, in the servlet filter in front of the index.jsp web page, we first check whether a new fact (source and statement) is submitted in this request. If this is the case, the filter sends the transaction to the blockchain using its regular TCP socket API connection.

public class IndexFilter implements Filter {
  private FactsApp app;
  FilterConfig config;
  public void destroy() { }
  public void doFilter (ServletRequest request,
            ServletResponse response, FilterChain chain)
                      throws IOException, ServletException {
    if (app == null) {
      app = (FactsApp) config.getServletContext().getAttribute("app");
    }
    String source = request.getParameter("source");
    String stmt = request.getParameter("stmt");
    if (source == null || source.trim().isEmpty() ||
        stmt == null || stmt.trim().isEmpty()) {
      // Do nothing
    } else {
      CloseableHttpClient httpclient = HttpClients.createDefault();
      HttpGet httpGet = new HttpGet(
          "http://localhost:46657/broadcast_tx_commit?tx=%22" +
          URLEncoder.encode(source) + ":" +
          URLEncoder.encode(stmt) + "%22");
      CloseableHttpResponse resp = httpclient.execute(httpGet);

      try {
        HttpEntity entity = resp.getEntity();
        System.out.println(EntityUtils.toString(entity));
      } finally {
        resp.close();
      }
    }
    // Sends the application data store to the web page for JSTL
    // to display in a table.
    request.setAttribute("facts", app.db);
    chain.doFilter(request, response);
  }
  public void init(FilterConfig filterConfig) throws ServletException {
    this.config = filterConfig;
  }
}

The filter then queries the ABCI application’s data store directly to get a tally of facts by sources. Notice that we do not go through the socket-based blockchain query API for this. While for this simple application the data store query is simple and well supported by the blockchain query API, I can envision application scenarios where the dapp makes heavy use of the off-chain application data store for complex business logic and UI logic.

<table class="table table-bordered table-striped">
  <thead>
    <tr>
      <th>Source</th>
      <th># of statements</th>
    </tr>
  </thead>
  <tbody>
    <c:forEach items="${facts}" var="fact">
      <tr>
        <td><b>${fact.key}</b></td>
        <td>${fact.value}</td>
      </tr>
    </c:forEach>
  </tbody>
</table>

The Java application can be found in the book’s GitHub repository. You can build a WAR file ready for Apache Tomcat deployment by running the following Maven build command:

$ mvn clean package

Conclusion

In this chapter, I showed how to build a complete blockchain application accessible to end users. I showed a web application, but it could easily be a web service to support rich client (i.e., mobile) applications. While it is possible to build completely decentralized dapps, most dapps are created and operated by companies offering services to their users.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.15.15