solidity comments

Comments are used to explain what the code does. Robert S. Martin (“Uncle” Bob) states that “correct use of comments should compensate for our inability to express something in code.” Therefore, comments make the source code more human-readable.

Why are comments so important when it comes to Solidity? Because they help to understand the work of your smart contract not only for developers, but also for end users.

How to write comments in Solidity?

To write a single line comment, you can use //

// This is a single line comment

For multiline use /* in combination with */

/* 
This is a
multi-line comment
*/

Solidity Documentation says:

A single-line comment is terminated by any Unicode end-of-line character (LF, VF, FF, CR, NEL, LS, or PS) encoded in utf-8. The line terminator is still part of the code that comes after the comment. So if it is not an ascii character (i.e. NEL, LS and PS) it will result in a parser error.

Different types of comments in Solidity

There are two main types of comments in Solidity: normal and comments NatSpec. So, for example, in the Remix IDE they can be recognized by different colors (green is used for regular comments, and blue for comments NatSpec).

What are NatSpec comments?

Solidity contracts have a special form of comments that form the basis of the Ethereum natural language specification format(Ethereum Natural Language Specification Format)also known as NatSpec. NatSpec developed and distributed by the Ethereum team.

Comment Format NatSpec matches the notation style Doxygen:

  • For single line comments use ///

  • For multiline comments use /** in conjunction with */

  • Comments are used before declaration function, contract, libraryinterface, function And constructor

/// This is a Natspec single line comment
/**
This is a 
Natspec multi-line
comment block
*/

Important! NatSpec comments do not apply to variables. Even if they are declared publicly and therefore affect the ABI. Details

Using Doxygen Tags with NatSpec

For maximum benefit, working with NatSpec you should use Doxygen tags.

Doxygendocumentation generator software. Documentation is generated by parsing comments in code.

Code snippet below (from documentation Solidity) shows how these tags are used. Doxygen tags start with @ and are used to explain, for example:

  1. Title of the contract (in a more human-readable form)

  2. What does the function do rectangle

  3. What are the parameters for? w And h(rectangle width and height)

  4. What will the function return: s(area) and p(perimeter)

pragma solidity >=0.4.0 <0.7.0;

/** @title Shape calculator. */
contract ShapeCalculator {
    /** @dev Calculates a rectangle's surface and perimeter.
      * @param w Width of the rectangle.
      * @param h Height of the rectangle.
      * @return s The calculated surface.
      * @return p The calculated perimeter.
      */
    function rectangle(uint w, uint h) public pure returns (uint s, uint p) {
        s = w * h;
        p = 2 * (w + h);
    }
}

You can use Doxygen with comments NatSpec as a documentation tool. However, keep in mind that only 6 Doxygen tags are available in Solidity:

All of these tags are optional, but using them has the following advantages:

  • Allows you to document functions, constructors, contracts, libraries and interfaces

  • Provide data for the user interface (displays the confirmation text that is shown to users when they try to call a function).

Note: Currently, NatSpec only interprets tags if they are applied to external or public values. You can still use them for your internal and private functions, but they won’t be parsed.

There are two main tags to keep in mind:

  • @notice: information about what the function does, which is shown to the user at run time

  • @dev: developer documentation

If no tags are used (for example, only ///), then the entire message is applied with the tag @notice

Tag @noticeperhaps the most important tag in NatSpec. It is intended for those who have never seen the source code. Therefore, information about implementation details of the code should be avoided.

Here is another example of using Doxygen tags in a smart contract SimpleStorage from Solidity documentation:

pragma solidity >=0.4.0 <0.7.0;

/// @author The Solidity Team
/// @title A simple storage example
contract SimpleStorage {
    uint storedData;

    /// Store `x`.
    /// @param x the new value to store
    /// @dev stores the number in the state variable `storedData`
    function set(uint x) public {
        storedData = x;
    }

    /// Return the stored value.
    /// @dev retrieves the value of the state variable `storedData`
    /// @return the stored value
    function get() public view returns (uint) {
        return storedData;
    }
}

tags @param And @return have the following specification:

  • After @param must be the name of the variable that was used in the function

  • After @return must be the name or type of the variable that the function returns

If your function returns multiple values, then you should use @return for each value separately (similar to @param).

A good example of a Solidity contract that elegantly uses NatSpec comments with Doxygen is the library Buffer by Oraclize (created and used by them for their API). You can see how well the features are documented append And appendInt using the tag @dev, which explains exactly what each function does. Finally, tags @param And @return help you understand how the function behaves.

Creating Documentation with NatSpec: An Introduction

The Solidity compiler automatically generates a JSON (contract metadata) file that contains information about the compiled contract. You can use this file to query the compiler version, sources used, ABI and NatSpec documentation for safer interaction with the contract and verification of its source code. More

In other words, this JSON file includes the compiler version, ABI, and documentation NatSpec. User and developer documentation NatSpec will appear at the end of the metadata file, under output (right below the ABI):

{
  version: "1",
  language: "Solidity",.
  compiler: {
    ...
  },
  sources:
  {
    ...
  },
  settings:
  {
    ...
  },
  output:
  {
    abi: [ ... ],
    userdoc: [ ... ],
    devdoc: [ ... ],
  }
}

Solidity Compiler solc can generate two types of documentation (in JSON format) after compiling your smart contract:

  1. Developer Documentation: solc --devdoc my_contract.sol

  2. User Documentation: solc --userdoc my_contract.sol

Creating Documentation with NatSpec: Getting Ready

Now, let’s see how the Solidity compiler generates our smart contract documentation. For this you need a compiler solc (installation instructions). Once installed, open your terminal and follow the instructions below:

  1. Create a new folder (eg NatSpec) and go into it: $ mkdir Natspec && cd Natspec

  2. Create a new Solidity file: $ nano natspec.sol

  3. Paste the code below:

pragma solidity ^0.5.0;
/// @title A Geometry triangle simulator
/// @author Jean Cavallera
/// @notice Use this contract for only the most basic simulation
/// @dev Contract under development to enable floating point
contract Geometry {
    
    struct Triangle {
        uint side_a;
        uint side_b;
        uint hypothenuse;
    }
    
    /// @notice Math function to calculate square root
    /// @dev Not working with decimal numbers
    /// @param x The number to calculate the square root of
    /// @return y The square root of x
    function sqrt(uint x) internal pure returns (uint y) {
            uint z = (x + 1) / 2;
            y = x;
            while (z < y) {
                y = z;
                z = (x / z + z) / 2;
            }
        }
    
    /// @notice Calculate the hypothenuse length based on x and y
    /// @dev Not working as it returns integers and not float
    /// @param _a Side 1
    /// @param _b Side 2
    /// @return uint the hypothenuse length
    function calculateHypothenuse(uint _a, uint _b) public pure returns (uint) {
        return sqrt((_a * _a) + (_b * _b));
    }
    
    Triangle public my_triangle;
    
    /// @author Jean Cavallera
    /// @notice Enter the two legs of your right angle triangle
    /// @dev This function modifies the state of the variable `my_triangle` and use `calculateHypothenuse()` function
    /// @param _a Side 1
    /// @param _b Side 2
    /// @return string return to user a custom success message
    function createTriangle(uint _a, uint _b) public returns (string memory) {
        my_triangle = Triangle ({
            side_a: _a,
            side_b: _b,
            hypothenuse: calculateHypothenuse(_a, _b)
        });
        return "new triangle created";
    }
    
    
}

Creating Documentation with NatSpec: Developer Documentation

Enter the following command:

solc — devdoc natspec.sol

You should get something like this:

{
  "author" : "Jean Cavallera",
  "details" : "All function calls are currently implemented without side effects",
  "methods" :
  {
    "calculateHypothenuse(uint256,uint256)" :
    {
      "details" : "Not working as it returns integers and not float",
      "params" :
      {
        "_a" : "Side 1",
        "_b" : "Side 2"
      },
      "return" : "uint the hypothenuse length"
    },
    "createTriangle(uint256,uint256)" :
    {
      "author" : "Jean Cavallera",
      "details" : "This function modifies the state of the variable `my_triangle` and use `calculateHypothenuse()` function",
      "params" :
      {
        "_a" : "Side 1",
        "_b" : "Side 2"
      },
      "return" : "string return to user a custom success message"
    }
  },
  "title" : "A Geometry triangle simulator"
}

Let’s take a closer look at this file:

  • the keys are the Doxygen tags we used before: @title, @autor, @param And @return . The only difference is the value of the details key, which is taken from the tag @dev.

  • the key values ​​correspond to the description of the tags from the NetSpec comments.

There are two more important things about the section devdoc in ABI:

  • the function includes the types of the passed arguments (example: "createTriangle(uint256,uint256)")

  • only public functions are shown. So, for example, a private function sqrt(uint x) missing from the final file.

NatSpec generates documentation only for public And external functions

We mentioned this earlier. Here’s what the Solidity documentation says:

(Solidity documentation): NatSpec currently only interprets tags if they apply to external or public functions. You can still use similar comments for your internal and private functions, but they won’t be parsed.

Creating Documentation with NatSpec: User Documentation

Run the following command:

solc --userdoc natspec.sol

You should get something like this:

{
    "methods" : 
  	{
      "calculateHypothenuse(uint256,uint256)" :
      {
        "notice" : "Calculate the hypothenuse length based on x and y"
      },
      "createTriangle(uint256,uint256)" :
      {
        "notice" : "Create a new right angle triangle using two right angle sides and calculate the hypothenuse dynamically"
      }
    },
    "notice" : "Use this contract for only the most basic simulation"
  }

As we can see, we still have the function name with its parameters, as well as the tag @notice for both contracts and functions.

Example: Developer documentation in Remix

Using Doxygen tags is especially handy if you are working with Remix.

The new version of Remix contains plugins that extend its core functionality. A very useful feature is the “Documentation File Generator in Markdown”. It generates a Markdown contract generation based on NetSpec comments.

  1. Open Remix. Click on the button “plugin manager”.

  2. Find “Solidity Document Generator” and activate the plugin.

  3. A new icon will appear on the left side of the interface. Click on it and select the contract for which you want to create documentation.

The plugin will generate documentation in Markdown format. It looks something like this:

Example: user documentation for displaying a message in the UI

Wallet can use user documentation NatSpec to display a confirmation message to the user whenever they interact with the contract, along with an authorization request to sign the transaction.

Example: dynamic messages

/// @notice Send `(valueInmGAV / 1000).fixed(0,3)` GAV from the account of 
/// `message.caller.address()` to an account accessible only by `to.address()`
function send(address to, uint256 valueInmGAV) {
...
}

If the user (for example, with the address 0x2334) will try to call this function with to = 0x0 And valueInmGAV=4.135then he will see:

Send 4.135 GAV from the account of 0.2334 to an account accessible only by 0x0

The code enclosed in back quotes will be executed in the EVM Javascript environment, which has access to message and all function parameters. So you can use any expression Javascript/Paperscript to create custom messages.

Atom plugin to auto-generate NatSpec comments

NodeFactory.io developed Atom plugin – solidity comments. It contains the basic functions to generate all template documentation for your Solidity smart contract. It can be used by pressing the following key combination: Ctrl + Alt + G.

For example, let’s say you have the following code:

pragma solidity 0.4.24;

contract SomeContract {

    function test(uint _param1, uint _param2) external {
        require(_param1 == 1 && _param2 == 2);
    }
}

Click Ctrl + Alt + G and you will get:

pragma solidity 0.4.24;

/// @title SomeContract
/// @notice
/// @dev
contract SomeContract {

    /// @notice
    /// @dev
    /// @param _param1
    /// @param _param2
    /// @return
    function test(uint _param1, uint _param2) external {
        require(_param1 == 1 && _param2 == 2);
    }
}

It remains only to fill in the empty tags.

Links

  1. Difference between /* and /**

  2. Ethereum Wiki

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *