Create a style and stick to it

All of us start from zero. We take the right decision and become a hero. ~ Govinda

Creating a style is proven to be a good way to reduce headaches and improve success. Well, besides being proven or not, the fact is, it does.

If you don’t know or you’ve never used a style guide before, now is the time!

A style guide consists of defining a set of rules and applying them. Those rules can vary from coding style to filename style, git branch naming style, you name it. Basically, anything that can be done in multiple ways, it makes sense to define a style guide for your project.

By doing so, everyone working on your project follows the same standard.

We will see how OpenZeppelin follows a standard, and how you can also do the same.

We also cover some specific tools but it’s up to you to decide what tools you use and how to use them.

Defining a style guide

Either you are working with something really new, or, most likely, there’s already a standard.

Take the example of some well-known languages. There’s a standard for:

Of course, there’s already a style guide for Solidity which you can follow: https://solidity.readthedocs.io/en/latest/style-guide.html.

But let’s say you don’t really follow some of these rules. For example, in JavaScript, there’s often the fight between having or not the semicolon at the end of a statement. Also, whether to have spaces after keywords such as if, switch and while. The number of spaces is also a common rule that varies. I prefer 4 spaces, as it’s easier for me to read. Some people prefer 2 spaces.

Now, let’s assume you’ve written a document, declaring all the rules to follow. Developers will look at them and just follow, you might think. Of course, it is not going to happen that easily. We are humans, it’s easy to make mistakes, forget about doing important things, etc.

Instead of hiring someone to just read code and fix the not respected rules, we can use a linting tool and automate the steps. Even better, we can show warnings in the Integrated Development Environment (IDE).

Use the right tool

A linter is a tool that runs over the code and verifies that a given list of rules is respected. Considering JavaScript code and our defined JavaScript rules, we can then choose a tool to do the verification for us.

ESLint

One of the most common linters, and also the one used by OpenZeppelin, is ESLint.

To define the rules with ESLint, you need an .eslintrc file in the project’s root directory, then define the rules and then analyze the code.

Let’s put this into easy steps:

  1. Create a directory and then start a new project within it (with npm init -y)
  2. Install ESLint (with npm install --save-dev eslint)
  3. Define a .eslintrc file (use the example below)
  4. Create some code (use the example below)
  5. Analyze (with npx eslint .)

.eslintrc

{
    "rules": {
        "quotes": [
            "error",
            "single"
        ]
    }
}

index.js

var msg = "hello";
console.log(msg);

When analyzing the code, it will show you an error, because you’ve used double quotes on a string, when the rules say to use a single quote, and if not, show an error.

(path)/index.js
1:11 error Strings must use singlequote quotes
✖ 1 problem (1 error, 0 warnings)
1 error and 0 warnings potentially fixable with the `--fix` option.

You can improve this process even more by showing the warnings and errors in the IDE. The ESLint website shows all the available integrations: https://eslint.org/docs/user-guide/integrations.
After installing the integration, you might need to reload the IDE, and then you will get the errors displayed.

And you can easily fix it by clicking Quick Fix, or in a lamp icon when it appears.

Let’s consider now, that you want to use the JavaScript standard rules. First, you need to change the .eslintrc to extend from the standard rules. Then, install the dependencies to get those rules.

.eslintrc (updated)

{
    "extends" : [
        "standard"
    ]
}

Then install the required dependencies with:
npm install --save-dev eslint-config-standard eslint-plugin-import eslint-plugin-node eslint-plugin-promise eslint-plugin-standard

Analyze again and you will now get different errors. That is because the rules have changed.

Of course, these are standard rules, and you can change rules suited to the specific needs of your project.

Looking at the OpenZeppelin Contracts repository, you can see what rules OpenZeppelin have made changes to in .eslintrc.

Solidity linter

Of course there is a linter for Solidity. In fact, there’s more than one.
We will look at solhint, which is the linter used by OpenZeppelin.

To make solhint work, the process is similar to the one shown above for ESLint.

First, install solhint with npm install --save-dev solhint
Then add a .solhint.json file and extend the recommended solhint rules, as shown below

.solhint.json

{
    "extends": "solhint:default",
}

And finally analyze with npx solhint (e.g. npx solhint “contracts/**/*.sol”)

Most of the IDE extensions for Solidity support solhint the same way they support ESLint. e.g. https://github.com/juanfranblanco/vscode-solidity#solhint

OpenZeppelin documents the coding style they use in CODE_STYLE.md.

Git

You can implement style guides for git branch naming. e.g. OpenZeppelin have documented branch naming in the workflow section of their contribution guide.

There is also a well-known convention regarding git branch naming.

File names

But wait there’s more. What about file name conventions? There are plenty to choose from.

Take the OpenZeppelin example:

  • Camel case for directory names
  • Pascal case for file names (if it’s a Solidity or JavaScript file).
    For script files, it’s snake case.
  • Files have extensions and test files have .test.js extension

Though (like me) you could also use .spec.js rather than .test.js.

Conclusion

Create a style for your project, and stick to it using automated tools such as linters.

This will make life much easier for users, contributors and auditors reading your code.

OpenZeppelin have defined their style, so it is a great place to start if you haven’t defined your own.

You can also add linting to your Continuous Integration process (see my Test smart contracts like a rockstar article).

Thanks to the OpenZeppelin community and especially to @abcoathup for reviewing, fix typos and make suggestions. Thank you so much.

Remember, make decisions and stick to them.

7 Likes

Prettier is a great tool to make code styled in the same way. We use it at OpenZeppelin and I highly recommend it.

1 Like