Developing Smart Contracts Using Solidity

By Praveen Nagpal - Lead Developer Chainthat Limited

Having developed and designed centralised applications in Java/C++ over the past 15 years, I started looking at the Ethereum stack few months ago to develop decentralized applications (DApps) based on the core blockchain framework. One of the key constituents in the Ethereum’s blockchain implementation is the ability to write Smart Contracts.

What is a Smart Contract?

I think of Smart Contract similar to a web service with its public functions as the service API and the Contract’s public address as the identifier (web service address). Ethereum treats Smart Contract as a special kind of account which has a computer program (piece of code) along with data (storage) sitting on the blockchain ledger at a certain address

What is Solidity?

Solidity is a high-level language to write Smart Contracts and is designed to be compiled into bytecode for the Ethereum Virtual Machine. Like most programmings languages, it is Turing complete.

Key features of Smart Contract written in Solidity

  • Like other OOPs (Object Oriented Programming) languages such as Java/C++, Solidity is a statically typed language. Unlike scripting languages such as javascript, this means that you have to declare the type of the variable before using it in the contract, otherwise the compiler will not allow it. Syntactically, solidity is a bit like javascript
  • There are several ways to develop contract:
    • Browser based Solidity compiler can be found at https://ethereum.github.io/browser-solidity. This is the easiest way to get started writing contracts
    • For command line options, one can install solc binary. Refer to following instructions to install solidity
    • Use Mix IDE, tool developed by the ethereum community. You can download its binary or build it from a C++ ethereum source
    • There are development frameworks available such as Truffle or Embark which allow Smart Contracts to be compiled and deployed on in-memory blockchain or test networks
    • Personally, I use a meteor wrapped solidity compiler which internally uses a solc node package manager (npm) library. For unit testing on javascript clients, mocha framework is quite good.
  • Smart Contract is like a special account in ethereum which has code and also has a balance. However, the only way to trigger functions in the contract is when we pass a transaction through a normal/external account (“poke” a contract).

 

  • There is a Cost of computation in Smart Contract, which is expressed in Gas.
    • Each write function in a contract requires client to pay for the fuel (Gas) in a currency token such as ether in Ethereum. This is used to pay the fees to the miners who are validating the transactions in the block.
    • The maximum amount of Gas intended for using per block is Gas Limit. It is meant as a safety net for buggy code which can run into an infinite loop and thus compromise the network.
    • Product of gas price and gas represents the maximum amount of ether (or wei) that one is willing to spend on the transaction.
    • Each operation in the EVM is assigned a number of how much gas it consumes. gasUsed is summing up all the gas for all the operations executed.
    • Total cost on the transaction is gasUsed * gasPrice
  • One of the early mistakes that one can do is to try and store all the information in the transaction on the contract state itself. DApps needs to store only that information in the state which is crucial for the consensus on blockchain. Remember, there is a block size limit on the blockchain and there is a cost to store information in the contract
  • Contracts can call or delegate to other contracts. This allows you to build a nice dependency chain and also have an abstraction layer for you to update a contract at a later stage (e.g. if there is a bug fix required).
    • Example: User (Account) -> Smart Contract A (Abstract Contract) -> Smart Contract B (Implementation). In this example, client is not hardwired to Contract A, so even if there is a bug fix needed in the implemention contract, it is possible provided the signature of the contract API does not change
  • Eris describes a 5 model type to categorize smart contracts. If we use the old MVC analogy, contracts can work both as a model (database contract) and a controller. They can also be used to store reference data like one time registration information which other contracts or DApp can look upto.
  • Solidity supports all the usual control structures such as if/else, while, for, break, continue, return. However, there is no support for goto or switch yet.
  • Events are mechanisms in Solidity to alert the outside world of some transaction related activity happening in the contract. They are part of transaction logs and therefore are replicated across the nodes.

Potential Areas of Improvement

  • Better exception handling. There is no try catch mechanism in Solidity yet as sending gas is a one way street from the caller to the contract, therefore caller will have no gas left to do something.
  • At the time of writing this article, an array of string cannot be passed to an external or a public function in Solidity. This is quite a common requirement and feature in a number of languages.
  • Mapping Iterator: Solidity provides a mapping type which is like a hashtable storing a key value format. However, it does not provide an iterator on this, so anybody wishing to traverse a mapping like a list needs to write his/her own iterator.  This could be done through a doubly linked list or a double mapping implementation wherein one stores the key of the original mapping as a value with a sequence as a key in another mapping to get the size of the mapping. Wish it could be made a lot simpler with an iterator.

Security

In context of the recent DAO hack, it becomes even more important for developers to write secure smart contracts and be aware of pitfalls. There are a number of blogs which are highlighting some of the best practices needed while developing Smart Contracts:

References