diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/050-breaking-changes.rst | 2 | ||||
-rw-r--r-- | docs/abi-spec.rst | 25 | ||||
-rw-r--r-- | docs/contributing.rst | 6 | ||||
-rw-r--r-- | docs/grammar.txt | 2 | ||||
-rw-r--r-- | docs/introduction-to-smart-contracts.rst | 29 | ||||
-rw-r--r-- | docs/types.rst | 65 | ||||
-rw-r--r-- | docs/using-the-compiler.rst | 50 |
7 files changed, 135 insertions, 44 deletions
diff --git a/docs/050-breaking-changes.rst b/docs/050-breaking-changes.rst index 7b5acd89..5a7add5d 100644 --- a/docs/050-breaking-changes.rst +++ b/docs/050-breaking-changes.rst @@ -198,6 +198,8 @@ Literals and Suffixes * Combining hex numbers with unit denominations (e.g. ``0x1e wei``) is now disallowed. +* The prefix ``0X`` for hex numbers is disallowed, only ``0x`` is possible. + Variables --------- diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 92af8f0c..4e7c88d0 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -78,8 +78,29 @@ Types can be combined to a tuple by enclosing them inside parentheses, separated It is possible to form tuples of tuples, arrays of tuples and so on. It is also possible to form zero-tuples (where ``n == 0``). -.. note:: - Solidity supports all the types presented above with the same names with the exception of tuples. The ABI tuple type is utilised for encoding Solidity ``structs``. +Mapping Solidity to ABI types +----------------------------- + +Solidity supports all the types presented above with the same names with the +exception of tuples. On the other hand, some Solidity types are not supported +by the ABI. The following table shows on the left column Solidity types that +are not part of the ABI, and on the right column the ABI types that represent +them. + ++-------------------------------+-----------------------------------------------------------------------------+ +| Solidity | ABI | ++===============================+=============================================================================+ +|:ref:`address payable<address>`|``address`` | ++-------------------------------+-----------------------------------------------------------------------------+ +|:ref:`contract<contracts>` |``address`` | ++-------------------------------+-----------------------------------------------------------------------------+ +|:ref:`enum<enums>` |smallest ``uint`` type that is large enough to hold all values | +| | | +| |For example, an ``enum`` of 255 values or less is mapped to ``uint8`` and | +| |an ``enum`` of 256 values is mapped to ``uint16``. | ++-------------------------------+-----------------------------------------------------------------------------+ +|:ref:`struct<structs>` |``tuple`` | ++-------------------------------+-----------------------------------------------------------------------------+ Formal Specification of the Encoding ==================================== diff --git a/docs/contributing.rst b/docs/contributing.rst index 6fe96be4..d1ed9c6b 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -19,6 +19,8 @@ In particular, we need help in the following areas: `up-for-grabs <https://github.com/ethereum/solidity/issues?q=is%3Aopen+is%3Aissue+label%3Aup-for-grabs>`_ which are meant as introductory issues for external contributors. +Please note that this project is released with a `Contributor Code of Conduct <https://raw.githubusercontent.com/ethereum/solidity/develop/CODE_OF_CONDUCT.md>`_. By participating in this project - in the issues, pull requests, or Gitter channels - you agree to abide by its terms. + How to Report Issues ==================== @@ -62,10 +64,6 @@ Finally, please make sure you respect the `coding style for this project. Also, even though we do CI testing, please test your code and ensure that it builds locally before submitting a pull request. -Please note that this project is released with a `Contributor Code of Conduct -<https://raw.githubusercontent.com/ethereum/solidity/develop/CODE_OF_CONDUCT.md>`_. -By participating in this project you agree to abide by its terms. - Thank you for your help! Running the compiler tests diff --git a/docs/grammar.txt b/docs/grammar.txt index 594998f0..b9c8ddb9 100644 --- a/docs/grammar.txt +++ b/docs/grammar.txt @@ -132,7 +132,7 @@ HexLiteral = 'hex' ('"' ([0-9a-fA-F]{2})* '"' | '\'' ([0-9a-fA-F]{2})* '\'') StringLiteral = '"' ([^"\r\n\\] | '\\' .)* '"' Identifier = [a-zA-Z_$] [a-zA-Z_$0-9]* -HexNumber = '0' [xX] [0-9a-fA-F]+ +HexNumber = '0x' [0-9a-fA-F]+ DecimalNumber = [0-9]+ ( '.' [0-9]* )? ( [eE] [0-9]+ )? TupleExpression = '(' ( Expression? ( ',' Expression? )* )? ')' diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index bd30a8fd..5ba7ed12 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -220,7 +220,7 @@ Blockchain Basics Blockchains as a concept are not too hard to understand for programmers. The reason is that most of the complications (mining, `hashing <https://en.wikipedia.org/wiki/Cryptographic_hash_function>`_, `elliptic-curve cryptography <https://en.wikipedia.org/wiki/Elliptic_curve_cryptography>`_, `peer-to-peer networks <https://en.wikipedia.org/wiki/Peer-to-peer>`_, etc.) -are just there to provide a certain set of features and promises. Once you accept these +are just there to provide a certain set of features and promises for the platform. Once you accept these features as given, you do not have to worry about the underlying technology - or do you have to know how Amazon's AWS works internally in order to use it? @@ -235,7 +235,7 @@ If you want to change something in the database, you have to create a so-called which has to be accepted by all others. The word transaction implies that the change you want to make (assume you want to change two values at the same time) is either not done at all or completely applied. Furthermore, -while your transaction is applied to the database, no other transaction can alter it. +while your transaction is being applied to the database, no other transaction can alter it. As an example, imagine a table that lists the balances of all accounts in an electronic currency. If a transfer from one account to another is requested, @@ -254,12 +254,13 @@ only the person holding the keys to the account can transfer money from it. Blocks ====== -One major obstacle to overcome is what, in Bitcoin terms, is called a "double-spend attack": -What happens if two transactions exist in the network that both want to empty an account, -a so-called conflict? +One major obstacle to overcome is what (in Bitcoin terms) is called a "double-spend attack": +What happens if two transactions exist in the network that both want to empty an account? +Only one of the transactions can be valid, typically the one that is accepted first. +The problem is that "first" is not an objective term in a peer-to-peer network. -The abstract answer to this is that you do not have to care. An order of the transactions -will be selected for you, the transactions will be bundled into what is called a "block" +The abstract answer to this is that you do not have to care. A globally accepted order of the transactions +will be selected for you, solving the conflict. The transactions will be bundled into what is called a "block" and then they will be executed and distributed among all participating nodes. If two transactions contradict each other, the one that ends up being second will be rejected and not become part of the block. @@ -270,14 +271,16 @@ Ethereum this is roughly every 17 seconds. As part of the "order selection mechanism" (which is called "mining") it may happen that blocks are reverted from time to time, but only at the "tip" of the chain. The more -blocks that are added on top, the less likely it is. So it might be that your transactions +blocks are added on top of a particular block, the less likely this block will be reverted. So it might be that your transactions are reverted and even removed from the blockchain, but the longer you wait, the less likely it will be. .. note:: - Transactions are not guaranteed to happen on the next block or any future specific block, since it is up to the miners to include transactions and not the submitter of the transaction. This applies to function calls and contract creation transactions alike. + Transactions are not guaranteed to be included in the next block or any specific future block, + since it is not up to the submitter of a transaction, but up to the miners to determine in which block the transaction is included. - If you want to schedule future calls of your contract, you can use the `alarm clock <http://www.ethereum-alarm-clock.com/>`_ service. + If you want to schedule future calls of your contract, you can use + the `alarm clock <http://www.ethereum-alarm-clock.com/>`_ or a similar oracle service. .. _the-ethereum-virtual-machine: @@ -319,7 +322,7 @@ Every account has a persistent key-value store mapping 256-bit words to 256-bit words called **storage**. Furthermore, every account has a **balance** in -Ether (in "Wei" to be exact) which can be modified by sending transactions that +Ether (in "Wei" to be exact, `1 ether` is `10**18 wei`) which can be modified by sending transactions that include Ether. .. index:: ! transaction @@ -329,7 +332,7 @@ Transactions A transaction is a message that is sent from one account to another account (which might be the same or the special zero-account, see below). -It can include binary data (its payload) and Ether. +It can include binary data (which is called "payload") and Ether. If the target account contains code, that code is executed and the payload is provided as input data. @@ -340,7 +343,7 @@ As already mentioned, the address of that contract is not the zero address but an address derived from the sender and its number of transactions sent (the "nonce"). The payload of such a contract creation transaction is taken to be -EVM bytecode and executed. The output of this execution is +EVM bytecode and executed. The output data of this execution is permanently stored as the code of the contract. This means that in order to create a contract, you do not send the actual code of the contract, but in fact code that diff --git a/docs/types.rst b/docs/types.rst index 432420d3..c5ce4c31 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -137,15 +137,26 @@ Operators: Address ------- -``address``: Holds a 20 byte value (size of an Ethereum address). Address types also have members and serve as a base for all contracts. -``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``. +The address type comes in two flavours, which are largely identical: + + - ``address``: Holds a 20 byte value (size of an Ethereum address). + - ``address payable``: Same as ``address``, but with the additional members ``transfer`` and ``send``. + +The idea behind this distinction is that ``address payable`` is an address you can send Ether to, +while a plain ``address`` cannot be sent Ether. + +Type conversions: Implicit conversions from ``address payable`` to ``address`` are allowed, whereas conversions from ``address`` to ``address payable`` are not possible (the only way to perform such a conversion is by using an intermediate conversion to ``uint160``). + +:ref:`Address literals<address_literals>` can be implicitly converted to ``address payable``. + +Explicit conversions to and from ``address`` are allowed for integers, integer literals, ``bytes20`` and contract types with the following +caveat: Conversions of the form ``address payable(x)`` are not allowed. Instead the result of a conversion of the form ``address(x)`` has the type ``address payable``, if ``x`` is of integer or fixed bytes type, a literal or a contract with a payable fallback function. -If ``x`` is a contract without payable fallback function ``address(x)`` will be of type ``address``. The type of address literals -is ``address payable``. +If ``x`` is a contract without payable fallback function, then ``address(x)`` will be of type ``address``. In external function signatures ``address`` is used for both the ``address`` and the ``address payable`` type. Operators: @@ -161,7 +172,8 @@ Operators: or you can use ``address(uint160(uint256(b)))``, which results in ``0x777788889999AaAAbBbbCcccddDdeeeEfFFfCcCc``. .. note:: - Starting with version 0.5.0 contracts do not derive from the address type, but can still be explicitly converted to + The distinction between ``address`` and ``address payable`` was introduced with version 0.5.0. + Also starting from that version, contracts do not derive from the address type, but can still be explicitly converted to ``address`` or to ``address payable``, if they have a payable fallback function. .. _members-of-addresses: @@ -169,9 +181,9 @@ Operators: Members of Addresses ^^^^^^^^^^^^^^^^^^^^ -* ``balance`` and ``transfer`` +For a quick reference of all members of address, see :ref:`address_related`. -For a quick reference, see :ref:`address_related`. +* ``balance`` and ``transfer`` 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: @@ -179,9 +191,13 @@ and to send Ether (in units of wei) to a payable address using the ``transfer`` :: address payable x = address(0x123); - address myAddress = this; + address myAddress = address(this); if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10); +The ``transfer`` function fails if the balance of the current contract is not large enough +or if the Ether transfer is rejected by the receiving account. The ``transfer`` function +reverts on failure. + .. note:: If ``x`` is a contract address, its code (more specifically: its :ref:`fallback-function`, if present) will be executed together with the ``transfer`` call (this is a feature of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted and the current contract will stop with an exception. @@ -195,14 +211,23 @@ Send is the low-level counterpart of ``transfer``. If the execution fails, the c 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. -* ``call``, ``callcode``, ``delegatecall`` and ``staticcall`` +* ``call``, ``delegatecall`` and ``staticcall`` -Furthermore, to interface with contracts that do not adhere to the ABI, +In order to interface with contracts that do not adhere to the ABI, or to get more direct control over the encoding, -the function ``call`` is provided which takes a single byte array as input. +the functions ``call``, ``delegatecall`` and ``staticcall`` are provided. +They all take a single ``bytes memory`` argument as input and +return the success condition (as a ``bool``) and the returned data +(``bytes memory``). The functions ``abi.encode``, ``abi.encodePacked``, ``abi.encodeWithSelector`` and ``abi.encodeWithSignature`` can be used to encode structured data. +Example:: + + bytes memory payload = abi.encodeWithSignature("register(string)", "MyName"); + (bool success, bytes memory returnData) = address(nameReg).call(payload); + require(success); + .. warning:: All these functions are low-level functions and should be used with care. Specifically, any unknown contract might be malicious and if you call it, you @@ -216,8 +241,6 @@ and ``abi.encodeWithSignature`` can be used to encode structured data. arbitrary arguments and would also handle a first argument of type ``bytes4`` differently. These edge cases were removed in version 0.5.0. -``call`` returns a boolean indicating whether the invoked function terminated (``true``) or caused an EVM exception (``false``). It is not possible to access the actual data returned with plain Solidity. However, using inline assembly it is possible to make a raw ``call`` and access the actual data returned with the ``returndatacopy`` instruction. - It is possible to adjust the supplied gas with the ``.gas()`` modifier:: namReg.call.gas(1000000)(abi.encodeWithSignature("register(string)", "MyName")); @@ -230,17 +253,14 @@ Lastly, these modifiers can be combined. Their order does not matter:: nameReg.call.gas(1000000).value(1 ether)(abi.encodeWithSignature("register(string)", "MyName")); -.. note:: - It is not yet possible to use the gas or value modifiers on overloaded functions. - - A workaround is to introduce a special case for gas and value and just re-check - whether they are present at the point of overload resolution. +In a similar way, the function ``delegatecall`` can be used: the difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. -In a similar way, the function ``delegatecall`` can be used: the difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. Prior to homestead, only a limited variant called ``callcode`` was available that did not provide access to the original ``msg.sender`` and ``msg.value`` values. +.. note:: + Prior to homestead, only a limited variant called ``callcode`` was available that did not provide access to the original ``msg.sender`` and ``msg.value`` values. This function was removed in version 0.5.0. -Since byzantium ``staticcall`` can be used as well. This is basically the same as ``call``, but will revert, if the called function modifies the state in any way. +Since byzantium ``staticcall`` can be used as well. This is basically the same as ``call``, but will revert if the called function modifies the state in any way. -All four functions ``call``, ``delegatecall``, ``callcode`` and ``staticcall`` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. +All three functions ``call``, ``delegatecall`` and ``staticcall`` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. The ``.gas()`` option is available on all three methods, while the ``.value()`` option is not supported for ``delegatecall``. @@ -248,9 +268,6 @@ The ``.gas()`` option is available on all three methods, while the ``.value()`` All contracts can be converted to ``address`` type, so it is possible to query the balance of the current contract using ``address(this).balance``. -.. note:: - The use of ``callcode`` is discouraged and will be removed in the future. - .. index:: ! contract type, ! type; contract .. _contract_types: diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 0a64d840..1e4bbecc 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -45,6 +45,56 @@ If ``solc`` is called with the option ``--link``, all input files are interprete If ``solc`` is called with the option ``--standard-json``, it will expect a JSON input (as explained below) on the standard input, and return a JSON output on the standard output. +.. _evm-version: +.. index:: ! EVM version, compile target + +Setting the EVM version to target +********************************* + +When you compile your contract code you can specify the Ethereum virtual machine +version to compile for to avoid particular features or behaviours. + +.. warning:: + + Compiling for the wrong EVM version can result in wrong, strange and failing + behaviour. Please ensure, especially if running a private chain, that you + use matching EVM versions. + +You use the ``--evm-version`` option on the command line: + +.. code-block:: shell + + solc --evm-version <VERSION> contract.sol + +Or if using the :ref:`standard JSON interface <compiler-api>`, with the ``evmVersion`` key: + +.. code-block:: json + + { + "evmVersion": "<VERSION>" + } + +Target options +-------------- + +Below is a list of target EVM versions and the compiler-relevant changes introduced +at each version. Backward compatibility is not guaranteed between each version. + +- ``homestead`` +- ``tangerineWhistle`` + - gas cost for access to other accounts increased, relevant for gas estimation and the optimizer. + - all gas sent by default for external calls, previously a certain amount had to be retained. +- ``spuriousDragon`` + - gas cost for the ``exp`` opcode increased, relevant for gas estimation and the optimizer. +- ``byzantium`` (**default**) + - opcodes ``returndatacopy``, ``returndatasize`` and ``staticcall`` are available in assembly. + - the ``staticcall`` opcode is used when calling view or pure functions, which prevents the functions from modifying state at the EVM level, i.e., even applies when you use invalid type conversions. + - it is possible to access dynamic data returned from function calls. + - ``revert`` opcode introduced, which means that ``revert()`` will not waste gas. +- ``constantinople`` (still in progress) + - opcodes ``shl``, ``shr`` and ``sar`` are available in assembly. + - shifting operators use shifting opcodes and thus need less gas. + .. _compiler-api: Compiler Input and Output JSON Description |