Merge pull request #11477 from iskanderandrews/feature/docs-highlight-solc

[Docs]: Highlighting code snippets in .rst docs
This commit is contained in:
chriseth 2021-06-28 14:40:43 +02:00 committed by GitHub
commit 2567eb46ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 433 additions and 245 deletions

View File

@ -290,7 +290,7 @@ It is still possible to interface with contracts written for Solidity versions p
v0.5.0 (or the other way around) by defining interfaces for them.
Consider you have the following pre-0.5.0 contract already deployed:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.4.25;
@ -308,7 +308,7 @@ Consider you have the following pre-0.5.0 contract already deployed:
This will no longer compile with Solidity v0.5.0. However, you can define a compatible interface for it:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -326,7 +326,7 @@ the function will work with ``staticcall``.
Given the interface defined above, you can now easily use the already deployed pre-0.5.0 contract:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -347,7 +347,7 @@ Similarly, pre-0.5.0 libraries can be used by defining the functions of the libr
supplying the address of the pre-0.5.0 library during linking (see :ref:`commandline-compiler` for how to use the
commandline compiler for linking):
::
.. code-block:: solidity
// This will not compile after 0.6.0
// SPDX-License-Identifier: GPL-3.0
@ -372,7 +372,7 @@ v0.5.0 with some of the changes listed in this section.
Old version:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.4.25;
@ -435,7 +435,7 @@ Old version:
New version:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.5.0;

View File

@ -235,7 +235,7 @@ Examples
Given the contract:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -510,7 +510,7 @@ call.
As an example, let us consider the following contract whose ``transfer`` function always
reverts with a custom error of "insufficient balance":
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -599,7 +599,7 @@ Errors look as follows:
For example,
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -653,7 +653,7 @@ which is of array type and has the same structure as the top-level object except
As an example, the code
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.4 <0.9.0;

View File

@ -39,7 +39,7 @@ load it into a ``bytes`` variable. This is not possible with "plain Solidity" an
idea is that reusable assembly libraries can enhance the Solidity language
without a compiler change.
.. code::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -65,7 +65,7 @@ without a compiler change.
Inline assembly is also beneficial in cases where the optimizer fails to produce
efficient code, for example:
.. code::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -217,7 +217,9 @@ starting from where this pointer points at and update it.
There is no guarantee that the memory has not been used before and thus
you cannot assume that its contents are zero bytes.
There is no built-in mechanism to release or free allocated memory.
Here is an assembly snippet you can use for allocating memory that follows the process outlined above::
Here is an assembly snippet you can use for allocating memory that follows the process outlined above
.. code-block:: yul
function allocate(length) -> pos {
pos := mload(0x40)

View File

@ -25,7 +25,7 @@ contract in order to become the "richest", inspired by
In the following contract, if you are no longer the richest,
you receive the funds of the person who is now the richest.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -63,7 +63,7 @@ you receive the funds of the person who is now the richest.
This is as opposed to the more intuitive sending pattern:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -129,7 +129,7 @@ functions and this is what this section is about.
The use of **function modifiers** makes these
restrictions highly readable.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -292,7 +292,7 @@ function finishes.
Starting with version 0.4.0, modifier code
will run even if the function explicitly returns.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;

View File

@ -11,7 +11,9 @@ Contracts may be marked as abstract even though all functions are implemented.
This can be done by using the ``abstract`` keyword as shown in the following example. Note that this contract needs to be
defined as abstract, because the function ``utterance()`` was defined, but no implementation was
provided (no implementation body ``{ }`` was given).::
provided (no implementation body ``{ }`` was given).
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -21,7 +23,9 @@ provided (no implementation body ``{ }`` was given).::
}
Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement
all defined functions. The usage of an abstract contract as a base class is shown in the following example::
all defined functions. The usage of an abstract contract as a base class is shown in the following example:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -40,11 +44,15 @@ functions by overriding, it needs to be marked as abstract as well.
Note that a function without implementation is different from
a :ref:`Function Type <function_types>` even though their syntax looks very similar.
Example of function without implementation (a function declaration)::
Example of function without implementation (a function declaration):
.. code-block:: solidity
function foo(address) external returns (address);
Example of a declaration of a variable whose type is a function type::
Example of a declaration of a variable whose type is a function type:
.. code-block:: solidity
function(address) external returns (address) foo;

View File

@ -27,7 +27,7 @@ can sometimes be cheaper than immutable values.
Not all types for constants and immutables are implemented at this time. The only supported types are
:ref:`strings <strings>` (only for constants) and :ref:`value types <value-types>`.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.4;

View File

@ -32,7 +32,7 @@ If a contract wants to create another contract, the source code
(and the binary) of the created contract has to be known to the creator.
This means that cyclic creation dependencies are impossible.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;

View File

@ -14,7 +14,7 @@ which causes
all changes in the current call to be reverted and passes the error data back to the
caller.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -79,4 +79,4 @@ of the built-in type ``Panic(uint256)``.
of inner calls is propagated back through the chain of external calls
by default. This means that an inner call
can "forge" revert data that looks like it could have come from the
contract that called it.
contract that called it.

View File

@ -15,7 +15,7 @@ inheritable properties of contracts and may be overridden by derived contracts,
if they are marked ``virtual``. For details, please see
:ref:`Modifier Overriding <modifier-overriding>`.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0 <0.9.0;

View File

@ -12,7 +12,7 @@ Functions outside of a contract, also called "free functions", always have impli
:ref:`visibility<visibility-and-getters>`. Their code is included in all contracts
that call them, similar to internal library functions.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0 <0.9.0;
@ -56,7 +56,9 @@ Function parameters are declared the same way as variables, and the name of
unused parameters can be omitted.
For example, if you want your contract to accept one kind of external call
with two integers, you would use something like the following::
with two integers, you would use something like the following:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -89,7 +91,9 @@ Function return variables are declared with the same syntax after the
``returns`` keyword.
For example, suppose you want to return two results: the sum and the product of
two integers passed as function parameters, then you use something like::
two integers passed as function parameters, then you use something like:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -114,7 +118,9 @@ You can either explicitly assign to return variables and
then leave the function as above,
or you can provide return values
(either a single or :ref:`multiple ones<multi-return>`) directly with the ``return``
statement::
statement:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -178,7 +184,7 @@ The following statements are considered modifying the state:
#. Using low-level calls.
#. Using inline assembly that contains certain opcodes.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -224,7 +230,7 @@ In addition to the list of state modifying statements explained above, the follo
#. Calling any function not marked ``pure``.
#. Using inline assembly that contains certain opcodes.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -321,7 +327,7 @@ will consume more gas than the 2300 gas stipend:
Below you can see an example of a Sink contract that uses function ``receive``.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -383,7 +389,7 @@ operations as long as there is enough gas passed on to it.
proper functions should be used instead.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.2 <0.9.0;
@ -461,7 +467,7 @@ This process is called "overloading" and also applies to inherited functions.
The following example shows overloading of the function
``f`` in the scope of contract ``A``.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -480,7 +486,7 @@ The following example shows overloading of the function
Overloaded functions are also present in the external interface. It is an error if two
externally visible functions differ by their Solidity types but not by their external types.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -514,7 +520,7 @@ candidate, resolution fails.
.. note::
Return parameters are not taken into account for overload resolution.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

View File

@ -36,7 +36,7 @@ some :ref:`differences <multi-inheritance>`.
Details are given in the following example.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -124,7 +124,9 @@ Details are given in the following example.
Note that above, we call ``Destructible.destroy()`` to "forward" the
destruction request. The way this is done is problematic, as
seen in the following example::
seen in the following example:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -154,7 +156,9 @@ seen in the following example::
A call to ``Final.destroy()`` will call ``Base2.destroy`` because we specify it
explicitly in the final override, but this function will bypass
``Base1.destroy``. The way around this is to use ``super``::
``Base1.destroy``. The way around this is to use ``super``:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -211,7 +215,7 @@ The mutability may be changed to a more strict one following the order:
The following example demonstrates changing mutability and visibility:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -235,7 +239,7 @@ and have not yet been overridden by another base contract (on some path through
Additionally, if a contract inherits the same function from multiple (unrelated)
bases, it has to explicitly override it:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -262,7 +266,7 @@ the function is defined in a common base contract
or if there is a unique function in a common base contract
that already overrides all other functions.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -303,7 +307,7 @@ Public state variables can override external functions if the
parameter and return types of the function matches the getter function
of the variable:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -335,7 +339,7 @@ Function modifiers can override each other. This works in the same way as
``virtual`` keyword must be used on the overridden modifier
and the ``override`` keyword must be used in the overriding modifier:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -354,7 +358,7 @@ and the ``override`` keyword must be used in the overriding modifier:
In case of multiple inheritance, all direct base contracts must be specified
explicitly:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -402,7 +406,7 @@ If there is no
constructor, the contract will assume the default constructor, which is
equivalent to ``constructor() {}``. For example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -439,7 +443,9 @@ Arguments for Base Constructors
The constructors of all the base contracts will be called following the
linearization rules explained below. If the base constructors have arguments,
derived contracts need to specify all of them. This can be done in two ways::
derived contracts need to specify all of them. This can be done in two ways:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -499,7 +505,7 @@ stopping at the first match. If a base contract has already been searched, it is
In the following code, Solidity will give the
error "Linearization of inheritance graph impossible".
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -520,7 +526,7 @@ C3 linearization is not too important in practice.
One area where inheritance linearization is especially important and perhaps not as clear is when there are multiple constructors in the inheritance hierarchy. The constructors will always be executed in the linearized order, regardless of the order in which their arguments are provided in the inheriting contract's constructor. For example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

View File

@ -20,7 +20,7 @@ an interface should be possible without any information loss.
Interfaces are denoted by their own keyword:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.2 <0.9.0;
@ -41,7 +41,7 @@ function is marked ``virtual``.
Interfaces can inherit from other interfaces. This has the same rules as normal
inheritance.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.2 <0.9.0;

View File

@ -50,7 +50,7 @@ The following example illustrates how to use libraries (but using a manual metho
be sure to check out :ref:`using for <using-for>` for a
more advanced example to implement a set).
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -129,7 +129,7 @@ The following example shows how to use :ref:`types stored in memory <data-locati
internal functions in libraries in order to implement
custom types without the overhead of external function calls:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.8 <0.9.0;
@ -238,7 +238,7 @@ The argument encoding is the same as for the regular contract ABI, except for st
Similarly to the contract ABI, the selector consists of the first four bytes of the Keccak256-hash of the signature.
Its value can be obtained from Solidity using the ``.selector`` member as follows:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.14 <0.9.0;

View File

@ -27,7 +27,9 @@ outside of the contract in which it is used. The directive
may only be used inside a contract, not inside any of its functions.
Let us rewrite the set example from the
:ref:`libraries` in this way::
:ref:`libraries` in this way:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -80,7 +82,9 @@ Let us rewrite the set example from the
}
}
It is also possible to extend elementary types in that way::
It is also possible to extend elementary types in that way:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.8 <0.9.0;

View File

@ -50,7 +50,7 @@ The visibility specifier is given after the type for
state variables and between parameter list and
return parameter list for functions.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -65,7 +65,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value
``data`` in state storage, but is not able to call ``f``. Contract ``E`` is derived from
``C`` and, thus, can call ``compute``.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -110,7 +110,7 @@ arguments and returns a ``uint``, the value of the state
variable ``data``. State variables can be initialized
when they are declared.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -131,7 +131,7 @@ symbol is accessed internally (i.e. without ``this.``),
it evaluates to a state variable. If it is accessed externally
(i.e. with ``this.``), it evaluates to a function.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -151,7 +151,7 @@ arguments to specify which individual element to return, for example
``myArray(0)``. If you want to return an entire array in one call, then you need
to write a function, for example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -178,7 +178,7 @@ Now you can use ``getArray()`` to retrieve the entire array, instead of
The next example is more complex:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -195,7 +195,7 @@ The next example is more complex:
It generates a function of the following form. The mapping in the struct is omitted
because there is no good way to provide the key for the mapping:
::
.. code-block:: solidity
function data(uint arg1, bool arg2, uint arg3) public returns (uint a, bytes3 b) {
a = data[arg1][arg2][arg3].a;

View File

@ -149,7 +149,7 @@ See especially:
If you want to debug using GDB, make sure you build differently than the "usual".
For example, you could run the following command in your ``build`` folder:
::
.. code-block:: bash
cmake -DCMAKE_BUILD_TYPE=Debug ..
make
@ -171,7 +171,7 @@ The test suite compiles and checks them against the given expectations.
For example: ``./test/libsolidity/syntaxTests/double_stateVariable_declaration.sol``
::
.. code-block:: solidity
contract test {
uint256 variable;
@ -190,7 +190,7 @@ In the above example, the state variable ``variable`` was declared twice, which
The ``isoltest`` tool is used for these tests and you can find it under ``./build/test/tools/``. It is an interactive tool which allows
editing of failing contracts using your preferred text editor. Let's try to break this test by removing the second declaration of ``variable``:
::
.. code-block:: solidity
contract test {
uint256 variable;
@ -200,7 +200,7 @@ editing of failing contracts using your preferred text editor. Let's try to brea
Running ``./build/test/isoltest`` again results in a test failure:
::
.. code-block:: text
syntaxTests/double_stateVariable_declaration.sol: FAIL
Contract:
@ -228,7 +228,7 @@ All of these options apply to the current contract, expect ``quit`` which stops
Automatically updating the test above changes it to
::
.. code-block:: solidity
contract test {
uint256 variable;
@ -237,7 +237,7 @@ Automatically updating the test above changes it to
and re-run the test. It now passes again:
::
.. code-block:: text
Re-running test case...
syntaxTests/double_stateVariable_declaration.sol: OK
@ -263,7 +263,7 @@ We mainly use `AFL <https://lcamtuf.coredump.cx/afl/>`_ for fuzzing. You need to
install the AFL packages from your repositories (afl, afl-clang) or build them manually.
Next, build Solidity (or just the ``solfuzzer`` binary) with AFL as your compiler:
.. code-block:: shell
.. code-block:: bash
cd build
# if needed
@ -284,7 +284,7 @@ At this stage you should be able to see a message similar to the following:
If the instrumentation messages did not appear, try switching the cmake flags pointing to AFL's clang binaries:
.. code-block:: shell
.. code-block:: bash
# if previously failed
make clean
@ -317,7 +317,7 @@ Next, you need some example source files. This makes it much easier for the fuzz
to find errors. You can either copy some files from the syntax tests or extract test files
from the documentation or the other tests:
.. code-block:: shell
.. code-block:: bash
mkdir /tmp/test_cases
cd /tmp/test_cases
@ -334,7 +334,7 @@ that result in similar behaviour of the binary.
Now run the fuzzer (the ``-m`` extends the size of memory to 60 MB):
.. code-block:: shell
.. code-block:: bash
afl-fuzz -m 60 -i /tmp/test_cases -o /tmp/fuzzer_reports -- /path/to/solfuzzer

View File

@ -39,7 +39,9 @@ Internal Function Calls
-----------------------
Functions of the current contract can be called directly ("internally"), also recursively, as seen in
this nonsensical example::
this nonsensical example:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
@ -82,7 +84,7 @@ Note that it is discouraged to specify gas values explicitly, since the gas cost
of opcodes can change in the future. Any Wei you send to the contract is added
to the total balance of that contract:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.2 <0.9.0;
@ -144,7 +146,7 @@ if they are enclosed in ``{ }`` as can be seen in the following
example. The argument list has to coincide by name with the list of
parameters from the function declaration, but can be in arbitrary order.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -168,7 +170,7 @@ Omitted Function Parameter Names
The names of unused parameters (especially return parameters) can be omitted.
Those parameters will still be present on the stack, but they are inaccessible.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
@ -192,7 +194,7 @@ A contract can create other contracts using the ``new`` keyword. The full
code of the contract being created has to be known when the creating contract
is compiled so recursive creation-dependencies are not possible.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -247,7 +249,7 @@ contracts creates other contracts in the meantime.
The main use-case here is contracts that act as judges for off-chain interactions,
which only need to be created if there is a dispute.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -316,7 +318,7 @@ or to pre-existing variables (or LValues in general).
Tuples are not proper types in Solidity, they can only be used to form syntactic
groupings of expressions.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -362,7 +364,7 @@ In the example below the call to ``g(x)`` has no effect on ``x`` because it crea
an independent copy of the storage value in memory. However, ``h(x)`` successfully modifies ``x``
because only a reference and not a copy is passed.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
@ -421,7 +423,7 @@ use state variables before they are declared and call functions recursively.
As a consequence, the following examples will compile without warnings, since
the two variables have the same name but disjoint scopes.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -443,7 +445,7 @@ As a special example of the C99 scoping rules, note that in the following,
the first assignment to ``x`` will actually assign the outer and not the inner variable.
In any case, you will get a warning about the outer variable being shadowed.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -465,7 +467,7 @@ In any case, you will get a warning about the outer variable being shadowed.
for the entire function, regardless where it was declared. The following example shows a code snippet that used
to compile but leads to an error starting from version 0.5.0.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -497,7 +499,7 @@ thus making the use of these libraries unnecessary.
To obtain the previous behaviour, an ``unchecked`` block can be used:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
@ -657,7 +659,7 @@ You can optionally provide a message string for ``require``, but not for ``asser
The following example shows how you can use ``require`` to check conditions on inputs
and ``assert`` for internal error checking.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -721,7 +723,7 @@ any costs.
The following example shows how to use an error string and a custom error instance
together with ``revert`` and the equivalent ``require``:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -781,7 +783,7 @@ The provided message can be retrieved by the caller using ``try``/``catch`` as s
A failure in an external call can be caught using a try/catch statement, as follows:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.8.0;

View File

@ -22,7 +22,7 @@ raised, the previous highest bidder gets their money back. After the end of
the bidding period, the contract has to be called manually for the beneficiary
to receive their money - contracts cannot activate themselves.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -191,7 +191,7 @@ transfers): Bidders can confuse competition by placing several high or low
invalid bids.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;

View File

@ -40,7 +40,7 @@ using `web3.js <https://github.com/ethereum/web3.js>`_ and
`MetaMask <https://metamask.io>`_, using the method described in `EIP-762 <https://github.com/ethereum/EIPs/pull/712>`_,
as it provides a number of other security benefits.
::
.. code-block:: javascript
/// Hashing first makes things easier
var hash = web3.utils.sha3("message to sign");
@ -90,7 +90,7 @@ library provides a function called ``soliditySHA3`` that mimics the behaviour of
Solidity's ``keccak256`` function applied to arguments encoded using ``abi.encodePacked``.
Here is a JavaScript function that creates the proper signature for the ``ReceiverPays`` example:
::
.. code-block:: javascript
// recipient is the address that should be paid.
// amount, in wei, specifies how much ether should be sent.
@ -272,7 +272,7 @@ to prevent a message intended for one payment channel from being used for a diff
Here is the modified JavaScript code to cryptographically sign a message from the previous section:
::
.. code-block:: javascript
function constructPaymentMessage(contractAddress, amount) {
return abi.soliditySHA3(
@ -456,7 +456,7 @@ We'll use the `ethereumjs-util <https://github.com/ethereumjs/ethereumjs-util>`_
library to write this verification. The final step can be done a number of ways,
and we use JavaScript. The following code borrows the ``constructPaymentMessage`` function from the signing **JavaScript code** above:
::
.. code-block:: javascript
// this mimics the prefixing behavior of the eth_sign JSON-RPC method.
function prefixed(hash) {

View File

@ -17,7 +17,7 @@ provides an isolated component that properly tracks balances of accounts.
It is easy to verify that the ``Balances`` library never produces negative balances or overflows
and the sum of all balances is an invariant across the lifetime of the contract.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;

View File

@ -23,7 +23,7 @@ This contract of course does not solve the problem, but gives an overview of how
you can use state machine-like constructs inside a contract.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;

View File

@ -30,7 +30,7 @@ At the end of the voting time, ``winningProposal()``
will return the proposal with the largest number
of votes.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

View File

@ -49,7 +49,7 @@ Example for Difference in Arrays
The following array occupies 32 bytes (1 slot) in storage, but 128
bytes (4 items with 32 bytes each) in memory.
::
.. code-block:: solidity
uint8[4] a;
@ -62,7 +62,7 @@ The following struct occupies 96 bytes (3 slots of 32 bytes) in storage,
but 128 bytes (4 items with 32 bytes each) in memory.
::
.. code-block:: solidity
struct S {
uint a;

View File

@ -98,7 +98,7 @@ for example, you have to add an offset corresponding to the struct member to rea
As an example, consider the following contract:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -216,7 +216,7 @@ The following example shows a contract and its storage layout, containing
value and reference types, types that are encoded packed, and nested types.
.. code::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -238,7 +238,7 @@ value and reference types, types that are encoded packed, and nested types.
bytes b1;
}
.. code::
.. code:: json
"storageLayout": {
"storage": [

View File

@ -87,7 +87,7 @@ Certain optimizer steps symbolically track the storage and memory locations. For
information is used to compute Keccak-256 hashes that can be evaluated during compile time. Consider
the sequence:
::
.. code-block:: none
PUSH 32
PUSH 0
@ -99,7 +99,7 @@ the sequence:
or the equivalent Yul
::
.. code-block:: yul
let x := calldataload(0)
mstore(x, 100)
@ -114,7 +114,7 @@ the instruction doesn't write to a certain location.
For example,
::
.. code-block:: yul
let x := calldataload(0)
mstore(x, 100)
@ -162,7 +162,7 @@ is used as replacement if it is smaller. If a basic block is split at a
``JUMPI`` and during the analysis, the condition evaluates to a constant,
the ``JUMPI`` is replaced based on the value of the constant. Thus code like
::
.. code-block:: solidity
uint x = 7;
data[7] = 9;
@ -173,7 +173,7 @@ the ``JUMPI`` is replaced based on the value of the constant. Thus code like
simplifies to this:
::
.. code-block:: solidity
data[7] = 9;
return 1;
@ -460,7 +460,7 @@ so that the following expressions still only need to reference SSA variables.
An example transformation is the following:
::
.. code-block:: yul
{
let a := calldataload(0)
@ -476,7 +476,7 @@ An example transformation is the following:
When all the following transformation steps are applied, the program will look
as follows:
::
.. code-block:: yul
{
let _1 := 0
@ -526,7 +526,7 @@ as arguments.
The above would be transformed into
::
.. code-block:: yul
{
let _1 := mload(y)
@ -563,7 +563,7 @@ reassigned variables are replaced by the newly declared variables.
Example:
::
.. code-block:: yul
{
let a := 1
@ -573,7 +573,7 @@ Example:
is transformed to
::
.. code-block:: yul
{
let a_1 := 1
@ -618,7 +618,7 @@ RedundantAssignEliminator
The SSA transform always generates an assignment of the form ``a := a_i``, even though
these might be unnecessary in many cases, like the following example:
::
.. code-block:: yul
{
let a := 1
@ -629,7 +629,7 @@ these might be unnecessary in many cases, like the following example:
The SSA transform converts this snippet to the following:
::
.. code-block:: yul
{
let a_1 := 1
@ -645,7 +645,7 @@ The Redundant Assign Eliminator removes all the three assignments to ``a``, beca
the value of ``a`` is not used and thus turn this
snippet into strict SSA form:
::
.. code-block:: yul
{
let a_1 := 1
@ -974,7 +974,7 @@ BlockFlattener
This stage eliminates nested blocks by inserting the statement in the
inner block at the appropriate place in the outer block:
::
.. code-block:: yul
{
let x := 2
@ -986,7 +986,7 @@ inner block at the appropriate place in the outer block:
is transformed to
::
.. code-block:: yul
{
let x := 2
@ -1026,7 +1026,7 @@ If a function, say, ``function f(a, b) { sstore (a, b) }``, is called with liter
example, ``f(x, 5)``, where ``x`` is an identifier, it could be specialized by creating a new
function ``f_1`` that takes only one argument, i.e.,
::
.. code-block:: yul
function f_1(a_1) {
let b_1 := 5
@ -1051,7 +1051,7 @@ This step removes unused parameters in a function.
If a parameter is unused, like ``c`` and ``y`` in, ``function f(a,b,c) -> x, y { x := div(a,b) }``, we
remove the parameter and create a new "linking" function as follows:
::
.. code-block:: yul
function f(a,b) -> x { x := div(a,b) }
function f2(a,b,c) -> x, y { x := f(a,b) }
@ -1184,14 +1184,14 @@ fresh variable declarations.
The SSA transform rewrites
::
.. code-block:: yul
a := E
mstore(a, 1)
to
::
.. code-block:: yul
let a_1 := E
a := a_1
@ -1202,7 +1202,7 @@ whenever ``a`` was referenced. The SSA transform changes statements
of this form by just swapping out the declaration and the assignment. The above
snippet is turned into
::
.. code-block:: yul
a := E
let a_1 := a

View File

@ -15,7 +15,7 @@ everything right now, we will go into more detail later.
Storage Example
===============
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -82,7 +82,7 @@ cryptocurrency. The contract allows only its creator to create new coins (differ
Anyone can send coins to each other without a need for
registering with a username and password, all you need is an Ethereum keypair.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;

View File

@ -14,7 +14,8 @@ hiding new and different behavior in existing code.
* When storage structs are deleted, every storage slot that contains a member of the struct is set to zero entirely. Formally, padding space was left untouched.
Consequently, if the padding space within a struct is used to store data (e.g. in the context of a contract upgrade), you have to be aware that ``delete`` will now also clear the added member (while it wouldn't have been cleared in the past).
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0;
@ -42,7 +43,8 @@ We have the same behavior for implicit delete, for example when array of structs
The new code generator implements modifiers using actual functions and passes function parameters on.
This means that multiple executions of a function will get the same values for the parameters.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0;
contract C {
@ -71,7 +73,9 @@ New order:
2. Constructor, if present.
This causes differences in some contracts, for example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0;
@ -93,7 +97,9 @@ With the new rules, ``y`` will be set to 42. We first initialize ``x`` to 0, the
* Copying ``bytes`` arrays from memory to storage is implemented in a different way. The old code generator always copies full words, while the new one cuts the byte array after its end. The old behaviour can lead to dirty data being copied after the end of the array (but still in the same storage slot).
This causes differences in some contracts, for example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.8.0;
@ -123,7 +129,8 @@ Now it is returning ``0x64656164626565660000000000000000000000000000000000000000
For example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.8.0;
contract C {
@ -141,7 +148,8 @@ The function ``preincr_u8(1)`` returns the following values:
On the other hand, function argument expressions are evaluated in the same order by both code generators.
For example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.8.0;
contract C {
@ -188,7 +196,9 @@ The old code generator only performs cleanup before an operation whose result co
The new code generator performs cleanup after any operation that can result in dirty bits.
For example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.8.0;
contract C {

View File

@ -56,7 +56,7 @@ to call back into A before this interaction is completed. To give an example,
the following code contains a bug (it is just a snippet and not a
complete contract):
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -80,7 +80,7 @@ basically retrieve all the Ether in the contract. In particular, the
following contract will allow an attacker to refund multiple times
as it uses ``call`` which forwards all remaining gas by default:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.2 <0.9.0;
@ -100,7 +100,7 @@ as it uses ``call`` which forwards all remaining gas by default:
To avoid re-entrancy, you can use the Checks-Effects-Interactions pattern as
outlined further below:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -198,7 +198,7 @@ tx.origin
Never use tx.origin for authorization. Let's say you have a wallet contract like this:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -218,7 +218,7 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like
Now someone tricks you into sending Ether to the address of this attack wallet:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -251,7 +251,7 @@ They resemble integers when the values are small, but cannot represent arbitrari
The following code causes an overflow because the result of the addition is too large
to be stored in the type ``uint8``:
::
.. code-block:: solidity
uint8 x = 255;
uint8 y = 1;
@ -289,7 +289,7 @@ field of a ``struct`` that is the base type of a dynamic storage array. The
``mapping`` is also ignored in assignments of structs or arrays containing a
``mapping``.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;

View File

@ -666,7 +666,7 @@ the arguments.
Using abstraction means loss of precise knowledge, but in many cases it does
not mean loss of proving power.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;
@ -713,7 +713,7 @@ location is erased.
If the type is nested, the knowledge removal also includes all the prefix base
types.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;

View File

@ -24,7 +24,7 @@ State Variables
State variables are variables whose values are permanently stored in contract
storage.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -47,7 +47,7 @@ Functions are the executable units of code. Functions are usually
defined inside a contract, but they can also be defined outside of
contracts.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.7.0 <0.9.0;
@ -81,7 +81,7 @@ is not possible.
Like functions, modifiers can be :ref:`overridden <modifier-overriding>`.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
@ -109,7 +109,7 @@ Events
Events are convenience interfaces with the EVM logging facilities.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.21 <0.9.0;
@ -137,7 +137,7 @@ In comparison to string descriptions, errors are much cheaper and allow you
to encode additional data. You can use NatSpec to describe the error to
the user.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -168,7 +168,7 @@ Struct Types
Structs are custom defined types that can group several variables (see
:ref:`structs` in types section).
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -190,7 +190,7 @@ Enum Types
Enums can be used to create custom types with a finite set of 'constant values' (see
:ref:`enums` in types section).
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

View File

@ -53,7 +53,9 @@ Blank Lines
Surround top level declarations in solidity source with two blank lines.
Yes::
Yes:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -72,7 +74,9 @@ Yes::
// ...
}
No::
No:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -92,7 +96,9 @@ 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::
Yes:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -113,7 +119,9 @@ Yes::
}
}
No::
No:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -150,7 +158,9 @@ Wrapped lines should conform to the following guidelines.
Function Calls
Yes::
Yes:
.. code-block:: solidity
thisFunctionCallIsReallyLong(
longArgument1,
@ -158,7 +168,9 @@ Yes::
longArgument3
);
No::
No:
.. code-block:: solidity
thisFunctionCallIsReallyLong(longArgument1,
longArgument2,
@ -188,7 +200,9 @@ No::
Assignment Statements
Yes::
Yes:
.. code-block:: solidity
thisIsALongNestedMapping[being][set][to_some_value] = someFunction(
argument1,
@ -197,7 +211,9 @@ Yes::
argument4
);
No::
No:
.. code-block:: solidity
thisIsALongNestedMapping[being][set][to_some_value] = someFunction(argument1,
argument2,
@ -206,7 +222,9 @@ No::
Event Definitions and Event Emitters
Yes::
Yes:
.. code-block:: solidity
event LongAndLotsOfArgs(
address sender,
@ -224,7 +242,9 @@ Yes::
options
);
No::
No:
.. code-block:: solidity
event LongAndLotsOfArgs(address sender,
address recipient,
@ -248,7 +268,9 @@ Imports
Import statements should always be placed at the top of the file.
Yes::
Yes:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -263,7 +285,9 @@ Yes::
// ...
}
No::
No:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -297,7 +321,9 @@ Functions should be grouped according to their visibility and ordered:
Within a grouping, place the ``view`` and ``pure`` functions last.
Yes::
Yes:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -333,7 +359,9 @@ Yes::
// ...
}
No::
No:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -370,11 +398,15 @@ Avoid extraneous whitespace in the following situations:
Immediately inside parenthesis, brackets or braces, with the exception of single line function declarations.
Yes::
Yes:
.. code-block:: solidity
spam(ham[1], Coin({name: "ham"}));
No::
No:
.. code-block:: solidity
spam( ham[ 1 ], Coin( { name: "ham" } ) );
@ -384,23 +416,31 @@ Exception::
Immediately before a comma, semicolon:
Yes::
Yes:
.. code-block:: solidity
function spam(uint i, Coin coin) public;
No::
No:
.. code-block:: solidity
function spam(uint i , Coin coin) public ;
More than one space around an assignment or other operator to align with another:
Yes::
Yes:
.. code-block:: solidity
x = 1;
y = 2;
long_variable = 3;
No::
No:
.. code-block:: solidity
x = 1;
y = 2;
@ -408,7 +448,9 @@ No::
Don't include a whitespace in the receive and fallback functions:
Yes::
Yes:
.. code-block:: solidity
receive() external payable {
...
@ -418,7 +460,9 @@ Yes::
...
}
No::
No:
.. code-block:: solidity
receive () external payable {
...
@ -440,7 +484,9 @@ should:
declaration.
* The opening brace should be preceded by a single space.
Yes::
Yes:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -452,7 +498,9 @@ Yes::
}
}
No::
No:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -473,7 +521,9 @@ Additionally there should be a single space between the control structures
conditional, as well as a single space between the conditional parenthetic
block and the opening brace.
Yes::
Yes:
.. code-block:: solidity
if (...) {
...
@ -483,7 +533,9 @@ Yes::
...
}
No::
No:
.. code-block:: solidity
if (...)
{
@ -499,12 +551,16 @@ No::
For control structures whose body contains a single statement, omitting the
braces is ok *if* the statement is contained on a single line.
Yes::
Yes:
.. code-block:: solidity
if (x < 10)
x += 1;
No::
No:
.. code-block:: solidity
if (x < 10)
someArray.push(Coin({
@ -516,7 +572,9 @@ For ``if`` blocks which have an ``else`` or ``else if`` clause, the ``else`` sho
placed on the same line as the ``if``'s closing brace. This is an exception compared
to the rules of other block-like structures.
Yes::
Yes:
.. code-block:: solidity
if (x < 3) {
x += 1;
@ -532,7 +590,9 @@ Yes::
else
x -= 1;
No::
No:
.. code-block:: solidity
if (x < 3) {
x += 1;
@ -552,7 +612,9 @@ declaration.
The opening brace should be preceded by a single space.
Yes::
Yes:
.. code-block:: solidity
function increment(uint x) public pure returns (uint) {
return x + 1;
@ -562,7 +624,9 @@ Yes::
return x + 1;
}
No::
No:
.. code-block:: solidity
function increment(uint x) public pure returns (uint)
{
@ -588,7 +652,9 @@ The modifier order for a function should be:
4. Override
5. Custom modifiers
Yes::
Yes:
.. code-block:: solidity
function balance(uint from) public view override returns (uint) {
return balanceOf[from];
@ -598,7 +664,9 @@ Yes::
selfdestruct(owner);
}
No::
No:
.. code-block:: solidity
function balance(uint from) public override view returns (uint) {
return balanceOf[from];
@ -613,7 +681,9 @@ 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::
Yes:
.. code-block:: solidity
function thisFunctionHasLotsOfArguments(
address a,
@ -628,7 +698,9 @@ Yes::
doSomething();
}
No::
No:
.. code-block:: solidity
function thisFunctionHasLotsOfArguments(address a, address b, address c,
address d, address e, address f) public {
@ -657,7 +729,9 @@ No::
If a long function declaration has modifiers, then each modifier should be
dropped to its own line.
Yes::
Yes:
.. code-block:: solidity
function thisFunctionNameIsReallyLong(address x, address y, address z)
public
@ -681,7 +755,9 @@ Yes::
doSomething();
}
No::
No:
.. code-block:: solidity
function thisFunctionNameIsReallyLong(address x, address y, address z)
public
@ -707,7 +783,9 @@ No::
Multiline output parameters and return statements should follow the same style recommended for wrapping long lines found in the :ref:`Maximum Line Length <maximum_line_length>` section.
Yes::
Yes:
.. code-block:: solidity
function thisFunctionNameIsReallyLong(
address a,
@ -730,7 +808,9 @@ Yes::
);
}
No::
No:
.. code-block:: solidity
function thisFunctionNameIsReallyLong(
address a,
@ -753,7 +833,9 @@ For constructor functions on inherited contracts whose 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.
Yes::
Yes:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -784,7 +866,9 @@ Yes::
}
}
No::
No:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -834,7 +918,9 @@ No::
When declaring short functions with a single statement, it is permissible to do it on a single line.
Permissible::
Permissible:
.. code-block:: solidity
function shortFunction() public { doSomething(); }
@ -849,14 +935,18 @@ In variable declarations, do not separate the keyword ``mapping`` from its
type by a space. Do not separate any nested ``mapping`` keyword from its type by
whitespace.
Yes::
Yes:
.. code-block:: solidity
mapping(uint => uint) map;
mapping(address => bool) registeredAddresses;
mapping(uint => mapping(bool => Data[])) public data;
mapping(uint => mapping(uint => s)) data;
No::
No:
.. code-block:: solidity
mapping (uint => uint) map;
mapping( address => bool ) registeredAddresses;
@ -869,11 +959,15 @@ Variable Declarations
Declarations of array variables should not have a space between the type and
the brackets.
Yes::
Yes:
.. code-block:: solidity
uint[] x;
No::
No:
.. code-block:: solidity
uint [] x;
@ -883,26 +977,34 @@ Other Recommendations
* Strings should be quoted with double-quotes instead of single-quotes.
Yes::
Yes:
.. code-block:: solidity
str = "foo";
str = "Hamlet says, 'To be or not to be...'";
No::
No:
.. code-block:: solidity
str = 'bar';
str = '"Be yourself; everyone else is already taken." -Oscar Wilde';
* Surround operators with a single space on either side.
Yes::
Yes:
.. code-block:: solidity
x = 3;
x = 100 / 10;
x += 3 + 4;
x |= y && z;
No::
No:
.. code-block:: solidity
x=3;
x = 100/10;
@ -914,13 +1016,17 @@ No::
improved readability for complex statement. You should always use the same
amount of whitespace on either side of an operator:
Yes::
Yes:
.. code-block:: solidity
x = 2**3 + 5;
x = 2*y + 3*z;
x = (a+b) * (a-b);
No::
No:
.. code-block:: solidity
x = 2** 3 + 5;
x = y+z;
@ -1005,7 +1111,9 @@ Contract and Library Names
As shown in the example below, if the contract name is ``Congress`` and the library name is ``Owned``, then their associated filenames should be ``Congress.sol`` and ``Owned.sol``.
Yes::
Yes:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -1028,7 +1136,9 @@ Yes::
}
}
and in ``Congress.sol``::
and in ``Congress.sol``:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -1040,7 +1150,9 @@ and in ``Congress.sol``::
//...
}
No::
No:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
@ -1063,7 +1175,9 @@ No::
}
}
and in ``Congress.sol``::
and in ``Congress.sol``:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.7.0;
@ -1147,7 +1261,9 @@ triple slash (``///``) or a double asterisk block (``/** ... */``) and
they should be used directly above function declarations or statements.
For example, the contract from :ref:`a simple smart contract <simple-smart-contract>` with the comments
added looks like the one below::
added looks like the one below:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;

View File

@ -32,7 +32,7 @@ in the ``uint16`` type. The resulting type of the expression ``y + z`` is ``uint
Because it is assigned to a variable of type ``uint32`` another implicit conversion
is performed after the addition.
::
.. code-block:: solidity
uint8 y;
uint16 z;
@ -50,7 +50,7 @@ result is what you want and expect!
Take the following example that converts a negative ``int`` to a ``uint``:
::
.. code-block:: solidity
int y = -3;
uint x = uint(y);
@ -59,13 +59,17 @@ At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 h
characters), which is -3 in the two's complement representation of 256 bits.
If an integer is explicitly converted to a smaller type, higher-order bits are
cut off::
cut off:
.. code-block:: solidity
uint32 a = 0x12345678;
uint16 b = uint16(a); // b will be 0x5678 now
If an integer is explicitly converted to a larger type, it is padded on the left (i.e., at the higher order end).
The result of the conversion will compare equal to the original integer::
The result of the conversion will compare equal to the original integer:
.. code-block:: solidity
uint16 a = 0x1234;
uint32 b = uint32(a); // b will be 0x00001234 now
@ -73,14 +77,18 @@ The result of the conversion will compare equal to the original integer::
Fixed-size bytes types behave differently during conversions. They can be thought of as
sequences of individual bytes and converting to a smaller type will cut off the
sequence::
sequence:
.. code-block:: solidity
bytes2 a = 0x1234;
bytes1 b = bytes1(a); // b will be 0x12
If a fixed-size bytes type is explicitly converted to a larger type, it is padded on
the right. Accessing the byte at a fixed index will result in the same value before and
after the conversion (if the index is still in range)::
after the conversion (if the index is still in range):
.. code-block:: solidity
bytes2 a = 0x1234;
bytes4 b = bytes4(a); // b will be 0x12340000
@ -91,7 +99,9 @@ Since integers and fixed-size byte arrays behave differently when truncating or
padding, explicit conversions between integers and fixed-size byte arrays are only allowed,
if both have the same size. If you want to convert between integers and fixed-size byte arrays of
different size, you have to use intermediate conversions that make the desired truncation and padding
rules explicit::
rules explicit:
.. code-block:: solidity
bytes2 a = 0x1234;
uint32 b = uint16(a); // b will be 0x00001234
@ -103,7 +113,7 @@ rules explicit::
In case the array is longer than the target fixed bytes type, truncation at the end will happen.
If the array is shorter than the target type, it will be padded with zeros at the end.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.5;
@ -129,7 +139,9 @@ Integer Types
-------------
Decimal and hexadecimal number literals can be implicitly converted to any integer type
that is large enough to represent it without truncation::
that is large enough to represent it without truncation:
.. code-block:: solidity
uint8 a = 12; // fine
uint32 b = 1234; // fine
@ -146,7 +158,9 @@ Fixed-Size Byte Arrays
Decimal number literals cannot be implicitly converted to fixed-size byte arrays. Hexadecimal
number literals can be, but only if the number of hex digits exactly fits the size of the bytes
type. As an exception both decimal and hexadecimal literals which have a value of zero can be
converted to any fixed-size bytes type::
converted to any fixed-size bytes type:
.. code-block:: solidity
bytes2 a = 54321; // not allowed
bytes2 b = 0x12; // not allowed
@ -157,7 +171,9 @@ converted to any fixed-size bytes type::
bytes4 g = 0x0; // fine
String literals and hex string literals can be implicitly converted to fixed-size byte arrays,
if their number of characters matches the size of the bytes type::
if their number of characters matches the size of the bytes type:
.. code-block:: solidity
bytes2 a = hex"1234"; // fine
bytes2 b = "xy"; // fine

View File

@ -40,7 +40,7 @@ an Ethereum address to an unsigned integer value. As ``uint`` is a value type, t
returns a value that matches the type, which you can see in the ``MappingUser``
contract that returns the value at the specified address.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -66,7 +66,7 @@ The example below is a simplified version of an
``_allowances`` is an example of a mapping type inside another mapping type.
The example below uses ``_allowances`` to record the amount someone else is allowed to withdraw from your account.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;
@ -121,7 +121,7 @@ top of them and iterate over that. For example, the code below implements an
``IterableMapping`` library that the ``User`` contract then adds data too, and
the ``sum`` function iterates over to sum all the values.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.8 <0.9.0;

View File

@ -40,7 +40,7 @@ This distinction is visible when ``a`` is reference variable: It
will only reset ``a`` itself, not the
value it referred to previously.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;

View File

@ -60,7 +60,7 @@ Data locations are not only relevant for persistency of data, but also for the s
variables of storage struct type, even if the local variable
itself is just a reference.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.5.0 <0.9.0;
@ -171,7 +171,7 @@ You can concatenate a variable number of ``bytes`` or ``bytes1 ... bytes32`` usi
The function returns a single ``bytes memory`` array that contains the contents of the arguments without padding.
If you want to use string parameters or other types, you need to convert them to ``bytes`` or ``bytes1``/.../``bytes32`` first.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.4;
@ -200,7 +200,7 @@ or create a new memory array and copy every element.
As all variables in Solidity, the elements of newly allocated arrays are always initialized
with the :ref:`default value<default-value>`.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -239,7 +239,7 @@ In the example below, the type of ``[1, 2, 3]`` is
you want the result to be a ``uint[3] memory`` type, you need to convert
the first element to ``uint``.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -261,7 +261,7 @@ Since fixed-size memory arrays of different type cannot be converted into each o
(even if the base types can), you always have to specify a common base type explicitly
if you want to use two-dimensional array literals:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -278,7 +278,7 @@ if you want to use two-dimensional array literals:
Fixed size memory arrays cannot be assigned to dynamically-sized
memory arrays, i.e. the following is not possible:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.0 <0.9.0;
@ -298,7 +298,7 @@ complications because of how arrays are passed in the ABI.
If you want to initialize dynamically-sized arrays, you have to assign the
individual elements:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -356,7 +356,7 @@ Array Members
that return dynamic arrays, make sure to use an EVM that is set to
Byzantium mode.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;
@ -489,7 +489,7 @@ they only exist in intermediate expressions.
Array slices are useful to ABI-decode secondary data passed in function parameters:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >0.8.4 <0.9.0;
@ -528,7 +528,7 @@ Structs
Solidity provides a way to define new types in the form of structs, which is
shown in the following example:
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.9.0;

View File

@ -238,7 +238,7 @@ For a quick reference of all members of address, see :ref:`address_related`.
It is possible to query the balance of an address using the property ``balance``
and to send Ether (in units of wei) to a payable address using the ``transfer`` function:
::
.. code-block:: solidity
address payable x = address(0x123);
address myAddress = address(this);
@ -272,7 +272,9 @@ return the success condition (as a ``bool``) and the returned data
The functions ``abi.encode``, ``abi.encodePacked``, ``abi.encodeWithSelector``
and ``abi.encodeWithSignature`` can be used to encode structured data.
Example::
Example:
.. code-block:: solidity
bytes memory payload = abi.encodeWithSignature("register(string)", "MyName");
(bool success, bytes memory returnData) = address(nameReg).call(payload);
@ -291,15 +293,21 @@ Example::
arbitrary arguments and would also handle a first argument of type
``bytes4`` differently. These edge cases were removed in version 0.5.0.
It is possible to adjust the supplied gas with the ``gas`` modifier::
It is possible to adjust the supplied gas with the ``gas`` modifier:
.. code-block:: solidity
address(nameReg).call{gas: 1000000}(abi.encodeWithSignature("register(string)", "MyName"));
Similarly, the supplied Ether value can be controlled too::
Similarly, the supplied Ether value can be controlled too:
.. code-block:: solidity
address(nameReg).call{value: 1 ether}(abi.encodeWithSignature("register(string)", "MyName"));
Lastly, these modifiers can be combined. Their order does not matter::
Lastly, these modifiers can be combined. Their order does not matter:
.. code-block:: solidity
address(nameReg).call{gas: 1000000, value: 1 ether}(abi.encodeWithSignature("register(string)", "MyName"));
@ -483,7 +491,7 @@ regardless of the type of the right (exponent) operand.
for the type of ``2.5`` and ``uint128``, the Solidity compiler does not accept
this code.
::
.. code-block:: solidity
uint128 a = 1;
uint128 b = 2.5 + a + 0.5;
@ -536,7 +544,7 @@ Unicode Literals
While regular string literals can only contain ASCII, Unicode literals prefixed with the keyword ``unicode`` can contain any valid UTF-8 sequence.
They also support the very same escape sequences as regular string literals.
::
.. code-block:: solidity
string memory a = unicode"Hello 😃";
@ -574,7 +582,7 @@ The data representation is the same as for enums in C: The options are represent
subsequent unsigned integer values starting from ``0``.
::
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -626,7 +634,9 @@ contract internally.
External functions consist of an address and a function signature and they can
be passed via and returned from external function calls.
Function types are notated as follows::
Function types are notated as follows:
.. code-block:: solidity
function (<parameter types>) {internal|external} [pure|view|payable] [returns (<return types>)]
@ -695,7 +705,9 @@ External (or public) functions have the following members:
respectively. See :ref:`External Function Calls <external-function-calls>` for
more information.
Example that shows how to use the members::
Example that shows how to use the members:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.4 <0.9.0;
@ -711,7 +723,9 @@ Example that shows how to use the members::
}
}
Example that shows how to use internal function types::
Example that shows how to use internal function types:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.16 <0.9.0;
@ -769,7 +783,9 @@ Example that shows how to use internal function types::
}
}
Another example that uses external function types::
Another example that uses external function types:
.. code-block:: solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.4.22 <0.9.0;

View File

@ -9,7 +9,7 @@ Ether Units
A literal number can take a suffix of ``wei``, ``gwei`` or ``ether`` to specify a subdenomination of Ether, where Ether numbers without a postfix are assumed to be Wei.
::
.. code-block:: solidity
assert(1 wei == 1);
assert(1 gwei == 1e9);
@ -45,7 +45,9 @@ library has to be updated by an external oracle.
The suffix ``years`` has been removed in version 0.5.0 due to the reasons above.
These suffixes cannot be applied to variables. For example, if you want to
interpret a function parameter in days, you can in the following way::
interpret a function parameter in days, you can in the following way:
.. code-block:: solidity
function f(uint start, uint daysAfter) public {
if (block.timestamp >= start + daysAfter * 1 days) {