Access the Ad Impression Contract by web page

In the previous blog we created a smart contract in solidity and accessed it using the nodejs console. Here we will access it using a static web page. This will help us learn the Javascript that goes into invocations of the ethereum contract. We will be copying the 5 or 6 lines of javascript invocation calls we used last time after the contract is deployed.

Again this is a simplistic view. Every impression needs to be recorded using some gas from the account. This will turn out to be expensive. In the next blog we will attempt to overcome this issue using channels. After that we will deploy our web pages using truffle.

These two files can be kept in the same folder where we kept the solc files except for the fact that they should be work together. The HTML simply has a text box to post impressions. Tomorrow in a real world scenario we will replace with values posted from the beacon on client or AdServer.

Sample Impression DApp


<!--
<a href="https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js">https://cdn.rawgit.com/ethereum/web3.js/develop/dist/web3.js<//a>
<a href="https://code.jquery.com/jquery-3.1.1.slim.min.js">https://code.jquery.com/jquery-3.1.1.slim.min.js</a>
<a href="http://./index.js">http://./index.js</a>
Sample Impression DApp
<h1>Access Ad Impression Smart Contract</h1>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Entity</th>
<th>Impression</th>
</tr>
</thead>
<tbody>
<tr>
<td>Advertiser</td>
<td id="advertiser"></td>
</tr>
<tr>
<td>Publisher</td>
<td id="publisher"></td>
<//tr>
<//tbody>
<//table>
<//div>
<a href="#" class="btn btn-primary">Impression Increment</a>

I have intentionally used few slashes extra to escape the WordPress html formatting.
We need to ensure that deployed address is available using the nodeJS console. Even the inserted interface script is one copied from the script tag when we compile code by solc.


web3 = new Web3();
web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));
abi = JSON.parse('[{"constant":false,"inputs":[{"name":"sender","type":"bytes32"}],"name":"increment","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"bytes32"}],"name":"getImpressions","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"impressionsLedger","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_entity","type":"bytes32[]"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]')
AdImpression = web3.eth.contract(abi);
// In your nodejs console, execute contractInstance.address to get the address at which the contract is deployed and change the line below to use your deployed address
contractInstance = AdImpression.at('0xca50e64ec65c7cd1fd15404149ff880b7d91efce');
sender = "hello";

function increment() {
  entityName = $("#entity").val();
  contractInstance.increment(entityName, {from: web3.eth.accounts[1]}, function() {
//    let div_id = candidates[candidateName];
    $("#" + "advertiser").html(contractInstance.getImpressions.call("Rama").toString());
    $("#" + "publisher").html(contractInstance.getImpressions.call("Nick").toString());
  });
}

$(document).ready(function() {
    let val = contractInstance.getImpressions.call("Rama").toString()
    $("#" + "advertiser").html(val);
    let val2 = contractInstance.getImpressions.call("Nick").toString()
    $("#" + "advertiser").html(val);
});

The updates might have to wait for transactions to be committed.

Setting up a simple contract on ad impressions – invoke from console

Blockchain has been making inroads in every business vertical in the field of IT. The search for a technology that is a single source of truth in areas lacking transparency and middlemen have an answer as blockchain today. In the world of advertising too there is a lot of incorrect reporting of ad clicks or impressions. Here in this example we will set up a simple contract between an advertiser and publisher that will attempt to have an impression ledger. Later we will delve into the issues around verifying impressions over a channel rather than hashing blocks of impressions.

Let us store this in a folder named impressioncontract.


pragma solidity ^0.4.11;

contract AdImpressionLedger {

    mapping (bytes32 => uint8) public impressionsLedger;

    bytes32 demand;
    bytes32 supply;

    function AdImpressionLedger (bytes32[] _entity) {
        demand=_entity[0];
        supply=_entity[1];
    }

    function increment (bytes32 sender) returns (bool) {
        impressionsLedger[sender]+=1;
        return true;
    }

    function getImpressions(bytes32 sender) returns (uint8) {
        return impressionsLedger[sender];
    }
}

This contract has been written in solidity. As mentioned in the earlier blog we will require a solc compiler. We will deploy this contract in ethereum node using testrpc client. We will load testrpc which is a local in-memory blockchain. I feel always safe to set up the GOPATH and the NODE_PATH. It is good to set them up in our startup scripts.

I always start testrpc along with mining enabled, default does not allow to mine. So we allow 60 seconds to mine blocks. In a local environment this will be sufficient.


$ testrpc -b 60

On another terminal start node. Since testrpc is inmemory database we will need to do this each time we start testrpc,


$ node
>Web3 = require('web3')
>web3 = new Web3();
>web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));
>code = fs.readFileSync('AdImpressionLedger.sol').toString()
>solc = require('solc')
>compiledCode = solc.compile(code)
>abiDefinition=JSON.parse(compiledCode.contracts[':AdImpressionLedger'].interface)
>AdImpression= web3.eth.contract(abiDefinition)
>byteCode = compiledCode.contracts[':AdImpression'].bytecode
>deployedContract = AdImpression.new('advertiser1',{data: byteCode, from: web3.eth.accounts[0], gas: 4700000})
>deployedContract.address
'0xa79721b60cc5f8c1badbd1687a02fe6cf7535801'

Sometimes we will need to wait for sometime to get the address.


>contractInstance = AdImpression.at(deployedContract.address)
>contractInstance.getImpressions.call("advertiser1");
{ [String: '0'] s: 1, e: 0, c: [ 0 ] }
so far mining or no mining did not create any difference.

I reduced the blocktime to 10  seconds.


contractInstance.increment('hello',{from:web3.eth.accounts[1]})

I still need to figure out why the contract constructor is refusing to take 2 arguments, so I forced it as an array.

A good environment to start with

Blockchain can be set up at home or on cloud. To begin development, we can always start with a set up at home. In future if we have requirements where many other people need to connect to our node, we can host it in cloud.

When you develop and deploy contracts on ethereum, you will require a node which will allow you to mine the blocks, you will need gas to deploy the contracts. Mining blocks require good CPU power and RAM. A hardware environment with 8GB RAM minimum and a 4 core CPU is recommended. My hardware configuration is as follows:

  • Processor i7 7700 (8mb cache upto 4.20 Ghz)
  • RAM – 16 GB DDR4 2133 Mhz (8×2)
  • Graphic Card – GTX 1060, For Development purpose with no intent to mine, graphics card is not needed.

My setup has Linux 16.02 LTS loaded on an Oracle Virtual Box. It is safe, easy to work on testrpc or geth developer environment, as these are local and allow us play with contracts, our gas. Since mining happens very quick, we do not need to wait for gas from others, or mine. If we decide to attach to any blockchain outside, syncing up the blockchain is the first activity, this takes up time and CPU power. We can ignore these for development now.

All websites advise to keep accounts and passwords safe. These cannot be recovered in future if forgotten. It is good to start with development environment, maybe it is good to have a separate hardware which will allow us to handle blockchain.

Here is what will help us moving forward:

  • testrpc or geth client to run and interact with our node. Both of them have web interfaces to deploy and query our contracts.
  • truffle with web pack as a build, deployment and test framework for our smart app. This will provide the web pages and instructions to deploy our contracts into ethereal clients.
  • Both of them require Golang, NodeJs, Web3, ethereumjs-testrpc.
  • We will need to install solidity separately to build smart contracts.

All these will be good to start for building basic Dapp.

Building Dapps on Ethereum

We are witnessing a surge of Dapps today, I found 704 Dapps listed on the d-app ether casts (https://dapps.ethercasts.com) itself. This is supposed to be a game changer for the technology landscape today.  Ethereum provides a platform where many d-apps can be deployed, there is no need for setting up individual blockchain for every application. Still the journey from concept to deployed application has few challenges. This requires an understanding of

  • Blockchain domain
  • Tools and their purpose

Before building smart apps on blockchain, one has to have a good understanding of how the blockchain works, what are the different possibilities or opportunities. How do we validate if blockchain is the real solution for the problem at hand. The courses listed from blockchaininstituteoftechnology helps. The courses helps us understand the domain, and the current events. The blockgeeks website is also helpful with good lectures on cryptocurrencies.

Once we understand the technology and tools available, the next is to try them. Here we will discuss deploying smart contracts with Ethereum. The switch from building centralised applications to deploying distributed applications on blockchain requires change in perspective. The way we start understanding the applications on an enterprise web application server is different from deploying smart decentralised applications on Ethereum. There are many good websites available to start learning. I liked the one by Mahesh Murthy. There are few others too.

The Ethereum landscape has many tools. Being early stages of development, documentation is less. Here is a list of tools and their purpose. This will help in understanding the architecture of deployment of Decentralised Smart Applications on an ethereum virtual machine.

The components that make up a blockchain ecosystem can be listed as:

  • A peer to peer network component.
  • A block building and rewarding component
  • A component to handle our cryptocurrency wallet
  • A virtual machine where apps are deployed
  • the dApp itself

The dApp itself can be a standalone CLI application. For example, Ethereum has multiple clients we can choose from:

  • C++ based Ethereum Client
  • Golang based geth
  • Javascript based testrpc

This is used mostly for testing purposes.

We can also interface with a web application deployed on a web server. Here we need to distinguish between two web servers

  • A web interface for the blockchain component – Usually this will host components that are provided to the applications that interacts with the smart contracts.
  • A web server where our web pages which interact with blockchain lie.

Ethereum provides a sandboxed environment for Blockchain and thats the reason the web servers have to be separated.

Development of dApps can be done using Javascript, or Solidity. These can be compiled into EVM bytecode.

Apart from these we will also need build, integration and management tools like truffle. In my next post I will share details on how to use these tools.