Building a smart contract is hard, but building it the right way is even harder, here are 9 tips to get you started.

Be lazy, do not reinvente the wheel

The Ethereum smart contract ecosystem is composed of many awesome people who may already have solved the problem you currently have. Instead of writing code that you could easily reuse, use some kind of library.

I personally prefer to use OpenZeppelin, their code is widely used and audited by various projects. They have components covering the creation of ERC20 and ERC721 tokens as well as crowdsales or more specific use-cases like access control, cryptography or even the lifecycle of a contract. So instead of retyping each times 100 lines to do an ERC721 token you could just reuse what’s already available and widely used.

Example of an ERC721 token with OpenZeppelin (taken from their GitHub repository).

Use solidity

Solidity is the default language when you write a smart contract, there are others but you should forget about them for many reasons:

Solidity was built for the Ethereum platform

Most if not all the components you will want to reuse are made in Solidity

There are many tools built for Solidity to help you build, test and verify a contract such as Truffle

If you have a problem or a bug it will be easier to find help

It is very easy to learn and use!

Test your code before writing it

Whenever you write code you need to write tests for it. For smart contracts it is even more important, the code will handle money and you want to minimize costly mistakes.

The best way to do that is to use a framework like the previously mentioned Truffle which will make it easier to write tests. Even better, you should write your tests before writing your code. This helps you clearly define your objectives and avoid having a biased point of view which could make you take some shortcuts, which would later lead to critical mistakes.

Test your contract before using it

Even when your contract is done and 100% tested you should deploy on a test network and ask a few people to use it (and try to break it). They will spot what you forgot or help figuring out what you missed when coding.

Avoid loops

Don’t use for or while loops, don’t use recursive function calls.

Loops in a smart contract should be avoided whenever it is possible. Loops means you are doing heavy computation in your contract and might make it very expensive to run. Also you may not know when a loop ends and would consume all the gas paid to execute the transaction before your code completed (thus making the transaction fail). Plus it is harder to debug.

Move what you can do off-chain outside of your contract

Running and storing a smart contract is extremely expensive, smart contracts are also harder to upgrade than frontend’s code. So if you can do something on the frontend side of your DAPP (Decentralized Application) do it. This will make your contract tinier, cheaper and easier to code, maintain and understand.

Be modular

Bad or monolithic code is very hard to maintain. You should rather use a very modular code by avoiding code duplication and isolating the different components (makes testing easier).

Organization of OpenZeppelin’s crowdsale contracts.

A good example would OpenZeppelin’s crowdsale contracts, they have a main contract and then take the different components away from this one. For instance they isolated and modularized the logic to control the distribution, the emission, the price and validation of the sale. If you want a specific validation logic you could write this specific component and use the standard ones for the other parts. Now, if you look at the sample sale contract you can see components are easily plugged together (like LEGOs), you end with an extremely clean and easy to understand code.

Example of crowdsale contract.

Having isolated components makes them very easy to test, in the case of the sales contracts the OpenZeppelin team is testing each components without the others, this makes the tests smaller and easier to use. If you had a contract for each kind of sales (which means a lot of code being duplicated) you would have to write very long tests and repeat them for each use-case.

Optimize

We already said contracts are expensive to store and use. Whenever possible you should reduce the amount of code needed to perform an operation, less code means less instructions to execute which then means less costs to execute the transactions. If your contract is well optimized it will also be easier to maintain.

Audit

Your contracts will see and use money, if you are serious about your project you should hire someone to audit them and find weaknesses you aren’t seeing.

You don’t want to end like the parity wallet or The Dao.