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.
|
||||
|
||||
.. _abi_function_selector:
|
||||
.. index:: 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
|
||||
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::
|
||||
In an earlier version of Solidity, ``return`` statements in functions
|
||||
having modifiers behaved differently.
|
||||
|
||||
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.
|
||||
An explicit return from a modifier with ``return;`` does not affect the values returned by the function.
|
||||
The modifier can, however, choose not to execute the function body at all and in that case the return
|
||||
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,
|
||||
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
|
||||
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
|
||||
|
||||
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.)
|
||||
|
||||
.. _library-selectors:
|
||||
.. index:: selector
|
||||
|
||||
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
|
||||
via transactions. An external function ``f`` cannot be called
|
||||
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 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
|
||||
accessed internally (i.e. from within the current contract
|
||||
or contracts deriving from it), without using ``this``.
|
||||
This is the default visibility level for state variables.
|
||||
|
||||
``private``
|
||||
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
|
||||
the contract that is about to be called actually exists (it contains code)
|
||||
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
|
||||
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
|
||||
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::
|
||||
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.
|
||||
|
@ -197,6 +197,9 @@ the ``.push`` member functions are not available).
|
||||
You either have to calculate the required size in advance
|
||||
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
|
||||
|
@ -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,
|
||||
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:
|
||||
|
||||
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:
|
||||
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::
|
||||
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``.
|
||||
|
@ -828,13 +828,14 @@ the ``dup`` and ``swap`` instructions as well as ``jump`` instructions, labels 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 |
|
||||
| | | | 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 |
|
||||
| | | | keccak256(0xff . this . s . keccak256(mem[p...(p+n))) |
|
||||
| | | | and send v wei and return the new address, where ``0xff`` is a |
|
||||
| | | | 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)) |
|
||||
| insize, out, outsize) | | | providing g gas and v wei and output area |
|
||||
|
Loading…
Reference in New Issue
Block a user