A style guide is about consistency. Consistency with this style guide is important. Consistency within a project is more important. Consistency within one module or function is most important.
But most importantly: know when to be inconsistent -- sometimes the style guide just doesn't apply. When in doubt, use your best judgment. Look at other examples and decide what looks best. And don't hesitate to ask!
***********
Code Layout
***********
Indentation
===========
Use 4 spaces per indentation level.
Tabs or Spaces
==============
Spaces are the preferred indentation method.
Mixing tabs and spaces should be avoided.
Blank Lines
===========
Surround top level declarations in solidity source with two blank lines.
Yes::
contract A {
...
}
contract B {
...
}
contract C {
...
}
No::
contract A {
...
}
contract B {
...
}
contract C {
...
}
Within a contract surround function declarations with a single blank line.
Blank lines may be omitted between groups of related one-liners (such as stub functions for an abstract contract)
Yes::
contract A {
function spam();
function ham();
}
contract B is A {
function spam() {
...
}
function ham() {
...
}
}
No::
contract A {
function spam() {
...
}
function ham() {
...
}
}
Source File Encoding
====================
UTF-8 or ASCII encoding is preferred.
Imports
==========
Import statements should always be placed at the top of the file.
Yes::
import "owned";
contract A {
...
}
contract B is owned {
...
}
No::
contract A {
...
}
import "owned";
contract B is owned {
...
}
Whitespace in Expressions
=========================
Avoid extraneous whitespace in the following situations:
* Immediately inside parenthesis, brackets or braces.
Yes: `spam(ham[1], Coin({name: "ham"}));`
No: `spam( ham[ 1 ], Coin( { name: "ham" } ) );`
* Immediately before a comma, semicolon:
Yes: `function spam(uint i, Coin coin);`
No: `function spam(uint i , Coin coin) ;`
* More than one space around an assignment or other operator to align with
another:
Yes::
x = 1;
y = 2;
long_variable = 3;
No::
x = 1;
y = 2;
long_variable = 3;
Control Structures
==================
The braces denoting the body of a contract, library, functions and structs
should:
* open on the same line as the declaration
* close on their own line at the same indentation level as the beginning of the
declaration.
* The opening brace should be proceeded by a single space.
Yes::
contract Coin {
struct Bank {
address owner;
uint balance;
}
}
No::
contract Coin
{
struct Bank {
address owner;
uint balance;
}
}
The same recommendations apply to the control structures `if`, `else`, `while`,
and `for`.
Additionally there should be a single space between the control structures
`if`, `while`, and `for` and the parenthetic block representing the
conditional, as well as a single space between the conditional parenthetic
block and the opening brace.
Yes::
if (...) {
...
}
for (...) {
...
}
No::
if (...)
{
...
}
while(...){
}
for (...) {
...;}
For control structures who's body contains a single statement, omitting the
braces is ok *if* the statement is contained on a single line.
Yes::
if (x < 10)
x += 1;
No::
if (x < 10)
someArray.push(Coin({
name: 'spam',
value: 42
}));
For `if` blocks which have an `else` or `else if` clause, the `else` should be
placed on it's own line following the previous closing parenthesis. The
parenthesis for the else block should follow the same rules as the other
conditional control structures.
Yes::
if (x < 3) {
x += 1;
}
else {
x -= 1;
}
if (x < 3)
x += 1;
else
x -= 1;
No::
if (x < 3) {
x += 1;
} else {
x -= 1;
}
Function Declaration
====================
For short function declarations, it is recommended for the opening brace of the
function body to be kept on the same line as the function declaration.
The closing brace should be at the same indentation level as the function
declaration.
The opening brace should be preceeded by a single space.
Yes::
function increment(uint x) returns (uint) {
return x + 1;
}
function increment(uint x) public onlyowner returns (uint) {
return x + 1;
}
No::
function increment(uint x) returns (uint)
{
return x + 1;
}
function increment(uint x) returns (uint){
return x + 1;
}
function increment(uint x) returns (uint) {
return x + 1;
}
function increment(uint x) returns (uint) {
return x + 1;}
The visibility modifiers for a function should come before any custom
modifiers.
Yes::
function kill() public onlyowner {
selfdestruct(owner);
}
No::
function kill() onlyowner public {
selfdestruct(owner);
}
For long function declarations, it is recommended to drop each arguent onto
it's own line at the same indentation level as the function body. The closing
parenthesis and opening bracket should be placed on their own line as well at
the same indentation level as the function declaration.
Yes::
function thisFunctionHasLotsOfArguments(
address a,
address b,
address c,
address d,
address e,
address f,
) {
do_something;
}
No::
function thisFunctionHasLotsOfArguments(address a, address b, address c,
address d, address e, address f) {
do_something;
}
function thisFunctionHasLotsOfArguments(address a,
address b,
address c,
address d,
address e,
address f) {
do_something;
}
function thisFunctionHasLotsOfArguments(
address a,
address b,
address c,
address d,
address e,
address f) {
do_something;
}
If a long function declaration has modifiers, then each modifier should be
dropped to it's own line.
Yes::
function thisFunctionNameIsReallyLong(address x, address y, address z)
public
onlyowner
priced
returns (address)
{
do_something;
}
function thisFunctionNameIsReallyLong(
address x,
address y,
address z,
)
public
onlyowner
priced
returns (address)
{
do_something;
}
No::
function thisFunctionNameIsReallyLong(address x, address y, address z)
public
onlyowner
priced
returns (address) {
do_something;
}
function thisFunctionNameIsReallyLong(address x, address y, address z)
public onlyowner priced returns (address)
{
do_something;
}
function thisFunctionNameIsReallyLong(address x, address y, address z)
public
onlyowner
priced
returns (address) {
do_something;
}
For constructor functions on inherited contracts who's bases require arguments,
it is recommended to drop the base constructors onto new lines in the same
manner as modifiers if the function declaration is long or hard to read.