aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/contracts.rst400
-rw-r--r--docs/contracts/functions.rst398
-rw-r--r--docs/examples/blind-auction.rst339
-rw-r--r--docs/frequently-asked-questions.rst36
-rw-r--r--docs/solidity-by-example.rst342
-rw-r--r--docs/types.rst187
-rw-r--r--docs/types/conversion.rst127
-rw-r--r--docs/types/mapping-types.rst58
8 files changed, 926 insertions, 961 deletions
diff --git a/docs/contracts.rst b/docs/contracts.rst
index 859cd9e9..646e4cdc 100644
--- a/docs/contracts.rst
+++ b/docs/contracts.rst
@@ -19,405 +19,7 @@ inaccessible.
.. include:: contracts/function-modifiers.rst
.. include:: contracts/constant-state-variables.rst
-
-.. index:: ! functions
-
-.. _functions:
-
-*********
-Functions
-*********
-
-.. _function-parameters-return-variables:
-
-Function Parameters and Return Variables
-========================================
-
-As in JavaScript, functions may take parameters as input. Unlike in JavaScript
-and C, functions may also return an arbitrary number of values as output.
-
-Function Parameters
--------------------
-
-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::
-
- pragma solidity >=0.4.16 <0.6.0;
-
- contract Simple {
- uint sum;
- function taker(uint _a, uint _b) public {
- sum = _a + _b;
- }
- }
-
-Function parameters can be used as any other local variable and they can also be assigned to.
-
-.. note::
-
- An :ref:`external function<external-function-calls>` cannot accept a
- multi-dimensional array as an input
- parameter. This functionality is possible if you enable the new
- experimental ``ABIEncoderV2`` feature by adding ``pragma experimental ABIEncoderV2;`` to your source file.
-
- An :ref:`internal function<external-function-calls>` can accept a
- multi-dimensional array without enabling the feature.
-
-.. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct
-
-Return Variables
-----------------
-
-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::
-
- pragma solidity >=0.4.16 <0.6.0;
-
- contract Simple {
- function arithmetic(uint _a, uint _b)
- public
- pure
- returns (uint o_sum, uint o_product)
- {
- o_sum = _a + _b;
- o_product = _a * _b;
- }
- }
-
-The names of return variables can be omitted.
-Return variables can be used as any other local variable and they
-are initialized with their :ref:`default value <default-value>` and have that value unless explicitly set.
-
-You can either explicitly assign to return variables and
-then leave the function using ``return;``,
-or you can provide return values
-(either a single or :ref:`multiple ones<multi-return>`) directly with the ``return``
-statement::
-
- pragma solidity >=0.4.16 <0.6.0;
-
- contract Simple {
- function arithmetic(uint _a, uint _b)
- public
- pure
- returns (uint o_sum, uint o_product)
- {
- return (_a + _b, _a * _b);
- }
- }
-
-This form is equivalent to first assigning values to the
-return variables and then using ``return;`` to leave the function.
-
-.. note::
- You cannot return some types from non-internal functions, notably
- multi-dimensional dynamic arrays and structs. If you enable the
- new experimental ``ABIEncoderV2`` feature by adding ``pragma experimental
- ABIEncoderV2;`` to your source file then more types are available, but
- ``mapping`` types are still limited to inside a single contract and you
- cannot transfer them.
-
-.. _multi-return:
-
-Returning Multiple Values
--------------------------
-
-When a function has multiple return types, the statement ``return (v0, v1, ..., vn)`` can be used to return multiple values.
-The number of components must be the same as the number of return types.
-
-.. index:: ! view function, function;view
-
-.. _view-functions:
-
-View Functions
-==============
-
-Functions can be declared ``view`` in which case they promise not to modify the state.
-
-.. note::
- If the compiler's EVM target is Byzantium or newer (default) the opcode
- ``STATICCALL`` is used for ``view`` functions which enforces the state
- to stay unmodified as part of the EVM execution. For library ``view`` functions
- ``DELEGATECALL`` is used, because there is no combined ``DELEGATECALL`` and ``STATICCALL``.
- This means library ``view`` functions do not have run-time checks that prevent state
- modifications. This should not impact security negatively because library code is
- usually known at compile-time and the static checker performs compile-time checks.
-
-The following statements are considered modifying the state:
-
-#. Writing to state variables.
-#. :ref:`Emitting events <events>`.
-#. :ref:`Creating other contracts <creating-contracts>`.
-#. Using ``selfdestruct``.
-#. Sending Ether via calls.
-#. Calling any function not marked ``view`` or ``pure``.
-#. Using low-level calls.
-#. Using inline assembly that contains certain opcodes.
-
-::
-
- pragma solidity ^0.5.0;
-
- contract C {
- function f(uint a, uint b) public view returns (uint) {
- return a * (b + 42) + now;
- }
- }
-
-.. note::
- ``constant`` on functions used to be an alias to ``view``, but this was dropped in version 0.5.0.
-
-.. note::
- Getter methods are automatically marked ``view``.
-
-.. note::
- Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode
- for ``view`` functions.
- This enabled state modifications in ``view`` functions through the use of
- invalid explicit type conversions.
- By using ``STATICCALL`` for ``view`` functions, modifications to the
- state are prevented on the level of the EVM.
-
-.. index:: ! pure function, function;pure
-
-.. _pure-functions:
-
-Pure Functions
-==============
-
-Functions can be declared ``pure`` in which case they promise not to read from or modify the state.
-
-.. note::
- If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used,
- which does not guarantee that the state is not read, but at least that it is not modified.
-
-In addition to the list of state modifying statements explained above, the following are considered reading from the state:
-
-#. Reading from state variables.
-#. Accessing ``address(this).balance`` or ``<address>.balance``.
-#. Accessing any of the members of ``block``, ``tx``, ``msg`` (with the exception of ``msg.sig`` and ``msg.data``).
-#. Calling any function not marked ``pure``.
-#. Using inline assembly that contains certain opcodes.
-
-::
-
- pragma solidity ^0.5.0;
-
- contract C {
- function f(uint a, uint b) public pure returns (uint) {
- return a * (b + 42);
- }
- }
-
-Pure functions are able to use the `revert()` and `require()` functions to revert
-potential state changes when an :ref:`error occurs <assert-and-require>`.
-
-Reverting a state change is not considered a "state modification", as only changes to the
-state made previously in code that did not have the ``view`` or ``pure`` restriction
-are reverted and that code has the option to catch the ``revert`` and not pass it on.
-
-This behaviour is also in line with the ``STATICCALL`` opcode.
-
-.. warning::
- It is not possible to prevent functions from reading the state at the level
- of the EVM, it is only possible to prevent them from writing to the state
- (i.e. only ``view`` can be enforced at the EVM level, ``pure`` can not).
-
-.. note::
- Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode
- for ``pure`` functions.
- This enabled state modifications in ``pure`` functions through the use of
- invalid explicit type conversions.
- By using ``STATICCALL`` for ``pure`` functions, modifications to the
- state are prevented on the level of the EVM.
-
-.. note::
- Prior to version 0.4.17 the compiler did not enforce that ``pure`` is not reading the state.
- It is a compile-time type check, which can be circumvented doing invalid explicit conversions
- between contract types, because the compiler can verify that the type of the contract does
- not do state-changing operations, but it cannot check that the contract that will be called
- at runtime is actually of that type.
-
-.. index:: ! fallback function, function;fallback
-
-.. _fallback-function:
-
-Fallback Function
-=================
-
-A contract can have exactly one unnamed function. This function cannot have
-arguments, cannot return anything and has to have ``external`` visibility.
-It is executed on a call to the contract if none of the other
-functions match the given function identifier (or if no data was supplied at
-all).
-
-Furthermore, this function is executed whenever the contract receives plain
-Ether (without data). Additionally, in order to receive Ether, the fallback function
-must be marked ``payable``. If no such function exists, the contract cannot receive
-Ether through regular transactions.
-
-In the worst case, the fallback function can only rely on 2300 gas being
-available (for example when `send` or `transfer` is used), leaving little
-room to perform other operations except basic logging. The following operations
-will consume more gas than the 2300 gas stipend:
-
-- Writing to storage
-- Creating a contract
-- Calling an external function which consumes a large amount of gas
-- Sending Ether
-
-Like any function, the fallback function can execute complex operations as long as there is enough gas passed on to it.
-
-.. note::
- Even though the fallback function cannot have arguments, one can still use ``msg.data`` to retrieve
- any payload supplied with the call.
-
-.. warning::
- The fallback function is also executed if the caller meant to call
- a function that is not available. If you want to implement the fallback
- function only to receive ether, you should add a check
- like ``require(msg.data.length == 0)`` to prevent invalid calls.
-
-.. warning::
- Contracts that receive Ether directly (without a function call, i.e. using ``send`` or ``transfer``)
- but do not define a fallback function
- throw an exception, sending back the Ether (this was different
- before Solidity v0.4.0). So if you want your contract to receive Ether,
- you have to implement a payable fallback function.
-
-.. warning::
- A contract without a payable fallback function can receive Ether as a recipient of a `coinbase transaction` (aka `miner block reward`)
- or as a destination of a ``selfdestruct``.
-
- A contract cannot react to such Ether transfers and thus also cannot reject them. This is a design choice of the EVM and Solidity cannot work around it.
-
- It also means that ``address(this).balance`` can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the fallback function).
-
-::
-
- pragma solidity ^0.5.0;
-
- contract Test {
- // This function is called for all messages sent to
- // this contract (there is no other function).
- // Sending Ether to this contract will cause an exception,
- // because the fallback function does not have the `payable`
- // modifier.
- function() external { x = 1; }
- uint x;
- }
-
-
- // This contract keeps all Ether sent to it with no way
- // to get it back.
- contract Sink {
- function() external payable { }
- }
-
- contract Caller {
- function callTest(Test test) public returns (bool) {
- (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
- require(success);
- // results in test.x becoming == 1.
-
- // address(test) will not allow to call ``send`` directly, since ``test`` has no payable
- // fallback function. It has to be converted to the ``address payable`` type via an
- // intermediate conversion to ``uint160`` to even allow calling ``send`` on it.
- address payable testPayable = address(uint160(address(test)));
-
- // If someone sends ether to that contract,
- // the transfer will fail, i.e. this returns false here.
- return testPayable.send(2 ether);
- }
- }
-
-.. index:: ! overload
-
-.. _overload-function:
-
-Function Overloading
-====================
-
-A contract can have multiple functions of the same name but with different parameter
-types.
-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``.
-
-::
-
- pragma solidity >=0.4.16 <0.6.0;
-
- contract A {
- function f(uint _in) public pure returns (uint out) {
- out = _in;
- }
-
- function f(uint _in, bool _really) public pure returns (uint out) {
- if (_really)
- out = _in;
- }
- }
-
-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.
-
-::
-
- pragma solidity >=0.4.16 <0.6.0;
-
- // This will not compile
- contract A {
- function f(B _in) public pure returns (B out) {
- out = _in;
- }
-
- function f(address _in) public pure returns (address out) {
- out = _in;
- }
- }
-
- contract B {
- }
-
-
-Both ``f`` function overloads above end up accepting the address type for the ABI although
-they are considered different inside Solidity.
-
-Overload resolution and Argument matching
------------------------------------------
-
-Overloaded functions are selected by matching the function declarations in the current scope
-to the arguments supplied in the function call. Functions are selected as overload candidates
-if all arguments can be implicitly converted to the expected types. If there is not exactly one
-candidate, resolution fails.
-
-.. note::
- Return parameters are not taken into account for overload resolution.
-
-::
-
- pragma solidity >=0.4.16 <0.6.0;
-
- contract A {
- function f(uint8 _in) public pure returns (uint8 out) {
- out = _in;
- }
-
- function f(uint256 _in) public pure returns (uint256 out) {
- out = _in;
- }
- }
-
-Calling ``f(50)`` would create a type error since ``50`` can be implicitly converted both to ``uint8``
-and ``uint256`` types. On another hand ``f(256)`` would resolve to ``f(uint256)`` overload as ``256`` cannot be implicitly
-converted to ``uint8``.
+.. include:: contracts/functions.rst
.. include:: contracts/events.rst
diff --git a/docs/contracts/functions.rst b/docs/contracts/functions.rst
new file mode 100644
index 00000000..76245952
--- /dev/null
+++ b/docs/contracts/functions.rst
@@ -0,0 +1,398 @@
+.. index:: ! functions
+
+.. _functions:
+
+*********
+Functions
+*********
+
+.. _function-parameters-return-variables:
+
+Function Parameters and Return Variables
+========================================
+
+As in JavaScript, functions may take parameters as input. Unlike in JavaScript
+and C, functions may also return an arbitrary number of values as output.
+
+Function Parameters
+-------------------
+
+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::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ contract Simple {
+ uint sum;
+ function taker(uint _a, uint _b) public {
+ sum = _a + _b;
+ }
+ }
+
+Function parameters can be used as any other local variable and they can also be assigned to.
+
+.. note::
+
+ An :ref:`external function<external-function-calls>` cannot accept a
+ multi-dimensional array as an input
+ parameter. This functionality is possible if you enable the new
+ experimental ``ABIEncoderV2`` feature by adding ``pragma experimental ABIEncoderV2;`` to your source file.
+
+ An :ref:`internal function<external-function-calls>` can accept a
+ multi-dimensional array without enabling the feature.
+
+.. index:: return array, return string, array, string, array of strings, dynamic array, variably sized array, return struct, struct
+
+Return Variables
+----------------
+
+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::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ contract Simple {
+ function arithmetic(uint _a, uint _b)
+ public
+ pure
+ returns (uint o_sum, uint o_product)
+ {
+ o_sum = _a + _b;
+ o_product = _a * _b;
+ }
+ }
+
+The names of return variables can be omitted.
+Return variables can be used as any other local variable and they
+are initialized with their :ref:`default value <default-value>` and have that value unless explicitly set.
+
+You can either explicitly assign to return variables and
+then leave the function using ``return;``,
+or you can provide return values
+(either a single or :ref:`multiple ones<multi-return>`) directly with the ``return``
+statement::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ contract Simple {
+ function arithmetic(uint _a, uint _b)
+ public
+ pure
+ returns (uint o_sum, uint o_product)
+ {
+ return (_a + _b, _a * _b);
+ }
+ }
+
+This form is equivalent to first assigning values to the
+return variables and then using ``return;`` to leave the function.
+
+.. note::
+ You cannot return some types from non-internal functions, notably
+ multi-dimensional dynamic arrays and structs. If you enable the
+ new experimental ``ABIEncoderV2`` feature by adding ``pragma experimental
+ ABIEncoderV2;`` to your source file then more types are available, but
+ ``mapping`` types are still limited to inside a single contract and you
+ cannot transfer them.
+
+.. _multi-return:
+
+Returning Multiple Values
+-------------------------
+
+When a function has multiple return types, the statement ``return (v0, v1, ..., vn)`` can be used to return multiple values.
+The number of components must be the same as the number of return types.
+
+.. index:: ! view function, function;view
+
+.. _view-functions:
+
+View Functions
+==============
+
+Functions can be declared ``view`` in which case they promise not to modify the state.
+
+.. note::
+ If the compiler's EVM target is Byzantium or newer (default) the opcode
+ ``STATICCALL`` is used for ``view`` functions which enforces the state
+ to stay unmodified as part of the EVM execution. For library ``view`` functions
+ ``DELEGATECALL`` is used, because there is no combined ``DELEGATECALL`` and ``STATICCALL``.
+ This means library ``view`` functions do not have run-time checks that prevent state
+ modifications. This should not impact security negatively because library code is
+ usually known at compile-time and the static checker performs compile-time checks.
+
+The following statements are considered modifying the state:
+
+#. Writing to state variables.
+#. :ref:`Emitting events <events>`.
+#. :ref:`Creating other contracts <creating-contracts>`.
+#. Using ``selfdestruct``.
+#. Sending Ether via calls.
+#. Calling any function not marked ``view`` or ``pure``.
+#. Using low-level calls.
+#. Using inline assembly that contains certain opcodes.
+
+::
+
+ pragma solidity ^0.5.0;
+
+ contract C {
+ function f(uint a, uint b) public view returns (uint) {
+ return a * (b + 42) + now;
+ }
+ }
+
+.. note::
+ ``constant`` on functions used to be an alias to ``view``, but this was dropped in version 0.5.0.
+
+.. note::
+ Getter methods are automatically marked ``view``.
+
+.. note::
+ Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode
+ for ``view`` functions.
+ This enabled state modifications in ``view`` functions through the use of
+ invalid explicit type conversions.
+ By using ``STATICCALL`` for ``view`` functions, modifications to the
+ state are prevented on the level of the EVM.
+
+.. index:: ! pure function, function;pure
+
+.. _pure-functions:
+
+Pure Functions
+==============
+
+Functions can be declared ``pure`` in which case they promise not to read from or modify the state.
+
+.. note::
+ If the compiler's EVM target is Byzantium or newer (default) the opcode ``STATICCALL`` is used,
+ which does not guarantee that the state is not read, but at least that it is not modified.
+
+In addition to the list of state modifying statements explained above, the following are considered reading from the state:
+
+#. Reading from state variables.
+#. Accessing ``address(this).balance`` or ``<address>.balance``.
+#. Accessing any of the members of ``block``, ``tx``, ``msg`` (with the exception of ``msg.sig`` and ``msg.data``).
+#. Calling any function not marked ``pure``.
+#. Using inline assembly that contains certain opcodes.
+
+::
+
+ pragma solidity ^0.5.0;
+
+ contract C {
+ function f(uint a, uint b) public pure returns (uint) {
+ return a * (b + 42);
+ }
+ }
+
+Pure functions are able to use the `revert()` and `require()` functions to revert
+potential state changes when an :ref:`error occurs <assert-and-require>`.
+
+Reverting a state change is not considered a "state modification", as only changes to the
+state made previously in code that did not have the ``view`` or ``pure`` restriction
+are reverted and that code has the option to catch the ``revert`` and not pass it on.
+
+This behaviour is also in line with the ``STATICCALL`` opcode.
+
+.. warning::
+ It is not possible to prevent functions from reading the state at the level
+ of the EVM, it is only possible to prevent them from writing to the state
+ (i.e. only ``view`` can be enforced at the EVM level, ``pure`` can not).
+
+.. note::
+ Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode
+ for ``pure`` functions.
+ This enabled state modifications in ``pure`` functions through the use of
+ invalid explicit type conversions.
+ By using ``STATICCALL`` for ``pure`` functions, modifications to the
+ state are prevented on the level of the EVM.
+
+.. note::
+ Prior to version 0.4.17 the compiler did not enforce that ``pure`` is not reading the state.
+ It is a compile-time type check, which can be circumvented doing invalid explicit conversions
+ between contract types, because the compiler can verify that the type of the contract does
+ not do state-changing operations, but it cannot check that the contract that will be called
+ at runtime is actually of that type.
+
+.. index:: ! fallback function, function;fallback
+
+.. _fallback-function:
+
+Fallback Function
+=================
+
+A contract can have exactly one unnamed function. This function cannot have
+arguments, cannot return anything and has to have ``external`` visibility.
+It is executed on a call to the contract if none of the other
+functions match the given function identifier (or if no data was supplied at
+all).
+
+Furthermore, this function is executed whenever the contract receives plain
+Ether (without data). Additionally, in order to receive Ether, the fallback function
+must be marked ``payable``. If no such function exists, the contract cannot receive
+Ether through regular transactions.
+
+In the worst case, the fallback function can only rely on 2300 gas being
+available (for example when `send` or `transfer` is used), leaving little
+room to perform other operations except basic logging. The following operations
+will consume more gas than the 2300 gas stipend:
+
+- Writing to storage
+- Creating a contract
+- Calling an external function which consumes a large amount of gas
+- Sending Ether
+
+Like any function, the fallback function can execute complex operations as long as there is enough gas passed on to it.
+
+.. note::
+ Even though the fallback function cannot have arguments, one can still use ``msg.data`` to retrieve
+ any payload supplied with the call.
+
+.. warning::
+ The fallback function is also executed if the caller meant to call
+ a function that is not available. If you want to implement the fallback
+ function only to receive ether, you should add a check
+ like ``require(msg.data.length == 0)`` to prevent invalid calls.
+
+.. warning::
+ Contracts that receive Ether directly (without a function call, i.e. using ``send`` or ``transfer``)
+ but do not define a fallback function
+ throw an exception, sending back the Ether (this was different
+ before Solidity v0.4.0). So if you want your contract to receive Ether,
+ you have to implement a payable fallback function.
+
+.. warning::
+ A contract without a payable fallback function can receive Ether as a recipient of a `coinbase transaction` (aka `miner block reward`)
+ or as a destination of a ``selfdestruct``.
+
+ A contract cannot react to such Ether transfers and thus also cannot reject them. This is a design choice of the EVM and Solidity cannot work around it.
+
+ It also means that ``address(this).balance`` can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the fallback function).
+
+::
+
+ pragma solidity ^0.5.0;
+
+ contract Test {
+ // This function is called for all messages sent to
+ // this contract (there is no other function).
+ // Sending Ether to this contract will cause an exception,
+ // because the fallback function does not have the `payable`
+ // modifier.
+ function() external { x = 1; }
+ uint x;
+ }
+
+
+ // This contract keeps all Ether sent to it with no way
+ // to get it back.
+ contract Sink {
+ function() external payable { }
+ }
+
+ contract Caller {
+ function callTest(Test test) public returns (bool) {
+ (bool success,) = address(test).call(abi.encodeWithSignature("nonExistingFunction()"));
+ require(success);
+ // results in test.x becoming == 1.
+
+ // address(test) will not allow to call ``send`` directly, since ``test`` has no payable
+ // fallback function. It has to be converted to the ``address payable`` type via an
+ // intermediate conversion to ``uint160`` to even allow calling ``send`` on it.
+ address payable testPayable = address(uint160(address(test)));
+
+ // If someone sends ether to that contract,
+ // the transfer will fail, i.e. this returns false here.
+ return testPayable.send(2 ether);
+ }
+ }
+
+.. index:: ! overload
+
+.. _overload-function:
+
+Function Overloading
+====================
+
+A contract can have multiple functions of the same name but with different parameter
+types.
+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``.
+
+::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ contract A {
+ function f(uint _in) public pure returns (uint out) {
+ out = _in;
+ }
+
+ function f(uint _in, bool _really) public pure returns (uint out) {
+ if (_really)
+ out = _in;
+ }
+ }
+
+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.
+
+::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ // This will not compile
+ contract A {
+ function f(B _in) public pure returns (B out) {
+ out = _in;
+ }
+
+ function f(address _in) public pure returns (address out) {
+ out = _in;
+ }
+ }
+
+ contract B {
+ }
+
+
+Both ``f`` function overloads above end up accepting the address type for the ABI although
+they are considered different inside Solidity.
+
+Overload resolution and Argument matching
+-----------------------------------------
+
+Overloaded functions are selected by matching the function declarations in the current scope
+to the arguments supplied in the function call. Functions are selected as overload candidates
+if all arguments can be implicitly converted to the expected types. If there is not exactly one
+candidate, resolution fails.
+
+.. note::
+ Return parameters are not taken into account for overload resolution.
+
+::
+
+ pragma solidity >=0.4.16 <0.6.0;
+
+ contract A {
+ function f(uint8 _in) public pure returns (uint8 out) {
+ out = _in;
+ }
+
+ function f(uint256 _in) public pure returns (uint256 out) {
+ out = _in;
+ }
+ }
+
+Calling ``f(50)`` would create a type error since ``50`` can be implicitly converted both to ``uint8``
+and ``uint256`` types. On another hand ``f(256)`` would resolve to ``f(uint256)`` overload as ``256`` cannot be implicitly
+converted to ``uint8``.
diff --git a/docs/examples/blind-auction.rst b/docs/examples/blind-auction.rst
new file mode 100644
index 00000000..70d95ad6
--- /dev/null
+++ b/docs/examples/blind-auction.rst
@@ -0,0 +1,339 @@
+.. index:: auction;blind, auction;open, blind auction, open auction
+
+*************
+Blind Auction
+*************
+
+In this section, we will show how easy it is to create a
+completely blind auction contract on Ethereum.
+We will start with an open auction where everyone
+can see the bids that are made and then extend this
+contract into a blind auction where it is not
+possible to see the actual bid until the bidding
+period ends.
+
+.. _simple_auction:
+
+Simple Open Auction
+===================
+
+The general idea of the following simple auction contract
+is that everyone can send their bids during
+a bidding period. The bids already include sending
+money / ether in order to bind the bidders to their
+bid. If the highest bid is raised, the previously
+highest bidder gets her 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.
+
+::
+
+ pragma solidity >=0.4.22 <0.6.0;
+
+ contract SimpleAuction {
+ // Parameters of the auction. Times are either
+ // absolute unix timestamps (seconds since 1970-01-01)
+ // or time periods in seconds.
+ address payable public beneficiary;
+ uint public auctionEndTime;
+
+ // Current state of the auction.
+ address public highestBidder;
+ uint public highestBid;
+
+ // Allowed withdrawals of previous bids
+ mapping(address => uint) pendingReturns;
+
+ // Set to true at the end, disallows any change.
+ // By default initialized to `false`.
+ bool ended;
+
+ // Events that will be emitted on changes.
+ event HighestBidIncreased(address bidder, uint amount);
+ event AuctionEnded(address winner, uint amount);
+
+ // The following is a so-called natspec comment,
+ // recognizable by the three slashes.
+ // It will be shown when the user is asked to
+ // confirm a transaction.
+
+ /// Create a simple auction with `_biddingTime`
+ /// seconds bidding time on behalf of the
+ /// beneficiary address `_beneficiary`.
+ constructor(
+ uint _biddingTime,
+ address payable _beneficiary
+ ) public {
+ beneficiary = _beneficiary;
+ auctionEndTime = now + _biddingTime;
+ }
+
+ /// Bid on the auction with the value sent
+ /// together with this transaction.
+ /// The value will only be refunded if the
+ /// auction is not won.
+ function bid() public payable {
+ // No arguments are necessary, all
+ // information is already part of
+ // the transaction. The keyword payable
+ // is required for the function to
+ // be able to receive Ether.
+
+ // Revert the call if the bidding
+ // period is over.
+ require(
+ now <= auctionEndTime,
+ "Auction already ended."
+ );
+
+ // If the bid is not higher, send the
+ // money back.
+ require(
+ msg.value > highestBid,
+ "There already is a higher bid."
+ );
+
+ if (highestBid != 0) {
+ // Sending back the money by simply using
+ // highestBidder.send(highestBid) is a security risk
+ // because it could execute an untrusted contract.
+ // It is always safer to let the recipients
+ // withdraw their money themselves.
+ pendingReturns[highestBidder] += highestBid;
+ }
+ highestBidder = msg.sender;
+ highestBid = msg.value;
+ emit HighestBidIncreased(msg.sender, msg.value);
+ }
+
+ /// Withdraw a bid that was overbid.
+ function withdraw() public returns (bool) {
+ uint amount = pendingReturns[msg.sender];
+ if (amount > 0) {
+ // It is important to set this to zero because the recipient
+ // can call this function again as part of the receiving call
+ // before `send` returns.
+ pendingReturns[msg.sender] = 0;
+
+ if (!msg.sender.send(amount)) {
+ // No need to call throw here, just reset the amount owing
+ pendingReturns[msg.sender] = amount;
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /// End the auction and send the highest bid
+ /// to the beneficiary.
+ function auctionEnd() public {
+ // It is a good guideline to structure functions that interact
+ // with other contracts (i.e. they call functions or send Ether)
+ // into three phases:
+ // 1. checking conditions
+ // 2. performing actions (potentially changing conditions)
+ // 3. interacting with other contracts
+ // If these phases are mixed up, the other contract could call
+ // back into the current contract and modify the state or cause
+ // effects (ether payout) to be performed multiple times.
+ // If functions called internally include interaction with external
+ // contracts, they also have to be considered interaction with
+ // external contracts.
+
+ // 1. Conditions
+ require(now >= auctionEndTime, "Auction not yet ended.");
+ require(!ended, "auctionEnd has already been called.");
+
+ // 2. Effects
+ ended = true;
+ emit AuctionEnded(highestBidder, highestBid);
+
+ // 3. Interaction
+ beneficiary.transfer(highestBid);
+ }
+ }
+
+Blind Auction
+=============
+
+The previous open auction is extended to a blind auction
+in the following. The advantage of a blind auction is
+that there is no time pressure towards the end of
+the bidding period. Creating a blind auction on a
+transparent computing platform might sound like a
+contradiction, but cryptography comes to the rescue.
+
+During the **bidding period**, a bidder does not
+actually send her bid, but only a hashed version of it.
+Since it is currently considered practically impossible
+to find two (sufficiently long) values whose hash
+values are equal, the bidder commits to the bid by that.
+After the end of the bidding period, the bidders have
+to reveal their bids: They send their values
+unencrypted and the contract checks that the hash value
+is the same as the one provided during the bidding period.
+
+Another challenge is how to make the auction
+**binding and blind** at the same time: The only way to
+prevent the bidder from just not sending the money
+after they won the auction is to make her send it
+together with the bid. Since value transfers cannot
+be blinded in Ethereum, anyone can see the value.
+
+The following contract solves this problem by
+accepting any value that is larger than the highest
+bid. Since this can of course only be checked during
+the reveal phase, some bids might be **invalid**, and
+this is on purpose (it even provides an explicit
+flag to place invalid bids with high value transfers):
+Bidders can confuse competition by placing several
+high or low invalid bids.
+
+
+::
+
+ pragma solidity >0.4.23 <0.6.0;
+
+ contract BlindAuction {
+ struct Bid {
+ bytes32 blindedBid;
+ uint deposit;
+ }
+
+ address payable public beneficiary;
+ uint public biddingEnd;
+ uint public revealEnd;
+ bool public ended;
+
+ mapping(address => Bid[]) public bids;
+
+ address public highestBidder;
+ uint public highestBid;
+
+ // Allowed withdrawals of previous bids
+ mapping(address => uint) pendingReturns;
+
+ event AuctionEnded(address winner, uint highestBid);
+
+ /// Modifiers are a convenient way to validate inputs to
+ /// functions. `onlyBefore` is applied to `bid` below:
+ /// The new function body is the modifier's body where
+ /// `_` is replaced by the old function body.
+ modifier onlyBefore(uint _time) { require(now < _time); _; }
+ modifier onlyAfter(uint _time) { require(now > _time); _; }
+
+ constructor(
+ uint _biddingTime,
+ uint _revealTime,
+ address payable _beneficiary
+ ) public {
+ beneficiary = _beneficiary;
+ biddingEnd = now + _biddingTime;
+ revealEnd = biddingEnd + _revealTime;
+ }
+
+ /// Place a blinded bid with `_blindedBid` =
+ /// keccak256(abi.encodePacked(value, fake, secret)).
+ /// The sent ether is only refunded if the bid is correctly
+ /// revealed in the revealing phase. The bid is valid if the
+ /// ether sent together with the bid is at least "value" and
+ /// "fake" is not true. Setting "fake" to true and sending
+ /// not the exact amount are ways to hide the real bid but
+ /// still make the required deposit. The same address can
+ /// place multiple bids.
+ function bid(bytes32 _blindedBid)
+ public
+ payable
+ onlyBefore(biddingEnd)
+ {
+ bids[msg.sender].push(Bid({
+ blindedBid: _blindedBid,
+ deposit: msg.value
+ }));
+ }
+
+ /// Reveal your blinded bids. You will get a refund for all
+ /// correctly blinded invalid bids and for all bids except for
+ /// the totally highest.
+ function reveal(
+ uint[] memory _values,
+ bool[] memory _fake,
+ bytes32[] memory _secret
+ )
+ public
+ onlyAfter(biddingEnd)
+ onlyBefore(revealEnd)
+ {
+ uint length = bids[msg.sender].length;
+ require(_values.length == length);
+ require(_fake.length == length);
+ require(_secret.length == length);
+
+ uint refund;
+ for (uint i = 0; i < length; i++) {
+ Bid storage bidToCheck = bids[msg.sender][i];
+ (uint value, bool fake, bytes32 secret) =
+ (_values[i], _fake[i], _secret[i]);
+ if (bidToCheck.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {
+ // Bid was not actually revealed.
+ // Do not refund deposit.
+ continue;
+ }
+ refund += bidToCheck.deposit;
+ if (!fake && bidToCheck.deposit >= value) {
+ if (placeBid(msg.sender, value))
+ refund -= value;
+ }
+ // Make it impossible for the sender to re-claim
+ // the same deposit.
+ bidToCheck.blindedBid = bytes32(0);
+ }
+ msg.sender.transfer(refund);
+ }
+
+ // This is an "internal" function which means that it
+ // can only be called from the contract itself (or from
+ // derived contracts).
+ function placeBid(address bidder, uint value) internal
+ returns (bool success)
+ {
+ if (value <= highestBid) {
+ return false;
+ }
+ if (highestBidder != address(0)) {
+ // Refund the previously highest bidder.
+ pendingReturns[highestBidder] += highestBid;
+ }
+ highestBid = value;
+ highestBidder = bidder;
+ return true;
+ }
+
+ /// Withdraw a bid that was overbid.
+ function withdraw() public {
+ uint amount = pendingReturns[msg.sender];
+ if (amount > 0) {
+ // It is important to set this to zero because the recipient
+ // can call this function again as part of the receiving call
+ // before `transfer` returns (see the remark above about
+ // conditions -> effects -> interaction).
+ pendingReturns[msg.sender] = 0;
+
+ msg.sender.transfer(amount);
+ }
+ }
+
+ /// End the auction and send the highest bid
+ /// to the beneficiary.
+ function auctionEnd()
+ public
+ onlyAfter(revealEnd)
+ {
+ require(!ended);
+ emit AuctionEnded(highestBidder, highestBid);
+ ended = true;
+ beneficiary.transfer(highestBid);
+ }
+ } \ No newline at end of file
diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst
index 2cc082b4..4635d577 100644
--- a/docs/frequently-asked-questions.rst
+++ b/docs/frequently-asked-questions.rst
@@ -77,15 +77,6 @@ otherwise an exception is thrown.
Advanced Questions
******************
-How do you get a random number in a contract? (Implement a self-returning gambling contract.)
-=============================================================================================
-
-Getting randomness right is often the crucial part in a crypto project and
-most failures result from bad random number generators.
-
-If you do not want it to be safe, you build something similar to the `coin flipper <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/35_coin_flipper.sol>`_
-but otherwise, rather use a contract that supplies randomness, like the `RANDAO <https://github.com/randao/randao>`_.
-
Get return value from non-constant function from another contract
=================================================================
@@ -94,23 +85,6 @@ The key point is that the calling contract needs to know about the function it i
See `ping.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_ping.sol>`_
and `pong.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_pong.sol>`_.
-How do you create 2-dimensional arrays?
-=======================================
-
-See `2D_array.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/55_2D_array.sol>`_.
-
-Note that filling a 10x10 square of ``uint8`` + contract creation took more than ``800,000``
-gas at the time of this writing. 17x17 took ``2,000,000`` gas. With the limit at
-3.14 million... well, there’s a pretty low ceiling for what you can create right
-now.
-
-Note that merely "creating" the array is free, the costs are in filling it.
-
-Note2: Optimizing storage access can pull the gas costs down considerably, because
-32 ``uint8`` values can be stored in a single slot. The problem is that these optimizations
-currently do not work across loops and also have a problem with bounds checking.
-You might get much better results in the future, though.
-
How do I initialize a contract with only a specific amount of wei?
==================================================================
@@ -178,16 +152,6 @@ does not fit inside this range, it is truncated. These truncations can have
above is necessary to avoid certain attacks.
-Why are explicit conversions between fixed-size bytes types and integer types failing?
-======================================================================================
-
-Since version 0.5.0 explicit conversions between fixed-size byte arrays and integers are only allowed,
-if both types have the same size. This prevents unexpected behaviour when truncating or padding.
-Such conversions are still possible, but intermediate casts are required that make the desired
-truncation and padding convention explicit. See :ref:`types-conversion-elementary-types` for a full
-explanation and examples.
-
-
Why can number literals not be converted to fixed-size bytes types?
===================================================================
diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst
index e94a9c29..933b0765 100644
--- a/docs/solidity-by-example.rst
+++ b/docs/solidity-by-example.rst
@@ -3,347 +3,7 @@ Solidity by Example
###################
.. include:: examples/voting.rst
-
-.. index:: auction;blind, auction;open, blind auction, open auction
-
-*************
-Blind Auction
-*************
-
-In this section, we will show how easy it is to create a
-completely blind auction contract on Ethereum.
-We will start with an open auction where everyone
-can see the bids that are made and then extend this
-contract into a blind auction where it is not
-possible to see the actual bid until the bidding
-period ends.
-
-.. _simple_auction:
-
-Simple Open Auction
-===================
-
-The general idea of the following simple auction contract
-is that everyone can send their bids during
-a bidding period. The bids already include sending
-money / ether in order to bind the bidders to their
-bid. If the highest bid is raised, the previously
-highest bidder gets her 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.
-
-::
-
- pragma solidity >=0.4.22 <0.6.0;
-
- contract SimpleAuction {
- // Parameters of the auction. Times are either
- // absolute unix timestamps (seconds since 1970-01-01)
- // or time periods in seconds.
- address payable public beneficiary;
- uint public auctionEndTime;
-
- // Current state of the auction.
- address public highestBidder;
- uint public highestBid;
-
- // Allowed withdrawals of previous bids
- mapping(address => uint) pendingReturns;
-
- // Set to true at the end, disallows any change.
- // By default initialized to `false`.
- bool ended;
-
- // Events that will be emitted on changes.
- event HighestBidIncreased(address bidder, uint amount);
- event AuctionEnded(address winner, uint amount);
-
- // The following is a so-called natspec comment,
- // recognizable by the three slashes.
- // It will be shown when the user is asked to
- // confirm a transaction.
-
- /// Create a simple auction with `_biddingTime`
- /// seconds bidding time on behalf of the
- /// beneficiary address `_beneficiary`.
- constructor(
- uint _biddingTime,
- address payable _beneficiary
- ) public {
- beneficiary = _beneficiary;
- auctionEndTime = now + _biddingTime;
- }
-
- /// Bid on the auction with the value sent
- /// together with this transaction.
- /// The value will only be refunded if the
- /// auction is not won.
- function bid() public payable {
- // No arguments are necessary, all
- // information is already part of
- // the transaction. The keyword payable
- // is required for the function to
- // be able to receive Ether.
-
- // Revert the call if the bidding
- // period is over.
- require(
- now <= auctionEndTime,
- "Auction already ended."
- );
-
- // If the bid is not higher, send the
- // money back.
- require(
- msg.value > highestBid,
- "There already is a higher bid."
- );
-
- if (highestBid != 0) {
- // Sending back the money by simply using
- // highestBidder.send(highestBid) is a security risk
- // because it could execute an untrusted contract.
- // It is always safer to let the recipients
- // withdraw their money themselves.
- pendingReturns[highestBidder] += highestBid;
- }
- highestBidder = msg.sender;
- highestBid = msg.value;
- emit HighestBidIncreased(msg.sender, msg.value);
- }
-
- /// Withdraw a bid that was overbid.
- function withdraw() public returns (bool) {
- uint amount = pendingReturns[msg.sender];
- if (amount > 0) {
- // It is important to set this to zero because the recipient
- // can call this function again as part of the receiving call
- // before `send` returns.
- pendingReturns[msg.sender] = 0;
-
- if (!msg.sender.send(amount)) {
- // No need to call throw here, just reset the amount owing
- pendingReturns[msg.sender] = amount;
- return false;
- }
- }
- return true;
- }
-
- /// End the auction and send the highest bid
- /// to the beneficiary.
- function auctionEnd() public {
- // It is a good guideline to structure functions that interact
- // with other contracts (i.e. they call functions or send Ether)
- // into three phases:
- // 1. checking conditions
- // 2. performing actions (potentially changing conditions)
- // 3. interacting with other contracts
- // If these phases are mixed up, the other contract could call
- // back into the current contract and modify the state or cause
- // effects (ether payout) to be performed multiple times.
- // If functions called internally include interaction with external
- // contracts, they also have to be considered interaction with
- // external contracts.
-
- // 1. Conditions
- require(now >= auctionEndTime, "Auction not yet ended.");
- require(!ended, "auctionEnd has already been called.");
-
- // 2. Effects
- ended = true;
- emit AuctionEnded(highestBidder, highestBid);
-
- // 3. Interaction
- beneficiary.transfer(highestBid);
- }
- }
-
-Blind Auction
-=============
-
-The previous open auction is extended to a blind auction
-in the following. The advantage of a blind auction is
-that there is no time pressure towards the end of
-the bidding period. Creating a blind auction on a
-transparent computing platform might sound like a
-contradiction, but cryptography comes to the rescue.
-
-During the **bidding period**, a bidder does not
-actually send her bid, but only a hashed version of it.
-Since it is currently considered practically impossible
-to find two (sufficiently long) values whose hash
-values are equal, the bidder commits to the bid by that.
-After the end of the bidding period, the bidders have
-to reveal their bids: They send their values
-unencrypted and the contract checks that the hash value
-is the same as the one provided during the bidding period.
-
-Another challenge is how to make the auction
-**binding and blind** at the same time: The only way to
-prevent the bidder from just not sending the money
-after they won the auction is to make her send it
-together with the bid. Since value transfers cannot
-be blinded in Ethereum, anyone can see the value.
-
-The following contract solves this problem by
-accepting any value that is larger than the highest
-bid. Since this can of course only be checked during
-the reveal phase, some bids might be **invalid**, and
-this is on purpose (it even provides an explicit
-flag to place invalid bids with high value transfers):
-Bidders can confuse competition by placing several
-high or low invalid bids.
-
-
-::
-
- pragma solidity >0.4.23 <0.6.0;
-
- contract BlindAuction {
- struct Bid {
- bytes32 blindedBid;
- uint deposit;
- }
-
- address payable public beneficiary;
- uint public biddingEnd;
- uint public revealEnd;
- bool public ended;
-
- mapping(address => Bid[]) public bids;
-
- address public highestBidder;
- uint public highestBid;
-
- // Allowed withdrawals of previous bids
- mapping(address => uint) pendingReturns;
-
- event AuctionEnded(address winner, uint highestBid);
-
- /// Modifiers are a convenient way to validate inputs to
- /// functions. `onlyBefore` is applied to `bid` below:
- /// The new function body is the modifier's body where
- /// `_` is replaced by the old function body.
- modifier onlyBefore(uint _time) { require(now < _time); _; }
- modifier onlyAfter(uint _time) { require(now > _time); _; }
-
- constructor(
- uint _biddingTime,
- uint _revealTime,
- address payable _beneficiary
- ) public {
- beneficiary = _beneficiary;
- biddingEnd = now + _biddingTime;
- revealEnd = biddingEnd + _revealTime;
- }
-
- /// Place a blinded bid with `_blindedBid` =
- /// keccak256(abi.encodePacked(value, fake, secret)).
- /// The sent ether is only refunded if the bid is correctly
- /// revealed in the revealing phase. The bid is valid if the
- /// ether sent together with the bid is at least "value" and
- /// "fake" is not true. Setting "fake" to true and sending
- /// not the exact amount are ways to hide the real bid but
- /// still make the required deposit. The same address can
- /// place multiple bids.
- function bid(bytes32 _blindedBid)
- public
- payable
- onlyBefore(biddingEnd)
- {
- bids[msg.sender].push(Bid({
- blindedBid: _blindedBid,
- deposit: msg.value
- }));
- }
-
- /// Reveal your blinded bids. You will get a refund for all
- /// correctly blinded invalid bids and for all bids except for
- /// the totally highest.
- function reveal(
- uint[] memory _values,
- bool[] memory _fake,
- bytes32[] memory _secret
- )
- public
- onlyAfter(biddingEnd)
- onlyBefore(revealEnd)
- {
- uint length = bids[msg.sender].length;
- require(_values.length == length);
- require(_fake.length == length);
- require(_secret.length == length);
-
- uint refund;
- for (uint i = 0; i < length; i++) {
- Bid storage bidToCheck = bids[msg.sender][i];
- (uint value, bool fake, bytes32 secret) =
- (_values[i], _fake[i], _secret[i]);
- if (bidToCheck.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) {
- // Bid was not actually revealed.
- // Do not refund deposit.
- continue;
- }
- refund += bidToCheck.deposit;
- if (!fake && bidToCheck.deposit >= value) {
- if (placeBid(msg.sender, value))
- refund -= value;
- }
- // Make it impossible for the sender to re-claim
- // the same deposit.
- bidToCheck.blindedBid = bytes32(0);
- }
- msg.sender.transfer(refund);
- }
-
- // This is an "internal" function which means that it
- // can only be called from the contract itself (or from
- // derived contracts).
- function placeBid(address bidder, uint value) internal
- returns (bool success)
- {
- if (value <= highestBid) {
- return false;
- }
- if (highestBidder != address(0)) {
- // Refund the previously highest bidder.
- pendingReturns[highestBidder] += highestBid;
- }
- highestBid = value;
- highestBidder = bidder;
- return true;
- }
-
- /// Withdraw a bid that was overbid.
- function withdraw() public {
- uint amount = pendingReturns[msg.sender];
- if (amount > 0) {
- // It is important to set this to zero because the recipient
- // can call this function again as part of the receiving call
- // before `transfer` returns (see the remark above about
- // conditions -> effects -> interaction).
- pendingReturns[msg.sender] = 0;
-
- msg.sender.transfer(amount);
- }
- }
-
- /// End the auction and send the highest bid
- /// to the beneficiary.
- function auctionEnd()
- public
- onlyAfter(revealEnd)
- {
- require(!ended);
- emit AuctionEnded(highestBidder, highestBid);
- ended = true;
- beneficiary.transfer(highestBid);
- }
- }
-
+.. include:: examples/blind-auction.rst
.. include:: examples/safe-remote.rst
diff --git a/docs/types.rst b/docs/types.rst
index ea45b7d7..b9c06f6c 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -22,191 +22,8 @@ tuple with a second `bool` value denoting success.
.. include:: types/reference-types.rst
-.. index:: !mapping
-.. _mapping-types:
-
-Mapping Types
-=============
-
-You declare mapping types with the syntax ``mapping(_KeyType => _ValueType)``.
-The ``_KeyType`` can be any elementary type. This means it can be any of
-the built-in value types plus ``bytes`` and ``string``. User-defined
-or complex types like contract types, enums, mappings, structs and any array type
-apart from ``bytes`` and ``string`` are not allowed.
-``_ValueType`` can be any type, including mappings.
-
-You can think of mappings as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_, which are virtually initialised
-such that every possible key exists and is mapped to a value whose
-byte-representation is all zeros, a type's :ref:`default value <default-value>`. The similarity ends there, the key data is not stored in a
-mapping, only its ``keccak256`` hash is used to look up the value.
-
-Because of this, mappings do not have a length or a concept of a key or
-value being set.
-
-Mappings can only have a data location of ``storage`` and thus
-are allowed for state variables, as storage reference types
-in functions, or as parameters for library functions.
-They cannot be used as parameters or return parameters
-of contract functions that are publicly visible.
-
-You can mark variables of mapping type as ``public`` and Solidity creates a
-:ref:`getter <visibility-and-getters>` for you. The ``_KeyType`` becomes a
-parameter for the getter. If ``_ValueType`` is a value type or a struct,
-the getter returns ``_ValueType``.
-If ``_ValueType`` is an array or a mapping, the getter has one parameter for
-each ``_KeyType``, recursively. For example with a mapping:
-
-::
-
- pragma solidity >=0.4.0 <0.6.0;
-
- contract MappingExample {
- mapping(address => uint) public balances;
-
- function update(uint newBalance) public {
- balances[msg.sender] = newBalance;
- }
- }
-
- contract MappingUser {
- function f() public returns (uint) {
- MappingExample m = new MappingExample();
- m.update(100);
- return m.balances(address(this));
- }
- }
-
-
-.. note::
- Mappings are not iterable, but it is possible to implement a data structure
- on top of them. For an example, see `iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_.
+.. include:: types/mapping-types.rst
.. include:: types/operators.rst
-.. index:: ! type;conversion, ! cast
-
-.. _types-conversion-elementary-types:
-
-Conversions between Elementary Types
-====================================
-
-Implicit Conversions
---------------------
-
-If an operator is applied to different types, the compiler tries to
-implicitly convert one of the operands to the type of the other (the same is
-true for assignments). In general, an implicit conversion between value-types
-is possible if it
-makes sense semantically and no information is lost: ``uint8`` is convertible to
-``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256``
-(because ``uint256`` cannot hold e.g. ``-1``).
-
-For more details, please consult the sections about the types themselves.
-
-Explicit Conversions
---------------------
-
-If the compiler does not allow implicit conversion but you know what you are
-doing, an explicit type conversion is sometimes possible. Note that this may
-give you some unexpected behaviour and allows you to bypass some security
-features of the compiler, so be sure to test that the
-result is what you want! Take the following example where you are converting
-a negative ``int8`` to a ``uint``:
-
-::
-
- int8 y = -3;
- uint x = uint(y);
-
-At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex
-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::
-
- 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::
-
- uint16 a = 0x1234;
- uint32 b = uint32(a); // b will be 0x00001234 now
- assert(a == b);
-
-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::
-
- 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)::
-
- bytes2 a = 0x1234;
- bytes4 b = bytes4(a); // b will be 0x12340000
- assert(a[0] == b[0]);
- assert(a[1] == b[1]);
-
-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::
-
- bytes2 a = 0x1234;
- uint32 b = uint16(a); // b will be 0x00001234
- uint32 c = uint32(bytes4(a)); // c will be 0x12340000
- uint8 d = uint8(uint16(a)); // d will be 0x34
- uint8 e = uint8(bytes1(a)); // e will be 0x12
-
-.. _types-conversion-literals:
-
-Conversions between Literals and Elementary Types
-=================================================
-
-Integer Types
--------------
-
-Decimal and hexadecimal number literals can be implicitly converted to any integer type
-that is large enough to represent it without truncation::
-
- uint8 a = 12; // fine
- uint32 b = 1234; // fine
- uint16 c = 0x123456; // fails, since it would have to truncate to 0x3456
-
-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::
-
- bytes2 a = 54321; // not allowed
- bytes2 b = 0x12; // not allowed
- bytes2 c = 0x123; // not allowed
- bytes2 d = 0x1234; // fine
- bytes2 e = 0x0012; // fine
- bytes4 f = 0; // fine
- 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::
-
- bytes2 a = hex"1234"; // fine
- bytes2 b = "xy"; // fine
- bytes2 c = hex"12"; // not allowed
- bytes2 d = hex"123"; // not allowed
- bytes2 e = "x"; // not allowed
- bytes2 f = "xyz"; // not allowed
-
-Addresses
----------
-
-As described in :ref:`address_literals`, hex literals of the correct size that pass the checksum
-test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type.
-
-Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``.
+.. include:: types/conversion.rst \ No newline at end of file
diff --git a/docs/types/conversion.rst b/docs/types/conversion.rst
new file mode 100644
index 00000000..5a9f84c0
--- /dev/null
+++ b/docs/types/conversion.rst
@@ -0,0 +1,127 @@
+.. index:: ! type;conversion, ! cast
+
+.. _types-conversion-elementary-types:
+
+Conversions between Elementary Types
+====================================
+
+Implicit Conversions
+--------------------
+
+If an operator is applied to different types, the compiler tries to
+implicitly convert one of the operands to the type of the other (the same is
+true for assignments). In general, an implicit conversion between value-types
+is possible if it
+makes sense semantically and no information is lost: ``uint8`` is convertible to
+``uint16`` and ``int128`` to ``int256``, but ``int8`` is not convertible to ``uint256``
+(because ``uint256`` cannot hold e.g. ``-1``).
+
+For more details, please consult the sections about the types themselves.
+
+Explicit Conversions
+--------------------
+
+If the compiler does not allow implicit conversion but you know what you are
+doing, an explicit type conversion is sometimes possible. Note that this may
+give you some unexpected behaviour and allows you to bypass some security
+features of the compiler, so be sure to test that the
+result is what you want! Take the following example where you are converting
+a negative ``int8`` to a ``uint``:
+
+::
+
+ int8 y = -3;
+ uint x = uint(y);
+
+At the end of this code snippet, ``x`` will have the value ``0xfffff..fd`` (64 hex
+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::
+
+ 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::
+
+ uint16 a = 0x1234;
+ uint32 b = uint32(a); // b will be 0x00001234 now
+ assert(a == b);
+
+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::
+
+ 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)::
+
+ bytes2 a = 0x1234;
+ bytes4 b = bytes4(a); // b will be 0x12340000
+ assert(a[0] == b[0]);
+ assert(a[1] == b[1]);
+
+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::
+
+ bytes2 a = 0x1234;
+ uint32 b = uint16(a); // b will be 0x00001234
+ uint32 c = uint32(bytes4(a)); // c will be 0x12340000
+ uint8 d = uint8(uint16(a)); // d will be 0x34
+ uint8 e = uint8(bytes1(a)); // e will be 0x12
+
+.. _types-conversion-literals:
+
+Conversions between Literals and Elementary Types
+=================================================
+
+Integer Types
+-------------
+
+Decimal and hexadecimal number literals can be implicitly converted to any integer type
+that is large enough to represent it without truncation::
+
+ uint8 a = 12; // fine
+ uint32 b = 1234; // fine
+ uint16 c = 0x123456; // fails, since it would have to truncate to 0x3456
+
+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::
+
+ bytes2 a = 54321; // not allowed
+ bytes2 b = 0x12; // not allowed
+ bytes2 c = 0x123; // not allowed
+ bytes2 d = 0x1234; // fine
+ bytes2 e = 0x0012; // fine
+ bytes4 f = 0; // fine
+ 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::
+
+ bytes2 a = hex"1234"; // fine
+ bytes2 b = "xy"; // fine
+ bytes2 c = hex"12"; // not allowed
+ bytes2 d = hex"123"; // not allowed
+ bytes2 e = "x"; // not allowed
+ bytes2 f = "xyz"; // not allowed
+
+Addresses
+---------
+
+As described in :ref:`address_literals`, hex literals of the correct size that pass the checksum
+test are of ``address`` type. No other literals can be implicitly converted to the ``address`` type.
+
+Explicit conversions from ``bytes20`` or any integer type to ``address`` result in ``address payable``.
diff --git a/docs/types/mapping-types.rst b/docs/types/mapping-types.rst
new file mode 100644
index 00000000..935ed6b4
--- /dev/null
+++ b/docs/types/mapping-types.rst
@@ -0,0 +1,58 @@
+.. index:: !mapping
+.. _mapping-types:
+
+Mapping Types
+=============
+
+You declare mapping types with the syntax ``mapping(_KeyType => _ValueType)``.
+The ``_KeyType`` can be any elementary type. This means it can be any of
+the built-in value types plus ``bytes`` and ``string``. User-defined
+or complex types like contract types, enums, mappings, structs and any array type
+apart from ``bytes`` and ``string`` are not allowed.
+``_ValueType`` can be any type, including mappings.
+
+You can think of mappings as `hash tables <https://en.wikipedia.org/wiki/Hash_table>`_, which are virtually initialised
+such that every possible key exists and is mapped to a value whose
+byte-representation is all zeros, a type's :ref:`default value <default-value>`. The similarity ends there, the key data is not stored in a
+mapping, only its ``keccak256`` hash is used to look up the value.
+
+Because of this, mappings do not have a length or a concept of a key or
+value being set.
+
+Mappings can only have a data location of ``storage`` and thus
+are allowed for state variables, as storage reference types
+in functions, or as parameters for library functions.
+They cannot be used as parameters or return parameters
+of contract functions that are publicly visible.
+
+You can mark variables of mapping type as ``public`` and Solidity creates a
+:ref:`getter <visibility-and-getters>` for you. The ``_KeyType`` becomes a
+parameter for the getter. If ``_ValueType`` is a value type or a struct,
+the getter returns ``_ValueType``.
+If ``_ValueType`` is an array or a mapping, the getter has one parameter for
+each ``_KeyType``, recursively. For example with a mapping:
+
+::
+
+ pragma solidity >=0.4.0 <0.6.0;
+
+ contract MappingExample {
+ mapping(address => uint) public balances;
+
+ function update(uint newBalance) public {
+ balances[msg.sender] = newBalance;
+ }
+ }
+
+ contract MappingUser {
+ function f() public returns (uint) {
+ MappingExample m = new MappingExample();
+ m.update(100);
+ return m.balances(address(this));
+ }
+ }
+
+
+.. note::
+ Mappings are not iterable, but it is possible to implement a data structure
+ on top of them. For an example, see `iterable mapping <https://github.com/ethereum/dapp-bin/blob/master/library/iterable_mapping.sol>`_.