⋮IWConnect Private Ethereum Blockchain as Smart Contract Repository

24 Jan, 2018 | 8 minutes read

Blockchain is inevitable buzzword today. Here at ⋮IWConnect we believe in the potential of this technology. Yes, there are shortcomings and obstacles at the moment like scalability and security, but we believe that the concepts will converge into stable implementations that will support ubiquitous solutions like micro payments in IoT  or peer-to-peer electrical energy sharing.

The whole story started with the Satoshi Nakamoto’s (believe me, I don’t know who this guy is :-)) paper back in 2008:

https://bitcoin.org/bitcoin.pdf

and the rise of Bitcoin as the first digital cryptocurrency:

https://en.wikipedia.org/wiki/Bitcoin

What is Blockchain?

Blockchain is globally shared, distributed database. There is no central entity or deployment that controls the database. Instead, it is a peer-to-peer network constituted of independent nodes. The entries in this distributed database are accepted and processed  transactions. Multiple (thousands or millions) nodes run the Blockchain software, submit transactions and synchronize globally accepted transaction state that can’t be forged by malicious nodes. All nodes eventually see the same database state and the same accepted transactions.

Each participant, human or machine, in this peer-to-peer Blockchain network has one or more accounts. Each account is a combination of public/private cryptographic key pair. The address of the account is derived from the public key and in general this is the information that is shared with the rest of the Blockchain participants. If some other participant needs to interact with me (send me a money for example), she will use my address. The private key is secret and it is used for digitally signing the submitted transactions.

Transactions are organized into blocks. The chain is a list of blocks. The blocks accepted by the network must be mined. What does it mean? If each node is able to group transactions into a block and submit that block to the network with a very little effort then there are will be a lot of crowd and contention that will make the global state synchronization impossible. In order to submit block for acceptance, the miner (a node that also mines) must solve cryptographic puzzle (Proof of Work). The puzzle in its simplest form can be described as:

  • Choose random nonce
  • Combine this nonce with the block’s content
  • Hash the result
  • Check if the calculated hash has X leading zeros
  • If true, submit the block for acceptance
  • If false, go at the beginning and try another nonce

Producing a hash that will contain previously agreed number of leading zeros is not trivial task and the miner must try a lot of random combinations. Miners are awarded with a fee once they mine an accepted block.

Today, there are several Blockchain technologies and implementations that run globally. Bitcoin was the first one and it is still the most successful cryptocurrency solution. In Bitcoin each transaction is a transfer of virtual money between a sender and recipient.

Ethereum

Ethereum is not just a cryptocurrency solution. It is a little bit more than that:

https://www.ethereum.org/

Ethereum is decentralized platform that runs Smart Contracts. Yes, with Ethereum you can transfer cryptocurrencies, Ethers, from one account to another. The principles of fund (value) transfer are similar as the ones well known from Bitcoin. So, how is Ethereum different and what are Smart Contracts?

Each Smart Contract is an entity, an account that is submitted to the Ethereum Blockchain and “lives” inside the Blockchain after that. The Smart Contract has its own address. The external participants (humans, machines) can interact with it once they know its address. The Smart Contract is a peace of code that has its own state (variables) and methods (functions). The external accounts interact with the Smart Contract through its methods. Some of the method calls will change the state of the Smart Contract and they are not free, i.e. the caller will be charged for that. Why is this necessary? Smart Contract mutator methods are executed within Ethereum Virtual Machine (EVM), on each node in the Ethereum peer-to-peer network. There are will be always “evil” external accounts that can write Smart Contract code that contains methods with endless loops. If that method execution is free, then invoking the problematic method will put the whole network into an execution loop. In order to prevent such situations, each mutator method execution spends Ethereum Gas.

The method caller must provide Ethereum Gas she is willing to spend in order to execute (successfully) particular contract method. Ethereum Virtual Machine consists of a set of instructions like SSTORE, SLOAD etc. (similar to assembly or JVM instructions). Each instruction costs particular amount of Ethereum Gas. So if the Gas provided by the contract’s method caller is enough to execute all EVM instructions, the method call will run to completion.  If it is not, the method execution will stop, the contract’s state will rollback and the Gas is not returned to the caller. This mechanism prevents the loops that will block the whole network. If the caller has submitted more Gas than required for particular method execution, the remaining gas is returned to the caller. The Gas has its price in Ethers (usually Gwei, 1 Ether = 10^18 wei, 1 Gwei = 10^9 wei). So, each account that is going to call Smart Contract mutator methods that change the state of the contract must have enough funds that will cover the Ethereum Gas costs. Note that the read only Smart Contract methods are free, i.e. they cost nothing and they are executed as RPC calls against the local node.

The Ethereum miners that successfully mine an accepted block are awarded with a fee that includes (besides fixed amount of 5 Ethers) the value of the Ethereum Gas spent for all transactions included in the mined block.

Ok, it looks like a beautiful and powerful technology. How we use it here at ⋮IWConnect?

⋮IWConnect’s Private Ethereum Blockchain

⋮IWConnect is organized into Practices (divisions): MuleSoft, SnapLogic, QA, Support, Microsoft, Cloud, Process & Project Management, PHP, Mobile etc. Each Practice has its own Practice Lead that is a manager for her Practice. As a manager, the Practice Lead makes plans what is she going to accomplish in the next quarter (research, training, certifications etc.). ⋮IWConnect believes in the S.M.A.R.T criteria, commitments and evaluations.

So, in a nutshell, here is our “game” (yes, it is funny too!):

  • We are running private Ethereum Blockchain (try, learn and experiment). There is only one dedicated miner that will transfer the necessary funds to the “game” participants;
  • Each Practice Lead has its own Ethereum account and address shared with the Company management representative. Each participant runs its own Go Ethereum local node;
  • Each Practice Lead submits Ethereum Smart Contract for each Practice Plan Task she is giving a commitment for the next quarter. This is a contract between the Company and the Practice Lead;
  • The Company management representative, at the end of the evaluation period, will list the tasks submitted and confirm success or failure for each task
  • Another Smart Contract called Practice Plan Points, created by the Company management representative, collects the number of successes and failures per Practice Lead for further analysis and statistics.

All participants use MetaMask as Ethereum, browser based wallet.

Solidity is the language that is used for writing Ethereum Smart Contracts. It is very similar to JavaScript.

We have these two simple Smart Contracts.

pragma solidity ^0.4.11;

contract PracticePlanPoints {
    
    struct Point {
        uint128 successes;
        uint128 failures;
    }

    modifier ownerOnly {
        require(tx.origin == owner);
        _;
    }

    address owner;
    mapping(address=>Point) public points;

    function PracticePlanPoints() public {
        owner = msg.sender;
    }

    function updatePoints(address practiceLead,uint8 successes,uint8 failures) public ownerOnly {
        points[practiceLead].successes += successes;
        points[practiceLead].failures += failures;
    }
}
pragma solidity ^0.4.11;

contract PracticePlanPoints {
    
    function updatePoints(address practiceLead,uint8 successes,uint8 failures) public;
}

contract PracticePlanTask {

    event PracticePlanTaskCreated(
        address indexed practiceLead
    );

    event PracticePlanTaskUpdated(
        address indexed practiceLead
    );

    event PracticePlanTaskConfirmed(
        address indexed manager
    );

    modifier onlyBy(address a) {
        require(msg.sender == a);
        _;
    }

    modifier notConfirmed() {
        require(!confirmed);
        _;
    }

    address public practiceLead;
    address public manager;
    bool public confirmed;
    uint16 public year;
    uint8 public quarter;
    string what;
    uint256 startDate;
    uint256 endDate;
    bool accomplished;

    function PracticePlanTask(address _manager, uint16 _year, uint8 _quarter,string _what, uint256 _startDate, uint256 _endDate) public {
       practiceLead=msg.sender;
       manager = _manager;
       year = _year;
       quarter = _quarter;
       what = _what;
       startDate = _startDate;
       endDate = _endDate;
       PracticePlanTaskCreated(practiceLead);
    }

    function updateTask(string _what, uint _startDate, uint _endDate) public onlyBy(practiceLead) notConfirmed {
        what=_what;
        startDate=_startDate;
        endDate=_endDate;
        PracticePlanTaskUpdated(practiceLead);
    }

    function confirm(address _practicePointsAddress,bool _accomplished) public onlyBy(manager) notConfirmed {
        uint8 successes;
        uint8 failures;
        accomplished = _accomplished;
        confirmed = true;
        successes=_accomplished ? 1:0;
        failures =_accomplished ? 0:1;
        PracticePlanTaskConfirmed(manager);
        PracticePlanPoints practicePlanPoints = PracticePlanPoints(_practicePointsAddress);
        practicePlanPoints.updatePoints(practiceLead, successes, failures);
   } 

    function info() view public returns (address _practiceLead, address _manager, uint16 _year, uint8 _quarter, bool _confirmed, string memory _what, uint256 _startDate, uint256 _endDate, bool _accomplished) {
        _practiceLead=practiceLead;
        _manager = manager;
        _year = year;
        _quarter = quarter;
        _confirmed = confirmed;
        _what=what;
        _startDate=startDate; 
        _endDate=endDate;
        _accomplished = accomplished;
    }
}

Explaining Solidity is a topic for itself and we won’t do that here. Instead, pay attention on the event raised when the Practice Plan Task contract is created.

event PracticePlanTaskCreated(
        address indexed practiceLead
);

Note that the Practice Lead’s address is declared as indexed. Indexed Ethereum event properties will help us search the database and retrieve the contracts for particular Practice Lead.

Another interesting Solidity feature are the modifiers. They are used in the contracts above in order to specify method invocation constraints (only the manager can confirm a task for example).

The code was compiled in Remix which is an excellent online, browser based Solidity IDE.

With compiled contract data and ABI (Abstract Binary Interface) in hand, we have created simple, single page Web application where Practice Leads can submit and list Task contracts. The Company management representative is capable to confirm the tasks if they were accomplished or not.

practice plans
Practice Lead can create, submit and list Practice Plan Tasks
(Figure 1 – Practice Lead can create, submit and list Practice Plan Tasks)
Company management representative can confirm task accomplishment with success or failure
(Figure 2 – Company management representatives can confirm task accomplishment with success or failure)

This is an example of Decentralized Ethereum Application – DApp. Each Practice Lead is running his own Go Ethereum node (geth) and local Node.js http server. The application is built using standard JavaScript libraries like jQuery, Handlebars, moment etc. The library for RPC interaction with the local Ethereum node is Web3. The Web3 provider in our DApp is injected by the MetaMask browser plugin.

Remember the event with the indexed Practice Lead address which is emitted once the Practice Plan Task contract is created? In our DApp, we can enlist the submitted contracts from particular Practice Lead using the following simple JavaScript snippet:

var options = {
  fromBlock:0,
  toBlock: "latest",
  topics:[web3.sha3("PracticePlanTaskCreated(address)"),"0x000000000000000000000000"+getPracticeAddress().substring(2)]
};

var filter = web3.eth.filter(options);

filter.get(function(error,logs){
  if(error)
    console.log(error);
  else {
    fetchPracticePlanTasks(logs);
  }
});

The topics field within the search options is an array with up to 4 elements. The first element must be a hash of the event’s Solidity signature, the rest of the parameters are 32 bytes-long hexadecimal representations of the indexed event properties. Cool, the Ethereum Blockchain is searchable like a real database!

⋮IWConnect has embraced a lot of Ethereum concepts using this simple deployment. We have Miner, Boot node, peer Go Ethereum nodes, DApp, MetaMask wallets and all ingredients that has helped us grasp this amazing technology.

Finally… Yes…. We are ready to help our Clients with practical solutions aligned with the current and future decentralized application trends.