Code Layout

Code layout refers to the way that your solidity code is structured and formatted. Proper code layout helps to make your code more readable, maintainable, and easy to understand. With respect to solidity code, here are some guidelines to maintain an ideal code layout throughout your code.

1. Indentation

Using 4 spaces for indentation instead of using a tab is considered a good practice. Refer to the right and wrong snippets that are written ahead to understand better.

pragma solidity >=0.4.0 <0.9.0;

// Right Practice for indentation

contract A {

   // …

}

contract B {

   // …

}

contract C {

   // …

}

pragma solidity >=0.4.0 <0.9.0;

// wrong practice for indentation

contract A {

   // …

}

contract B {

   // …

}

contract C {

   // …

}

2. Limit Line Length to 120 Characters

If a line of code exceeds this limit, consider breaking it up into multiple lines. This makes it easier to read the code even on smaller screens. Refer to the right and wrong snippets written ahead to understand better.

// right approach

thisFunctionCallIsReallyLong(

   tempArgument1,

   tempArgument2,

   tempArgument3

);

// Wrong approaches

thisFunctionCallIsReallyLong(tempArgument1,

                             tempArgument2,

                             tempArgument3

);

thisFunctionCallIsReallyLong(tempArgument1,

   tempArgument2,

   tempArgument3

);

thisFunctionCallIsReallyLong(

   tempArgument1, tempArgument2,

   tempArgument3

);

3. Curly Braces

Use curly braces to enclose the bodies of functions, control structures, and contracts. Place the opening curly brace on the same line as the declaration. Place the closing curly brace on a new line. Refer to the right and wrong snippets written ahead to understand better.

pragma solidity >=0.4.0 <0.9.0;

// right practice

import “./Owned.sol”;

contract A {

   // …

}

pragma solidity >=0.4.0 <0.9.0;

// wrong practice

import “./Owned.sol”;

contract A 

{

// …

}

4. Blank Line Between Functions

Add a blank line between the end of a function and the beginning of the next function. Refer to the right and wrong snippets written ahead to understand better.

pragma solidity >=0.6.0 <0.9.0;

// right practice

abstract contract A {

   function spam() public virtual pure;

   function ham() public virtual pure;

}

contract B is A {

   function spam() public pure override {

       // …

   }

   function ham() public pure override {

       // …

   }

}

pragma solidity >=0.6.0 <0.9.0;

// wrong practice 

abstract contract A {

   function spam() virtual pure public;

   function ham() public virtual pure;

}

contract B is A {

   function spam() public pure override {

       // …

   }

   function ham() public pure override {

       // …

   }

}

5. Blank Line Between Different Blocks of Code

Add a blank line between different blocks of code within a function (e.g. between variable declarations and function calls). Refer to the right and wrong snippets written ahead to understand better.

// right practice

uint256 public jobfirst;

doSomething();

// wrong practice

uint256 public jobfirst;

doSomething();

6. Single Space Between Operators and Operands

Never add spaces while declaration involving special characters like (“[]”) etc. Add single spaces between operators and operands. Refer to the right and wrong snippets written ahead to understand better.

// right practice

unit[] a;

a = 7;

a = 100 / 10;

a += 3 + 4;

a |= c && d;

// wrong practice

unit [] a;

a=7;

a = 100/10;

a += 3+4;

a |= c&&d;

7. No Space Between Reserved Keywords

While using reserved keywords never add spaces in between. Refer to the right and wrong snippets written ahead to understand better.

// right practice

mapping(uint => uint) map;

mapping(address => bool) registeredAddresses;

mapping(uint => mapping(uint => s)) data;

// wrong practice

mapping (uint => uint) map;

mapping( address => bool ) registeredAddresses;

mapping(uint => mapping (uint => s)) data;

8. Imports

Imports should be sorted in alphabetical order. The same import should not be repeated. Use the import “./filename”; syntax for external contract dependencies.

// Good
import "./filename1";
import "./filename2";
import "./filename3";
// Bad
import "./filename1";
import "./filename1";
import "./filename3";

9. Order of Functions

Functions should be ordered in the following manner:

  • Constructor.
  • Constant functions.
  • Public state-modifying functions.
  • Internal state-modifying functions.
  • Private state-modifying functions.

// Good

contract Example {

constructor() public { … }

function constantFunc1() public constant returns (…) { … }

function constantFunc2() public constant returns (…) { … }

function publicFunc1() public { … }

function publicFunc2() public { … }

function internalFunc1() internal { … }

function internalFunc2() internal { … }

function privateFunc1() private { … }

function privateFunc2() private { … }

}

// Bad

contract Example {

function internalFunc2() internal { … }

function privateFunc1() private { … }

constructor() public { … }

function constantFunc1() public constant returns (…) { … }

function publicFunc1() public { … }

function internalFunc1() internal { … }

function constantFunc2() public constant returns (…) { … }

function publicFunc2() public { … }

function privateFunc2() private { … }

}

10. Whitespace in Expressions

Use whitespace to increase readability and separate different elements in an expression. Put spaces around binary and ternary operators (e.g. +, -, ? :).

// Good

uint x = (a + b) * c;

uint y = (a > b) ? a : b;

// Bad

uint x=(a+b)*c;

uint y=(a>b)?a:b;

11. Function Declaration

Declare functions using the keyword function, followed by the function name, a list of parameters in parentheses (), and the function body in curly braces {}. Avoid declaring functions with the same name, even if they have different parameters, as this can cause confusion.

// Good

function add(uint a, uint b) public returns (uint) {

return a + b;

}

// Bad

function add(uint a, uint b) {

return a + b;

}

function add(uint a, uint b) public returns (uint) {

return a + b;

}

12. Variable Declarations

Declare variables , followed by the variable name and it’s type. Declare variables as close to their usage as possible, to increase readability. Initialize variables with a default value at declaration if possible.

// Good

function example() public {

uint a = 1;

uint b = 2;

uint c = a + b;

}

// Bad

function example() public {

uint a;

a = 1;

uint b = 2;

uint c = a + b;

}

13. Names to Avoid

Avoid using keywords (e.g. contract, function, etc.) as names for variables, functions, or contracts. Avoid using single-letter names, except for loop indices.

// Good

function addNumbers(uint a, uint b) public returns (uint) { … }

for (uint i = 0; i < 10; i++) { … }

// Bad

function contract(uint a, uint b) public returns (uint) { … }

for (uint x = 0; x < 10; x++) { … }

14. Contracts and Library Names

Name contracts and libraries in a descriptive manner that accurately reflects their purpose. Avoid naming contracts and libraries after their dependencies.

// Good

contract Token { … }

library Math { … }

// Bad

contract ERC20 { … }

library TokenLibrary { … }

Solidity – Style Guide

Solidity is a computer programming language used to create Ethereum smart contracts. These contracts self-execute. The code and the agreements contained therein are enforced by the blockchain network. Solidity is a high-level language, meaning that it is designed to be human-readable and easy to write. It is based on the JavaScript programming language and has a syntax similar to C++. Solidity is a statically-typed language, meaning that variables have a fixed type that must be declared when they are created. It also supports complex data types such as arrays and structs (collections of related variables).
One of the main benefits of Solidity is that it allows developers to build decentralized applications (DApps) on the Ethereum platform. These DApps can be used for a wide range of applications, including supply chain management, voting systems, and financial applications.

In this style guide, we will cover several elements starting with code layout till NatSpec declaration in code, followed by an example for better understanding.

Similar Reads

Code Layout

Code layout refers to the way that your solidity code is structured and formatted. Proper code layout helps to make your code more readable, maintainable, and easy to understand. With respect to solidity code, here are some guidelines to maintain an ideal code layout throughout your code....

Order of layout

Order of layout refers to the recommended order in which different elements of a solidity contract should be organized. It is important to follow a consistent order of layout in order to make the code more readable and easier to understand. This order might vary slightly for different programming languages. This order consists of several optional and mandatory pointers. We’ve tried to cover almost all (both mandatory/optional) elements as per their order of occurrences in the solidity code....

Naming Convention

A naming convention is a set of rules for choosing names for variables, functions, and other important entities in your code. With respect to solidity code, here are some guidelines for the naming convention while writing your code....

NatSpec

NatSpec (Natural Language Specification) is a system for documenting solidity code in a way that is easy for humans to understand. NatSpec comments are written in Markdown format and can be accessed through the Ethereum NatSpec Standard JSON Interface. To add single-line NatSpec documentation to your Solidity code, use double-slash comments (‘//’) followed by the NatSpec tag and the documentation text. And for adding multiple comments (“/**…..*/”) Here’s an example to refer to while writing comments....

Contact Us