15 Tips to Write Better Smart Contracts
Photo by Moose Photos from Pexels

15 Tips to Write Better Smart Contracts

By alexroan | Blockchain Developer | 25 Apr 2020


1. Define the Purpose

Before starting, make sure you have a clear understanding of what your smart contract is supposed to do. What value does it add? How should it be used? Consider the question of whether or not it even needs to be a blockchain application. Would it be better implemented on more well-established technology platforms?

Have a clear view of the purpose of your smart contract.

2. Check if It Has Been Done Before

Never spend the time rewriting something that already exists. If what you’re trying to create is a different flavour of an existing concept, consider extending work that has been done by others.

Don’t reinvent the wheel.

Openzeppelin provides a library of contracts that implement EIPs like ERC-20, and ERC-721. Utilise these by extending their functionality instead of writing your own from scratch.

3. Name It

Having a clear purpose should make naming your smart contract easy. If you have experience developing in object-oriented languages, name it as you would a class.

Names should be clear, descriptive, and succinct. It should have as few words as possible, ideally one or two. It should describe what the contract is, what it does, and indicate what it’s responsible for.

4. Chose Your Development Environment

If you’ve had experience developing software already, you’ll likely have a preferred IDE to code in. Multiple IDEs support Solidity development. My favourite is VS Code, a free text editor created by Microsoft, with the Solidity extension.

If you’re less experienced and don’t want to have to worry about setting up your environment, Ethereum provides a great online IDE called Remix. It allows you to start coding, compiling, and deploying immediately.

5. Is It a Standalone Smart Contract?

Sometimes smart contracts get very long and very complicated. If your contract has so many responsibilities that the name doesn’t describe everything it does, consider separating concerns and using multiple smart contracts.

If you expect your project to span across multiple smart contracts, consider using Truffle Suite as the framework for your project. Truffle makes it easy to write DApps on top of your contract.

6. Chose Solidity Version

Find out the latest stable version of Solidity and familiarise yourself with its syntax. If you’re extending libraries, make sure your chosen version isn’t ahead of the version that the libraries support.

For example, Openzeppelin contracts library version 0.2.5 supports Solidity version 0.5.5, but not 0.6.x.

7. Does It Do Any Maths?

If you expect your smart contract to perform mathematical calculations, refrain from using arithmetic operators like plus(+), minus(-), multiply(*), divide(/), and modulus (%). Without proper checks, they have the potential to introduce underflow and overflow vulnerabilities.

Use Openzeppelin’s SafeMath library for unsigned integer operations.

pragma solidity ^0.5.5;

import "@openzeppelin/contracts/math/SafeMath.sol";

contract BasicSafeMath {

  using SafeMath for uint;
  
  function doSomeMath(uint _a, uint _b) public returns (uint) {
    return _a.sub(_b);
  }
}

Example usage of SafeMath to subtract one integer from another

8. Restrict Access to Some Functions

Most smart contracts will need access restrictions on functions that only the owner of the contract should be able to invoke. A commonly used pattern for this is the onlyOwner pattern. This is where a custom modifier requires that the caller of the function is equal to the owner address.

To save writing your own logic for this, Openzeppelin provides a contract called Ownable, which you can extend in your code.

pragma solidity ^0.5.5;

import "@openzeppelin/contracts/ownership/Ownable.sol";

contract OwnableContract is Ownable {

  function restrictedFunction() public onlyOwner returns (uint) {
    return 99;
  }

  function openFunction() public returns (uint) {
    return 1;
  }

}

Example usage of onlyOwner to restrict function access.

9. Send Value Safely

If you expect your smart contract to send Ether or ERC-20 tokens to other addresses, you must consider the vulnerabilities that can introduce. Reentrancy attacks are well known throughout the industry due to high-profile hacks over the past few years.

Always use transfer() instead of call() when sending Ether, and never assume that address you’re sending to is a good actor.

10. Reduce Complexity

Functions should be concise and self-explanatory. Any functions which look too large, or perform nested loops or recursion should be revisited. More computation means more gas, meaning it costs more to perform those functions.

Consider off-chain computing to take some load off your blockchain application. For example, decentralised exchanges use off-chain order filling algorithms to fill orders, since the algorithm is quite complex. Once an order is filled, the settlement is performed on the blockchain.

If reducing complexity is too difficult, consider the possibility that blockchain may not be the ideal solution to your problem.

11. Save Space

Are there any variables that will never fill their data type size? If so, you should be able to reduce the amount of space your smart contract uses by changing the data type.

If all of your integer values are uint data type, but some only ever reach a maximum value of 100, consider uint8. It has a maximum value of 255.

Openzeppelin provides a library called SafeCast that casts integer values down to smaller data types.

pragma solidity ^0.5.5;

import "@openzeppelin/contracts/math/SafeCast.sol";

contract BasicSafeCast {

  using SafeCast for uint;
  
  function castToUint8(uint _a) public returns (uint8) {
    return _a.toUint8();
  }
}

Example usage of SafeCast to cast a uint variable to uint8

12. Test Thoroughly

Make sure you write as many tests as possible. Account for every possible scenario occurring and test every code path to ensure the expected result happens every time.

As well as testing on your local blockchain, deploy and test on as many Testnets as possible. These mimic the Mainnet environment more closely, so are a better representation of how your app will perform once live.

13. Show Others

Making code available for others to see is valuable.

Having a fresh set of eyes, not hampered by tunnel vision, often catches bugs that slip through the developer’s net. Second opinions and expert advice are very valuable tools, so use them where possible. They have the benefit of making your more critical of your work before you allow yourself to show it to others.

You could also write thorough documentation or articles about your smart contracts to explain them to others. This will help them understand the underlying concepts of your work and will aid them in hunting any bugs you might have introduced.

14. Consider How It Could Be Exploited

Think like a bad actor.

Think about how you would try to exploit the smart contract if you wanted to steal its funds or render it useless. Ask yourself where your smart contract is vulnerable and how you can mitigate the risks.

Use auditing services and static code analysis tools if necessary.

15. Make Sure It Works

Finally, does it do what you expect it to do? Ask yourself if it serves the purpose you envisaged when you set out from the beginning. Can you write an application front end, turning your smart contract into a full DApp?


Learn More

If you’re interested in Blockchain Development, I write tutorials, walkthroughs, hints, and tips on how to get started and build a portfolio. Check out this evolving list of Blockchain Development Resources.

If you enjoyed this post and want to learn more about Smart Contract Security, Blockchain Development or the Blockchain Space in general, I highly recommend signing up to the Blockgeeks platform. They have courses on a wide range of topics in the industry, from Coding to Marketing to Trading. It has proven to be an invaluable tool for my development in the Blockchain space.

 

How do you rate this article?


40

1

alexroan
alexroan

Blockchain Developer


Blockchain Developer
Blockchain Developer

Tutorials, walkthrough, hints and tips on Blockchain Development for all levels of expertise.

Send a $0.01 microtip in crypto to the author, and earn yourself as you read!

20% to author / 80% to me.
We pay the tips from our rewards pool.