2017-06-19 10:02:03 +00:00
|
|
|
********************************
|
2015-12-07 20:16:25 +00:00
|
|
|
Layout of a Solidity Source File
|
|
|
|
********************************
|
|
|
|
|
2018-09-13 16:29:14 +00:00
|
|
|
Source files can contain an arbitrary number of
|
2019-12-12 15:19:09 +00:00
|
|
|
:ref:`contract definitions<contract_structure>`, import_ directives,
|
|
|
|
:ref:`pragma directives<pragma>` and
|
2020-06-16 16:20:37 +00:00
|
|
|
:ref:`struct<structs>`, :ref:`enum<enums>` and :ref:`function<functions>` definitions.
|
2018-09-13 16:29:14 +00:00
|
|
|
|
2020-05-13 14:53:54 +00:00
|
|
|
.. index:: ! license, spdx
|
|
|
|
|
|
|
|
SPDX License Identifier
|
|
|
|
=======================
|
|
|
|
|
|
|
|
Trust in smart contract can be better established if their source code
|
|
|
|
is available. Since making source code available always touches on legal problems
|
2020-07-31 14:53:12 +00:00
|
|
|
with regards to copyright, the Solidity compiler encourages the use
|
2020-05-13 14:53:54 +00:00
|
|
|
of machine-readable `SPDX license identifiers <https://spdx.org>`_.
|
|
|
|
Every source file should start with a comment indicating its license:
|
|
|
|
|
|
|
|
``// SPDX-License-Identifier: MIT``
|
|
|
|
|
|
|
|
The compiler does not validate that the license is part of the
|
|
|
|
`list allowed by SPDX <https://spdx.org/licenses/>`_, but
|
|
|
|
it does include the supplied string in the `bytecode metadata <metadata>`_.
|
|
|
|
|
|
|
|
If you do not want to specify a license or if the source code is
|
|
|
|
not open-source, please use the special value ``UNLICENSED``.
|
|
|
|
|
|
|
|
Supplying this comment of course does not free you from other
|
|
|
|
obligations related to licensing like having to mention
|
|
|
|
a specific license header in each source file or the
|
|
|
|
original copyright holder.
|
|
|
|
|
|
|
|
The comment is recognized by the compiler anywhere in the file at the
|
|
|
|
file level, but it is recommended to put it at the top of the file.
|
|
|
|
|
|
|
|
More information about how to use SPDX license identifiers
|
|
|
|
can be found at the `SPDX website <https://spdx.org/ids-how>`_.
|
|
|
|
|
|
|
|
|
2018-09-13 16:29:14 +00:00
|
|
|
.. index:: ! pragma
|
|
|
|
|
|
|
|
.. _pragma:
|
|
|
|
|
|
|
|
Pragmas
|
|
|
|
=======
|
2016-08-19 17:57:21 +00:00
|
|
|
|
2019-02-27 15:14:43 +00:00
|
|
|
The ``pragma`` keyword is used to enable certain compiler features
|
2018-09-25 18:03:53 +00:00
|
|
|
or checks. A pragma directive is always local to a source file, so
|
|
|
|
you have to add the pragma to all your files if you want enable it
|
2019-12-12 15:19:09 +00:00
|
|
|
in your whole project. If you :ref:`import<import>` another file, the pragma
|
|
|
|
from that file does *not* automatically apply to the importing file.
|
2018-09-25 18:03:53 +00:00
|
|
|
|
2016-08-19 17:57:21 +00:00
|
|
|
.. index:: ! pragma, version
|
|
|
|
|
2017-03-16 00:42:42 +00:00
|
|
|
.. _version_pragma:
|
|
|
|
|
2016-08-19 17:57:21 +00:00
|
|
|
Version Pragma
|
2018-09-13 16:29:14 +00:00
|
|
|
--------------
|
2016-08-19 17:57:21 +00:00
|
|
|
|
2019-02-27 15:14:43 +00:00
|
|
|
Source files can (and should) be annotated with a version pragma to reject
|
|
|
|
compilation with future compiler versions that might introduce incompatible
|
|
|
|
changes. We try to keep these to an absolute minimum and
|
|
|
|
introduce them in a way that changes in semantics also require changes
|
|
|
|
in the syntax, but this is not always possible. Because of this, it is always
|
2016-08-19 17:57:21 +00:00
|
|
|
a good idea to read through the changelog at least for releases that contain
|
2019-02-27 15:14:43 +00:00
|
|
|
breaking changes. These releases always have versions of the form
|
2016-08-19 17:57:21 +00:00
|
|
|
``0.x.0`` or ``x.0.0``.
|
|
|
|
|
2019-10-28 11:35:01 +00:00
|
|
|
The version pragma is used as follows: ``pragma solidity ^0.5.2;``
|
2016-08-19 17:57:21 +00:00
|
|
|
|
2019-02-27 15:14:43 +00:00
|
|
|
A source file with the line above does not compile with a compiler earlier than version 0.5.2,
|
|
|
|
and it also does not work on a compiler starting from version 0.6.0 (this
|
2019-12-12 15:19:09 +00:00
|
|
|
second condition is added by using ``^``). Because
|
|
|
|
there will be no breaking changes until version ``0.6.0``, you can
|
2019-02-27 15:14:43 +00:00
|
|
|
be sure that your code compiles the way you intended. The exact version of the
|
|
|
|
compiler is not fixed, so that bugfix releases are still possible.
|
2016-08-19 17:57:21 +00:00
|
|
|
|
2019-02-27 15:14:43 +00:00
|
|
|
It is possible to specify more complex rules for the compiler version,
|
|
|
|
these follow the same syntax used by `npm <https://docs.npmjs.com/misc/semver>`_.
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2018-09-25 18:03:53 +00:00
|
|
|
.. note::
|
2019-02-27 15:14:43 +00:00
|
|
|
Using the version pragma *does not* change the version of the compiler.
|
|
|
|
It also *does not* enable or disable features of the compiler. It just
|
|
|
|
instructs the compiler to check whether its version matches the one
|
|
|
|
required by the pragma. If it does not match, the compiler issues
|
2018-09-25 18:03:53 +00:00
|
|
|
an error.
|
|
|
|
|
2018-09-13 16:29:14 +00:00
|
|
|
.. index:: ! pragma, experimental
|
|
|
|
|
|
|
|
.. _experimental_pragma:
|
|
|
|
|
|
|
|
Experimental Pragma
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
The second pragma is the experimental pragma. It can be used to enable
|
|
|
|
features of the compiler or language that are not yet enabled by default.
|
|
|
|
The following experimental pragmas are currently supported:
|
|
|
|
|
|
|
|
|
|
|
|
ABIEncoderV2
|
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
|
|
The new ABI encoder is able to encode and decode arbitrarily nested
|
2019-12-11 16:05:44 +00:00
|
|
|
arrays and structs. It might produce less optimal code and has not
|
|
|
|
received as much testing as the old encoder, but is considered
|
|
|
|
non-experimental as of Solidity 0.6.0. You still have to explicitly
|
|
|
|
activate it using ``pragma experimental ABIEncoderV2;`` - we kept
|
|
|
|
the same pragma, even though it is not considered experimental
|
|
|
|
anymore.
|
2018-09-13 16:29:14 +00:00
|
|
|
|
2018-09-27 12:55:05 +00:00
|
|
|
.. _smt_checker:
|
|
|
|
|
2018-09-13 16:29:14 +00:00
|
|
|
SMTChecker
|
|
|
|
~~~~~~~~~~
|
|
|
|
|
|
|
|
This component has to be enabled when the Solidity compiler is built
|
|
|
|
and therefore it is not available in all Solidity binaries.
|
|
|
|
The :ref:`build instructions<smt_solvers_build>` explain how to activate this option.
|
|
|
|
It is activated for the Ubuntu PPA releases in most versions,
|
2019-12-12 15:21:11 +00:00
|
|
|
but not for the Docker images, Windows binaries or the
|
|
|
|
statically-built Linux binaries. It can be activated for solc-js via the
|
|
|
|
`smtCallback <https://github.com/ethereum/solc-js#example-usage-with-smtsolver-callback>`_ if you have an SMT solver
|
|
|
|
installed locally and run solc-js via node (not via the browser).
|
2018-09-13 16:29:14 +00:00
|
|
|
|
2019-03-20 21:44:16 +00:00
|
|
|
If you use ``pragma experimental SMTChecker;``, then you get additional
|
|
|
|
:ref:`safety warnings<formal_verification>` which are obtained by querying an
|
|
|
|
SMT solver.
|
|
|
|
The component does not yet support all features of the Solidity language and
|
|
|
|
likely outputs many warnings. In case it reports unsupported features, the
|
|
|
|
analysis may not be fully sound.
|
2018-09-13 16:29:14 +00:00
|
|
|
|
2019-02-25 17:01:25 +00:00
|
|
|
.. index:: source file, ! import, module
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2016-06-07 17:44:32 +00:00
|
|
|
.. _import:
|
|
|
|
|
2015-12-07 20:16:25 +00:00
|
|
|
Importing other Source Files
|
|
|
|
============================
|
|
|
|
|
2016-01-11 21:33:36 +00:00
|
|
|
Syntax and Semantics
|
|
|
|
--------------------
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2019-12-12 15:19:09 +00:00
|
|
|
Solidity supports import statements to help modularise your code that
|
|
|
|
are similar to those available in JavaScript
|
|
|
|
(from ES6 on). However, Solidity does not support the concept of
|
|
|
|
a `default export <https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export#Description>`_.
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2016-01-11 21:33:36 +00:00
|
|
|
At a global level, you can use import statements of the following form:
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2016-02-18 09:34:23 +00:00
|
|
|
::
|
2016-01-11 21:33:36 +00:00
|
|
|
|
2016-02-18 09:34:23 +00:00
|
|
|
import "filename";
|
2016-01-11 21:33:36 +00:00
|
|
|
|
2016-08-05 08:30:40 +00:00
|
|
|
This statement imports all global symbols from "filename" (and symbols imported there) into the
|
2016-02-18 09:34:23 +00:00
|
|
|
current global scope (different than in ES6 but backwards-compatible for Solidity).
|
2019-02-25 17:01:25 +00:00
|
|
|
This form is not recommended for use, because it unpredictably pollutes the namespace.
|
|
|
|
If you add new top-level items inside "filename", they automatically
|
2018-09-13 16:41:08 +00:00
|
|
|
appear in all files that import like this from "filename". It is better to import specific
|
|
|
|
symbols explicitly.
|
|
|
|
|
|
|
|
The following example creates a new global symbol ``symbolName`` whose members are all
|
2019-02-25 17:01:25 +00:00
|
|
|
the global symbols from ``"filename"``:
|
2016-02-18 09:34:23 +00:00
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
import * as symbolName from "filename";
|
|
|
|
|
2019-02-25 17:01:25 +00:00
|
|
|
which results in all global symbols being available in the format ``symbolName.symbol``.
|
2016-02-18 09:34:23 +00:00
|
|
|
|
2019-02-25 17:01:25 +00:00
|
|
|
A variant of this syntax that is not part of ES6, but possibly useful is:
|
2016-01-11 21:33:36 +00:00
|
|
|
|
2016-02-18 09:34:23 +00:00
|
|
|
::
|
|
|
|
|
|
|
|
import "filename" as symbolName;
|
|
|
|
|
2016-08-05 08:45:52 +00:00
|
|
|
which is equivalent to ``import * as symbolName from "filename";``.
|
2016-01-11 21:33:36 +00:00
|
|
|
|
2019-02-25 17:01:25 +00:00
|
|
|
If there is a naming collision, you can rename symbols while importing. For example,
|
|
|
|
the code below creates new global symbols ``alias`` and ``symbol2`` which reference
|
|
|
|
``symbol1`` and ``symbol2`` from inside ``"filename"``, respectively.
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
import {symbol1 as alias, symbol2} from "filename";
|
2018-10-25 16:28:24 +00:00
|
|
|
|
2016-01-11 21:33:36 +00:00
|
|
|
Paths
|
|
|
|
-----
|
|
|
|
|
2016-05-24 17:57:36 +00:00
|
|
|
In the above, ``filename`` is always treated as a path with ``/`` as directory separator,
|
2019-02-25 17:01:25 +00:00
|
|
|
and ``.`` as the current and ``..`` as the parent directory. When ``.`` or ``..`` is followed by a character except ``/``,
|
2017-01-02 15:13:57 +00:00
|
|
|
it is not considered as the current or the parent directory.
|
|
|
|
All path names are treated as absolute paths unless they start with the current ``.`` or the parent directory ``..``.
|
2016-01-11 21:33:36 +00:00
|
|
|
|
2019-02-25 17:01:25 +00:00
|
|
|
To import a file ``filename`` from the same directory as the current file, use ``import "./filename" as symbolName;``.
|
|
|
|
If you use ``import "filename" as symbolName;`` instead, a different file could be referenced
|
2016-01-11 21:33:36 +00:00
|
|
|
(in a global "include directory").
|
|
|
|
|
2019-02-25 17:01:25 +00:00
|
|
|
It depends on the compiler (see :ref:`import-compiler`) how to actually resolve the paths.
|
2016-01-11 21:33:36 +00:00
|
|
|
In general, the directory hierarchy does not need to strictly map onto your local
|
2019-02-25 17:01:25 +00:00
|
|
|
filesystem, and the path can also map to resources such as ipfs, http or git.
|
2016-01-11 21:33:36 +00:00
|
|
|
|
2018-09-13 16:41:08 +00:00
|
|
|
.. note::
|
|
|
|
Always use relative imports like ``import "./filename.sol";`` and avoid
|
|
|
|
using ``..`` in path specifiers. In the latter case, it is probably better to use
|
|
|
|
global paths and set up remappings as explained below.
|
|
|
|
|
2019-02-25 17:01:25 +00:00
|
|
|
.. _import-compiler:
|
|
|
|
|
2016-08-11 20:50:53 +00:00
|
|
|
Use in Actual Compilers
|
2016-01-11 21:33:36 +00:00
|
|
|
-----------------------
|
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
When invoking the compiler, you can specify how to discover the first element
|
|
|
|
of a path, and also path prefix remappings. For
|
|
|
|
example you can setup a remapping so that everything imported from the virtual
|
|
|
|
directory ``github.com/ethereum/dapp-bin/library`` would actually be read from
|
|
|
|
your local directory ``/usr/local/dapp-bin/library``.
|
|
|
|
If multiple remappings apply, the one with the longest key is tried first.
|
|
|
|
An empty prefix is not allowed. The remappings can depend on a context,
|
|
|
|
which allows you to configure packages to import e.g., different versions of a
|
|
|
|
library of the same name.
|
2016-01-11 21:33:36 +00:00
|
|
|
|
2016-01-13 16:34:59 +00:00
|
|
|
**solc**:
|
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
For solc (the commandline compiler), you provide these path remappings as
|
2016-06-07 17:44:32 +00:00
|
|
|
``context:prefix=target`` arguments, where both the ``context:`` and the
|
2018-08-17 10:51:32 +00:00
|
|
|
``=target`` parts are optional (``target`` defaults to ``prefix`` in this
|
2016-01-11 21:33:36 +00:00
|
|
|
case). All remapping values that are regular files are compiled (including
|
2018-08-17 10:51:32 +00:00
|
|
|
their dependencies).
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
This mechanism is backwards-compatible (as long
|
|
|
|
as no filename contains ``=`` or ``:``) and thus not a breaking change. All
|
|
|
|
files in or below the ``context`` directory that import a file that starts with
|
|
|
|
``prefix`` are redirected by replacing ``prefix`` by ``target``.
|
|
|
|
|
|
|
|
For example, if you clone ``github.com/ethereum/dapp-bin/`` locally to
|
|
|
|
``/usr/local/dapp-bin``, you can use the following in your source file:
|
2016-01-13 16:34:59 +00:00
|
|
|
|
2016-02-18 10:00:33 +00:00
|
|
|
::
|
|
|
|
|
|
|
|
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;
|
2016-01-13 16:34:59 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
Then run the compiler:
|
2016-01-13 16:34:59 +00:00
|
|
|
|
2016-05-18 19:37:38 +00:00
|
|
|
.. code-block:: bash
|
2016-02-18 10:00:33 +00:00
|
|
|
|
|
|
|
solc github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ source.sol
|
2016-01-13 16:34:59 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
As a more complex example, suppose you rely on a module that uses an old
|
|
|
|
version of dapp-bin that you checked out to ``/usr/local/dapp-bin_old``, then you can run:
|
2016-06-07 17:44:32 +00:00
|
|
|
|
|
|
|
.. code-block:: bash
|
|
|
|
|
|
|
|
solc module1:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin/ \
|
|
|
|
module2:github.com/ethereum/dapp-bin/=/usr/local/dapp-bin_old/ \
|
|
|
|
source.sol
|
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
This means that all imports in ``module2`` point to the old version but imports
|
|
|
|
in ``module1`` point to the new version.
|
|
|
|
|
|
|
|
.. note::
|
2016-06-07 17:44:32 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
``solc`` only allows you to include files from certain directories. They have
|
|
|
|
to be in the directory (or subdirectory) of one of the explicitly specified
|
|
|
|
source files or in the directory (or subdirectory) of a remapping target. If
|
|
|
|
you want to allow direct absolute includes, add the remapping ``/=/``.
|
2016-01-29 22:17:43 +00:00
|
|
|
|
|
|
|
If there are multiple remappings that lead to a valid file, the remapping
|
|
|
|
with the longest common prefix is chosen.
|
|
|
|
|
2017-03-15 22:58:14 +00:00
|
|
|
**Remix**:
|
2016-01-13 16:34:59 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
`Remix <https://remix.ethereum.org/>`_ provides an automatic remapping for
|
|
|
|
GitHub and automatically retrieves the file over the network. You can import
|
|
|
|
the iterable mapping as above, e.g.
|
2016-01-13 16:34:59 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
::
|
2019-04-10 09:17:40 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2018-08-17 10:51:32 +00:00
|
|
|
Remix may add other source code providers in the future.
|
2015-12-07 20:16:25 +00:00
|
|
|
|
|
|
|
.. index:: ! comment, natspec
|
|
|
|
|
|
|
|
Comments
|
|
|
|
========
|
|
|
|
|
2016-05-24 17:57:36 +00:00
|
|
|
Single-line comments (``//``) and multi-line comments (``/*...*/``) are possible.
|
2015-12-07 20:16:25 +00:00
|
|
|
|
2016-02-18 10:08:20 +00:00
|
|
|
::
|
|
|
|
|
|
|
|
// This is a single-line comment.
|
2016-05-18 15:35:00 +00:00
|
|
|
|
2016-02-18 10:08:20 +00:00
|
|
|
/*
|
2016-05-18 15:35:00 +00:00
|
|
|
This is a
|
2016-02-18 10:08:20 +00:00
|
|
|
multi-line comment.
|
|
|
|
*/
|
2016-05-18 15:35:00 +00:00
|
|
|
|
2018-09-13 16:41:08 +00:00
|
|
|
.. note::
|
|
|
|
A single-line comment is terminated by any unicode line terminator
|
|
|
|
(LF, VF, FF, CR, NEL, LS or PS) in utf8 encoding. The terminator is still part of
|
|
|
|
the source code after the comment, so if it is not an ascii symbol
|
|
|
|
(these are NEL, LS and PS), it will lead to a parser error.
|
2016-02-18 10:08:20 +00:00
|
|
|
|
2016-04-20 11:53:36 +00:00
|
|
|
Additionally, there is another type of comment called a natspec comment,
|
2017-05-15 10:45:26 +00:00
|
|
|
which is detailed in the :ref:`style guide<natspec>`. They are written with a
|
2016-05-24 17:57:36 +00:00
|
|
|
triple slash (``///``) or a double asterisk block(``/** ... */``) and
|
2016-05-18 15:35:00 +00:00
|
|
|
they should be used directly above function declarations or statements.
|
2017-06-11 05:41:15 +00:00
|
|
|
You can use `Doxygen <https://en.wikipedia.org/wiki/Doxygen>`_-style tags inside these comments to document
|
2016-05-18 15:35:00 +00:00
|
|
|
functions, annotate conditions for formal verification, and provide a
|
2016-04-20 11:53:36 +00:00
|
|
|
**confirmation text** which is shown to users when they attempt to invoke a
|
|
|
|
function.
|
2016-08-05 11:16:14 +00:00
|
|
|
|
|
|
|
In the following example we document the title of the contract, the explanation
|
2018-10-24 11:23:15 +00:00
|
|
|
for the two function parameters and two return variables.
|
2016-08-05 11:16:14 +00:00
|
|
|
|
|
|
|
::
|
|
|
|
|
2020-05-13 15:45:58 +00:00
|
|
|
// SPDX-License-Identifier: GPL-3.0
|
2020-03-24 12:35:41 +00:00
|
|
|
pragma solidity >=0.4.21 <0.8.0;
|
2016-09-05 11:54:54 +00:00
|
|
|
|
2017-07-17 09:24:18 +00:00
|
|
|
/** @title Shape calculator. */
|
2018-05-26 19:37:52 +00:00
|
|
|
contract ShapeCalculator {
|
2019-12-12 15:19:09 +00:00
|
|
|
/// @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.
|
2018-08-09 13:36:00 +00:00
|
|
|
function rectangle(uint w, uint h) public pure returns (uint s, uint p) {
|
2017-07-17 09:24:18 +00:00
|
|
|
s = w * h;
|
|
|
|
p = 2 * (w + h);
|
|
|
|
}
|
|
|
|
}
|