Smart Contract for Beginners and Tougher
Have you ever wondered — can I write my own cosy smart contract? With fair and clean logic, to carry out my business dreams? We glad to announce that yes, you can [under some conditions, as n-years of experience in software development, sorry for that]. Leaving alone the step-by-step guide of how to build my first smart-contract, we will instead provide you with some tips derived from our experience.

In such intimidating activity as developing a contract, however smart it be, you need to consider some details. We will address Solidity smart contracts as one of the most popular type across many blockchains.

Generally speaking, smart contract development on Solidity is the same as in any other Turing-complete programing language — you think up the logic and implement it in mostly traditional way. The most interesting part is the environment in which contact will be deployed and executed. Ethereum Virtual Machine is a part of a blockchain network with lots of tiny but significant details to bear in mind. We present brief but hopefully instructive list of such details.

Deployment and block-size

Transactions in Ethereum are always limited in size by gas limit of a block. Taking into account that smart contract deployment is also a transaction we can find impossible to deploy two, or even one big contract at once. To solve this issue we usually deliberately split the system of smart contracts in logical parts optimized by size so that deployment could be done in several subsequent transactions. The most important part is to interconnect these parts. For that we need to deploy one smart contract at a time and provide the address of deployed part to the next smart contract’s constructor. Thus we can deploy a smart contract system of arbitrary complexity. A platform allowing to create tokens with customizable dividend distribution, for instance.

Gas optimization

Other side of gas-driven blockchain is optimization of smart contract operation. Each ‘write’ method of a smart contract requires number of Solidity opcodes to be executed. And each opcode has a price in gas, meaning real money. Due to that ‘clean code’ that is efficient and simple gets new dimension of being literally less expensive. One wants to save each dime whether own or clients. Solidity is the battlefield of operational efficiency and cost on one side, and the job being done at all on the other.

In some cases required amount of gas can be greater than gas limit of a block [ and some times greater than one’s total fundings, but we omit such cases ], i.e. when airdrop to 1 million of addresses need to be executed. If such transaction will be initiated, it won’t be executed due to gas limits of the network. To handle such cases pagination of transactions can be implemented. The code initiates transactions execution in bunches, e.g. 1 000 at a time. And when they are done, go to the next bunch. It makes smart contract heavier and logic becomes somewhat complex with addition of counters and checkers. But sometimes it is the only way to carry out the job. As everything in smart contracts development, such functionality requires good deal of design and testing because once deployed, code can’t be changed.

Solidity code peculiarities

The language itself has a lot in stock for adventurous developers. To name a few, one wouldn’t like to use simple ‘+’, ‘-’, etc. signs. If one consider to — funny things may happen, like addition of two uint256 variables which combined value may cause variable overflow. To save the day, SafeMath library methods must be used instead. They protect the integrity of the smart contract universe on the fundamental level of Math.

Another funny thing is that Solidity map structure can not return the array of it’s keys. It was made to allow big map structures to be stored in a smart contract but have a couple of interesting side effects: non-deterministic behavior when telling whether an element is in it or not. When one requests what value corresponds to ‘a’ key is in a map and it returns ‘0’ no one can tell whether key exists and it’s value is ‘0’, or there are no such key is the map.

On the other hand, if one knows for sure that the key is in a map — system becomes deterministic. So to implement deliberate access to a map by key duplicates of keys need to be stored in a separate array structure at the moment of writing key-value pair in it.

No native method to get map length. If such functionality is required, approach similar to mentioned can be implemented, but with ids array of integers, each element representing latest written key-value order. i.e. 0 for the first key-value, 1 for the second, etc.

Both cases are rather expensive in terms of gas, and we address them only when it is really necessary.

Finally, one funny fact about Solidity variables. We always want to minimize the size of smart contract and one may think that assigning uint8 or uint32 type instead of uint256 saves us something. But it is exactly opposite — under-the-hood Solidity converts all numbers to uint256 type making usage of uint8 more expensive due to conversion opcode costs. This example nicely illustrates that smart contract development only seems to be straightforward.

Of course, we have just skimmed over the thing. Real-life projects are much more complex and require close and constant attention to every detail and at every step. But hopefully one got useful hints regarding this amazing world of decentralized logic execution. Give us a big hand if you want more. Drop us a line if you need some really smart contract.
['Maxim Prishchepo']
['Solidity', 'Smart Contracts', 'Blockchain', 'Ethereum', 'Technology']