mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11176 from ethereum/random-doc-clarifications
Random documentation clarifications
This commit is contained in:
commit
99a9bd1a63
@ -19,6 +19,7 @@ We assume that all contracts will have the interface definitions of any contract
|
|||||||
This specification does not address contracts whose interface is dynamic or otherwise known only at run-time.
|
This specification does not address contracts whose interface is dynamic or otherwise known only at run-time.
|
||||||
|
|
||||||
.. _abi_function_selector:
|
.. _abi_function_selector:
|
||||||
|
.. index:: selector
|
||||||
|
|
||||||
Function Selector
|
Function Selector
|
||||||
=================
|
=================
|
||||||
|
@ -108,13 +108,24 @@ limited to functions of the same library.
|
|||||||
Multiple modifiers are applied to a function by specifying them in a
|
Multiple modifiers are applied to a function by specifying them in a
|
||||||
whitespace-separated list and are evaluated in the order presented.
|
whitespace-separated list and are evaluated in the order presented.
|
||||||
|
|
||||||
|
Modifiers cannot implicitly access or change the arguments and return values of functions they modify.
|
||||||
|
Their values can only be passed to them explicitly at the point of invocation.
|
||||||
|
|
||||||
|
Explicit returns from a modifier or function body only leave the current
|
||||||
|
modifier or function body. Return variables are assigned and
|
||||||
|
control flow continues after the ``_`` in the preceding modifier.
|
||||||
|
|
||||||
.. warning::
|
.. warning::
|
||||||
In an earlier version of Solidity, ``return`` statements in functions
|
In an earlier version of Solidity, ``return`` statements in functions
|
||||||
having modifiers behaved differently.
|
having modifiers behaved differently.
|
||||||
|
|
||||||
Explicit returns from a modifier or function body only leave the current
|
An explicit return from a modifier with ``return;`` does not affect the values returned by the function.
|
||||||
modifier or function body. Return variables are assigned and
|
The modifier can, however, choose not to execute the function body at all and in that case the return
|
||||||
control flow continues after the "_" in the preceding modifier.
|
variables are set to their :ref:`default values<default-value>` just as if the function had an empty
|
||||||
|
body.
|
||||||
|
|
||||||
|
The ``_`` symbol can appear in the modifier multiple times. Each occurrence is replaced with
|
||||||
|
the function body.
|
||||||
|
|
||||||
Arbitrary expressions are allowed for modifier arguments and in this context,
|
Arbitrary expressions are allowed for modifier arguments and in this context,
|
||||||
all symbols visible from the function are visible in the modifier. Symbols
|
all symbols visible from the function are visible in the modifier. Symbols
|
||||||
|
@ -38,6 +38,12 @@ To realize this in the EVM, code of internal library functions
|
|||||||
and all functions called from therein will at compile time be included in the calling
|
and all functions called from therein will at compile time be included in the calling
|
||||||
contract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``.
|
contract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL``.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
The inheritance analogy breaks down when it comes to public functions.
|
||||||
|
Calling a public library function with ``L.f()`` results in an external call (``DELEGATECALL``
|
||||||
|
to be precise).
|
||||||
|
In contrast, ``A.f()`` is an internal call when ``A`` is a base contract of the current contract.
|
||||||
|
|
||||||
.. index:: using for, set
|
.. index:: using for, set
|
||||||
|
|
||||||
The following example illustrates how to use libraries (but using a manual method,
|
The following example illustrates how to use libraries (but using a manual method,
|
||||||
@ -204,6 +210,7 @@ In comparison to contracts, libraries are restricted in the following ways:
|
|||||||
(These might be lifted at a later point.)
|
(These might be lifted at a later point.)
|
||||||
|
|
||||||
.. _library-selectors:
|
.. _library-selectors:
|
||||||
|
.. index:: selector
|
||||||
|
|
||||||
Function Signatures and Selectors in Libraries
|
Function Signatures and Selectors in Libraries
|
||||||
==============================================
|
==============================================
|
||||||
|
@ -21,9 +21,6 @@ For state variables, ``external`` is not possible.
|
|||||||
which means they can be called from other contracts and
|
which means they can be called from other contracts and
|
||||||
via transactions. An external function ``f`` cannot be called
|
via transactions. An external function ``f`` cannot be called
|
||||||
internally (i.e. ``f()`` does not work, but ``this.f()`` works).
|
internally (i.e. ``f()`` does not work, but ``this.f()`` works).
|
||||||
External functions are sometimes more efficient when
|
|
||||||
they receive large arrays of data, because the data
|
|
||||||
is not copied from calldata to memory.
|
|
||||||
|
|
||||||
``public``
|
``public``
|
||||||
Public functions are part of the contract interface
|
Public functions are part of the contract interface
|
||||||
@ -35,6 +32,7 @@ For state variables, ``external`` is not possible.
|
|||||||
Those functions and state variables can only be
|
Those functions and state variables can only be
|
||||||
accessed internally (i.e. from within the current contract
|
accessed internally (i.e. from within the current contract
|
||||||
or contracts deriving from it), without using ``this``.
|
or contracts deriving from it), without using ``this``.
|
||||||
|
This is the default visibility level for state variables.
|
||||||
|
|
||||||
``private``
|
``private``
|
||||||
Private functions and state variables are only
|
Private functions and state variables are only
|
||||||
|
@ -109,6 +109,8 @@ Due to the fact that the EVM considers a call to a non-existing contract to
|
|||||||
always succeed, Solidity uses the ``extcodesize`` opcode to check that
|
always succeed, Solidity uses the ``extcodesize`` opcode to check that
|
||||||
the contract that is about to be called actually exists (it contains code)
|
the contract that is about to be called actually exists (it contains code)
|
||||||
and causes an exception if it does not.
|
and causes an exception if it does not.
|
||||||
|
Note that this check is not performed in case of :ref:`low-level calls <address_related>` which
|
||||||
|
operate on addresses rather than contract instances.
|
||||||
|
|
||||||
Function calls also cause exceptions if the called contract itself
|
Function calls also cause exceptions if the called contract itself
|
||||||
throws an exception or goes out of gas.
|
throws an exception or goes out of gas.
|
||||||
@ -531,6 +533,12 @@ and will wrap without an error if used inside an unchecked block:
|
|||||||
It is not possible to disable the check for division by zero
|
It is not possible to disable the check for division by zero
|
||||||
or modulo by zero using the ``unchecked`` block.
|
or modulo by zero using the ``unchecked`` block.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
Bitwise operators do not perform overflow or underflow checks.
|
||||||
|
This is particularly visible when using bitwise shifts (``<<``, ``>>``, ``<<=``, ``>>=``) in
|
||||||
|
place of integer division and multiplication by a power of 2.
|
||||||
|
For example ``type(uint256).max << 3`` does not revert even though ``type(uint256).max * 8`` would.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
The second statement in ``int x = type(int).min; -x;`` will result in an overflow
|
The second statement in ``int x = type(int).min; -x;`` will result in an overflow
|
||||||
because the negative range can hold one more value than the positive range.
|
because the negative range can hold one more value than the positive range.
|
||||||
|
@ -197,6 +197,9 @@ the ``.push`` member functions are not available).
|
|||||||
You either have to calculate the required size in advance
|
You either have to calculate the required size in advance
|
||||||
or create a new memory array and copy every element.
|
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>`.
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
// SPDX-License-Identifier: GPL-3.0
|
// SPDX-License-Identifier: GPL-3.0
|
||||||
|
@ -663,6 +663,16 @@ Note that public functions of the current contract can be used both as an
|
|||||||
internal and as an external function. To use ``f`` as an internal function,
|
internal and as an external function. To use ``f`` as an internal function,
|
||||||
just use ``f``, if you want to use its external form, use ``this.f``.
|
just use ``f``, if you want to use its external form, use ``this.f``.
|
||||||
|
|
||||||
|
A function of an internal type can be assigned to a variable of an internal function type regardless
|
||||||
|
of where it is defined.
|
||||||
|
This includes private, internal and public functions of both contracts and libraries as well as free
|
||||||
|
functions.
|
||||||
|
External function types, on the other hand, are only compatible with public and external contract
|
||||||
|
functions.
|
||||||
|
Libraries are excluded because they require a ``delegatecall`` and use :ref:`a different ABI
|
||||||
|
convention for their selectors <library-selectors>`.
|
||||||
|
Functions declared in interfaces do not have definitions so pointing at them does not make sense either.
|
||||||
|
|
||||||
Members:
|
Members:
|
||||||
|
|
||||||
External (or public) functions have the following members:
|
External (or public) functions have the following members:
|
||||||
|
@ -262,6 +262,16 @@ For more information, see the section on :ref:`address`.
|
|||||||
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
|
to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better:
|
||||||
Use a pattern where the recipient withdraws the money.
|
Use a pattern where the recipient withdraws the money.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
Due to the fact that the EVM considers a call to a non-existing contract to always succeed,
|
||||||
|
Solidity includes an extra check using the ``extcodesize`` opcode when performing external calls.
|
||||||
|
This ensures that the contract that is about to be called either actually exists (it contains code)
|
||||||
|
or an exception is raised.
|
||||||
|
|
||||||
|
The low-level calls which operate on addresses rather than contract instances (i.e. ``.call()``,
|
||||||
|
``.delegatecall()``, ``.staticcall()``, ``.send()`` and ``.transfer()``) **do not** include this
|
||||||
|
check, which makes them cheaper in terms of gas but also less safe.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example ``this.balance``.
|
Prior to version 0.5.0, Solidity allowed address members to be accessed by a contract instance, for example ``this.balance``.
|
||||||
This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``.
|
This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``.
|
||||||
|
@ -828,13 +828,14 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels a
|
|||||||
| extcodehash(a) | | C | code hash of address a |
|
| extcodehash(a) | | C | code hash of address a |
|
||||||
+-------------------------+-----+---+-----------------------------------------------------------------+
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
| create(v, p, n) | | F | create new contract with code mem[p...(p+n)) and send v wei |
|
| create(v, p, n) | | F | create new contract with code mem[p...(p+n)) and send v wei |
|
||||||
| | | | and return the new address |
|
| | | | and return the new address; returns 0 on error |
|
||||||
+-------------------------+-----+---+-----------------------------------------------------------------+
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
| create2(v, p, n, s) | | C | create new contract with code mem[p...(p+n)) at address |
|
| create2(v, p, n, s) | | C | create new contract with code mem[p...(p+n)) at address |
|
||||||
| | | | keccak256(0xff . this . s . keccak256(mem[p...(p+n))) |
|
| | | | keccak256(0xff . this . s . keccak256(mem[p...(p+n))) |
|
||||||
| | | | and send v wei and return the new address, where ``0xff`` is a |
|
| | | | and send v wei and return the new address, where ``0xff`` is a |
|
||||||
| | | | 1 byte value, ``this`` is the current contract's address |
|
| | | | 1 byte value, ``this`` is the current contract's address |
|
||||||
| | | | as a 20 byte value and ``s`` is a big-endian 256-bit value |
|
| | | | as a 20 byte value and ``s`` is a big-endian 256-bit value; |
|
||||||
|
| | | | returns 0 on error |
|
||||||
+-------------------------+-----+---+-----------------------------------------------------------------+
|
+-------------------------+-----+---+-----------------------------------------------------------------+
|
||||||
| call(g, a, v, in, | | F | call contract at address a with input mem[in...(in+insize)) |
|
| call(g, a, v, in, | | F | call contract at address a with input mem[in...(in+insize)) |
|
||||||
| insize, out, outsize) | | | providing g gas and v wei and output area |
|
| insize, out, outsize) | | | providing g gas and v wei and output area |
|
||||||
|
Loading…
Reference in New Issue
Block a user