diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/050-breaking-changes.rst | 4 | ||||
-rw-r--r-- | docs/abi-spec.rst | 35 | ||||
-rw-r--r-- | docs/assembly.rst | 10 | ||||
-rw-r--r-- | docs/common-patterns.rst | 12 | ||||
-rw-r--r-- | docs/contracts.rst | 162 | ||||
-rw-r--r-- | docs/contributing.rst | 6 | ||||
-rw-r--r-- | docs/control-structures.rst | 100 | ||||
-rw-r--r-- | docs/frequently-asked-questions.rst | 12 | ||||
-rw-r--r-- | docs/grammar.txt | 2 | ||||
-rw-r--r-- | docs/introduction-to-smart-contracts.rst | 4 | ||||
-rw-r--r-- | docs/layout-of-source-files.rst | 15 | ||||
-rw-r--r-- | docs/miscellaneous.rst | 46 | ||||
-rw-r--r-- | docs/security-considerations.rst | 10 | ||||
-rw-r--r-- | docs/solidity-by-example.rst | 10 | ||||
-rw-r--r-- | docs/structure-of-a-contract.rst | 12 | ||||
-rw-r--r-- | docs/style-guide.rst | 28 | ||||
-rw-r--r-- | docs/types.rst | 170 | ||||
-rw-r--r-- | docs/units-and-global-variables.rst | 98 | ||||
-rw-r--r-- | docs/using-the-compiler.rst | 50 |
19 files changed, 488 insertions, 298 deletions
diff --git a/docs/050-breaking-changes.rst b/docs/050-breaking-changes.rst index e0c33538..1c12daa8 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 --------- @@ -327,7 +329,7 @@ New version: :: - pragma solidity >0.4.25; + pragma solidity >0.4.99 <0.6.0; contract OtherContract { uint x; diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 8a5e2f5c..7c9d9f9e 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -13,9 +13,9 @@ The Contract Application Binary Interface (ABI) is the standard way to interact from outside the blockchain and for contract-to-contract interaction. Data is encoded according to its type, as described in this specification. The encoding is not self describing and thus requires a schema in order to decode. -We assume the interface functions of a contract are strongly typed, known at compilation time and static. No introspection mechanism will be provided. We assume that all contracts will have the interface definitions of any contracts they call available at compile-time. +We assume the interface functions of a contract are strongly typed, known at compilation time and static. We assume that all contracts will have the interface definitions of any contracts they call available at compile-time. -This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. Should these cases become important they can be adequately handled as facilities built within the Ethereum ecosystem. +This specification does not address contracts whose interface is dynamic or otherwise known only at run-time. .. _abi_function_selector: @@ -23,12 +23,12 @@ Function Selector ================= The first four bytes of the call data for a function call specifies the function to be called. It is the -first (left, high-order in big-endian) four bytes of the Keccak (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype, i.e. +first (left, high-order in big-endian) four bytes of the Keccak-256 (SHA-3) hash of the signature of the function. The signature is defined as the canonical expression of the basic prototype without data location specifier, i.e. the function name with the parenthesised list of parameter types. Parameter types are split by a single comma - no spaces are used. .. note:: The return type of a function is not part of this signature. In :ref:`Solidity's function overloading <overload-function>` return types are not considered. The reason is to keep function call resolution context-independent. - The JSON description of the ABI however contains both inputs and outputs. See (the :ref:`JSON ABI <abi_json>`) + The :ref:`JSON description of the ABI<abi_json>` however contains both inputs and outputs. Argument Encoding ================= @@ -78,13 +78,14 @@ 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 ----------------------------- -The following table shows on the left column Solidity types that are not part of the ABI, -and on the right column the ABI type that they map to. + +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 | @@ -98,6 +99,8 @@ and on the right column the ABI type that they map to. | |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 ==================================== @@ -109,7 +112,7 @@ Properties: 1. The number of reads necessary to access a value is at most the depth of the value inside the argument array structure, i.e. four reads are needed to retrieve ``a_i[k][l][r]``. In a previous version of the ABI, the number of reads scaled linearly with the total number of dynamic parameters in the worst case. - 2. The data of a variable or array element is not interleaved with other data and it is relocatable, i.e. it only uses relative "addresses" + 2. The data of a variable or array element is not interleaved with other data and it is relocatable, i.e. it only uses relative "addresses". We distinguish static and dynamic types. Static types are encoded in-place and dynamic types are encoded at a separately allocated location after the current block. @@ -208,7 +211,7 @@ Given the contract: :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract Foo { function bar(bytes3[2] memory) public pure {} @@ -434,8 +437,8 @@ A function description is a JSON object with the fields: * ``components``: used for tuple types (more below). - ``outputs``: an array of objects similar to ``inputs``, can be omitted if function doesn't return anything; -- ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain state <view-functions>`), ``nonpayable`` (function does not accept ether) and ``payable`` (function accepts ether); -- ``payable``: ``true`` if function accepts ether, ``false`` otherwise; +- ``stateMutability``: a string with one of the following values: ``pure`` (:ref:`specified to not read blockchain state <pure-functions>`), ``view`` (:ref:`specified to not modify the blockchain state <view-functions>`), ``nonpayable`` (function does not accept Ether) and ``payable`` (function accepts Ether); +- ``payable``: ``true`` if function accepts Ether, ``false`` otherwise; - ``constant``: ``true`` if function is either ``pure`` or ``view``, ``false`` otherwise. ``type`` can be omitted, defaulting to ``"function"``, likewise ``payable`` and ``constant`` can be omitted, both defaulting to ``false``. @@ -446,7 +449,7 @@ Constructor and fallback function never have ``name`` or ``outputs``. Fallback f The fields ``constant`` and ``payable`` are deprecated and will be removed in the future. Instead, the ``stateMutability`` field can be used to determine the same properties. .. note:: - Sending non-zero ether to non-payable function will revert the transaction. + Sending non-zero Ether to non-payable function will revert the transaction. An event description is a JSON object with fairly similar fields: @@ -465,7 +468,7 @@ For example, :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract Test { constructor() public { b = hex"12345678901234567890123456789012"; } @@ -512,7 +515,7 @@ As an example, the code :: - pragma solidity ^0.4.19; + pragma solidity >=0.4.19 <0.6.0; pragma experimental ABIEncoderV2; contract Test { diff --git a/docs/assembly.rst b/docs/assembly.rst index 90bfa1f1..5d723645 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -67,7 +67,7 @@ idea is that assembly libraries will be used to enhance the Solidity language. .. code:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; library GetCode { function at(address _addr) public view returns (bytes memory o_code) { @@ -92,7 +92,7 @@ efficient code, for example: .. code:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; library VectorSum { // This function is less efficient because the optimizer currently fails to @@ -381,7 +381,7 @@ Local Solidity variables are available for assignments, for example: .. code:: - pragma solidity ^0.4.11; + pragma solidity >=0.4.11 <0.6.0; contract C { uint b; @@ -420,7 +420,7 @@ be just ``0``, but it can also be a complex functional-style expression. .. code:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { function f(uint x) public view returns (uint b) { @@ -685,7 +685,7 @@ Example: We will follow an example compilation from Solidity to assembly. We consider the runtime bytecode of the following Solidity program:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { function f(uint x) public pure returns (uint y) { diff --git a/docs/common-patterns.rst b/docs/common-patterns.rst index d26e4377..84c18936 100644 --- a/docs/common-patterns.rst +++ b/docs/common-patterns.rst @@ -13,11 +13,11 @@ Withdrawal from Contracts The recommended method of sending funds after an effect is using the withdrawal pattern. Although the most intuitive method of sending Ether, as a result of an effect, is a -direct ``send`` call, this is not recommended as it +direct ``transfer`` call, this is not recommended as it introduces a potential security risk. You may read more about this on the :ref:`security_considerations` page. -This is an example of the withdrawal pattern in practice in +The following is an example of the withdrawal pattern in practice in a contract where the goal is to send the most money to the contract in order to become the "richest", inspired by `King of the Ether <https://www.kingoftheether.com/>`_. @@ -28,7 +28,7 @@ become the new richest. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract WithdrawalContract { address public richest; @@ -65,7 +65,7 @@ This is as opposed to the more intuitive sending pattern: :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract SendContract { address payable public richest; @@ -130,7 +130,7 @@ restrictions highly readable. :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract AccessRestriction { // These will be assigned at the construction @@ -282,7 +282,7 @@ function finishes. :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract StateMachine { enum Stages { diff --git a/docs/contracts.rst b/docs/contracts.rst index 470d775e..315d1815 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -23,12 +23,12 @@ Contracts can be created "from outside" via Ethereum transactions or from within IDEs, such as `Remix <https://remix.ethereum.org/>`_, make the creation process seamless using UI elements. Creating contracts programmatically on Ethereum is best done via using the JavaScript API `web3.js <https://github.com/ethereum/web3.js>`_. -As of today it has a method called `web3.eth.Contract <https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#new-contract>`_ +It has a function called `web3.eth.Contract <https://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#new-contract>`_ to facilitate contract creation. When a contract is created, its constructor_ (a function declared with the ``constructor`` keyword) is executed once. -A constructor is optional. Only one constructor is allowed, and this means +A constructor is optional. Only one constructor is allowed, which means overloading is not supported. .. index:: constructor;arguments @@ -42,7 +42,7 @@ This means that cyclic creation dependencies are impossible. :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract OwnedToken { // TokenCreator is a contract type that is defined below. @@ -72,7 +72,7 @@ This means that cyclic creation dependencies are impossible. function changeName(bytes32 newName) public { // Only the creator can alter the name -- // the comparison is possible since contracts - // are implicitly convertible to addresses. + // are explicitly convertible to addresses. if (msg.sender == address(creator)) name = newName; } @@ -80,11 +80,11 @@ This means that cyclic creation dependencies are impossible. function transfer(address newOwner) public { // Only the current owner can transfer the token. if (msg.sender != owner) return; + // We also want to ask the creator if the transfer // is fine. Note that this calls a function of the // contract defined below. If the call fails (e.g. - // due to out-of-gas), the execution here stops - // immediately. + // due to out-of-gas), the execution also fails here. if (creator.isTokenTransferOK(owner, newOwner)) owner = newOwner; } @@ -102,7 +102,7 @@ This means that cyclic creation dependencies are impossible. return new OwnedToken(name); } - function changeName(OwnedToken tokenAddress, bytes32 name) public { + function changeName(OwnedToken tokenAddress, bytes32 name) public { // Again, the external type of `tokenAddress` is // simply `address`. tokenAddress.changeName(name); @@ -162,7 +162,7 @@ For state variables, ``external`` is not possible. .. note:: Everything that is inside a contract is visible to - all external observers. Making something ``private`` + all observers external to the blockchain. Making something ``private`` only prevents other contracts from accessing and modifying the information, but it will still be visible to the whole world outside of the blockchain. @@ -173,7 +173,7 @@ return parameter list for functions. :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { function f(uint a) private pure returns (uint b) { return a + 1; } @@ -187,7 +187,7 @@ In the following example, ``D``, can call ``c.getData()`` to retrieve the value :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { uint private data; @@ -231,7 +231,7 @@ when they are declared. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { uint public data = 42; @@ -246,12 +246,12 @@ when they are declared. The getter functions have external visibility. If the symbol is accessed internally (i.e. without ``this.``), -it is evaluated as a state variable. If it is accessed externally -(i.e. with ``this.``), it is evaluated as a function. +it evaluates to a state variable. If it is accessed externally +(i.e. with ``this.``), it evaluates to a function. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { uint public data; @@ -261,7 +261,7 @@ it is evaluated as a state variable. If it is accessed externally } } -If you have a `public` state variable of array type, then you can only retrieve +If you have a ``public`` state variable of array type, then you can only retrieve single elements of the array via the generated getter function. This mechanism exists to avoid high gas costs when returning an entire array. You can use arguments to specify which individual element to return, for example @@ -270,7 +270,8 @@ to write a function, for example: :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; + contract arrayExample { // public state variable uint[] public myArray; @@ -295,7 +296,7 @@ The next example is more complex: :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract Complex { struct Data { @@ -330,7 +331,7 @@ inheritable properties of contracts and may be overridden by derived contracts. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract owned { constructor() public { owner = msg.sender; } @@ -438,7 +439,7 @@ State variables can be declared as ``constant``. In this case, they have to be assigned from an expression which is a constant at compile time. Any expression that accesses storage, blockchain data (e.g. ``now``, ``address(this).balance`` or ``block.number``) or -execution data (``msg.value`` or ``gasleft()``) or make calls to external contracts are disallowed. Expressions +execution data (``msg.value`` or ``gasleft()``) or makes calls to external contracts is disallowed. Expressions that might have a side-effect on memory allocation are allowed, but those that might have a side-effect on other memory objects are not. The built-in functions ``keccak256``, ``sha256``, ``ripemd160``, ``ecrecover``, ``addmod`` and ``mulmod`` @@ -456,7 +457,7 @@ value types and strings. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { uint constant x = 32**22 + 8; @@ -483,7 +484,8 @@ Functions can be declared ``view`` in which case they promise not to modify the .. note:: If the compiler's EVM target is Byzantium or newer (default) the opcode - ``STATICCALL`` is used. + ``STATICCALL`` is used for ``view`` functions which enforces the state + to stay unmodified as part of the EVM execution. The following statements are considered modifying the state: @@ -498,7 +500,7 @@ The following statements are considered modifying the state: :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract C { function f(uint a, uint b) public view returns (uint) { @@ -510,7 +512,7 @@ The following statements are considered modifying the state: ``constant`` on functions used to be an alias to ``view``, but this was dropped in version 0.5.0. .. note:: - Getter methods are marked ``view``. + Getter methods are automatically marked ``view``. .. note:: Prior to version 0.5.0, the compiler did not use the ``STATICCALL`` opcode @@ -530,7 +532,8 @@ 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. + 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: @@ -542,7 +545,7 @@ In addition to the list of state modifying statements explained above, the follo :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract C { function f(uint a, uint b) public pure returns (uint) { @@ -562,7 +565,6 @@ In addition to the list of state modifying statements explained above, the follo 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). - It is a non-circumventable runtime checks done by the EVM. .. warning:: Before version 0.4.17 the compiler did not enforce that ``pure`` is not reading the state. @@ -571,8 +573,8 @@ In addition to the list of state modifying statements explained above, the follo not do state-changing operations, but it cannot check that the contract that will be called at runtime is actually of that type. -.. warning:: - Before version 0.5.0 the compiler did not enforce that ``view`` is not writing the state. +.. note:: + Before version 0.5.0 the compiler did not enforce that ``pure`` is not reading the state. .. index:: ! fallback function, function;fallback @@ -609,6 +611,12 @@ Like any function, the fallback function can execute complex operations as long 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 @@ -625,7 +633,7 @@ Like any function, the fallback function can execute complex operations as long :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract Test { // This function is called for all messages sent to @@ -676,7 +684,7 @@ The following example shows overloading of the function :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract A { function f(uint _in) public pure returns (uint out) { @@ -694,7 +702,7 @@ externally visible functions differ by their Solidity types but not by their ext :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; // This will not compile contract A { @@ -727,7 +735,7 @@ candidate, resolution fails. :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract A { function f(uint8 _in) public pure returns (uint8 out) { @@ -765,9 +773,9 @@ Frontier and Homestead, but this might change with Serenity). Log and event data is not accessible from within contracts (not even from the contract that created them). -SPV proofs for logs are possible, so if an external entity supplies +"Simple payment verification" (SPV) proofs for logs are possible, so if an external entity supplies a contract with such a proof, it can check that the log actually -exists inside the blockchain. But be aware that block headers have to be supplied because +exists inside the blockchain. Be aware that block headers have to be supplied because the contract can only see the last 256 block hashes. Up to three parameters can @@ -787,7 +795,7 @@ All non-indexed arguments will be :ref:`ABI-encoded <ABI>` into the data part of :: - pragma solidity ^0.4.21; + pragma solidity >=0.4.21 <0.6.0; contract ClientReceipt { event Deposit( @@ -844,7 +852,7 @@ as topics. The event call above can be performed in the same way as :: - pragma solidity ^0.4.10; + pragma solidity >=0.4.10 <0.6.0; contract C { function f() public payable { @@ -892,7 +900,7 @@ Details are given in the following example. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract owned { constructor() public { owner = msg.sender; } @@ -964,7 +972,7 @@ Note that above, we call ``mortal.kill()`` to "forward" the destruction request. The way this is done is problematic, as seen in the following example:: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract owned { constructor() public { owner = msg.sender; } @@ -993,7 +1001,7 @@ derived override, but this function will bypass ``Base1.kill``, basically because it does not even know about ``Base1``. The way around this is to use ``super``:: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract owned { constructor() public { owner = msg.sender; } @@ -1043,10 +1051,8 @@ initialisation code. Before the constructor code is executed, state variables are initialised to their specified value if you initialise them inline, or zero if you do not. -After the final code of the contract is returned. The final deployment of -the code costs additional gas linear to the length of the code. If you did not -supply enough gas to initiate the state variables declared in the constructor, -then an "out of gas" exception is generated. +After the constructor has run, the final code of the contract is returned. The deployment of +the code costs additional gas linear to the length of the code. Constructor functions can be either ``public`` or ``internal``. If there is no constructor, the contract will assume the default constructor, which is @@ -1054,7 +1060,7 @@ equivalent to ``constructor() public {}``. For example: :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract A { uint public a; @@ -1071,7 +1077,8 @@ equivalent to ``constructor() public {}``. For example: A constructor set as ``internal`` causes the contract to be marked as :ref:`abstract <abstract-contract>`. .. warning :: - Prior to version 0.4.22, constructors were defined as functions with the same name as the contract. This syntax was deprecated and is not allowed anymore in version 0.5.0. + Prior to version 0.4.22, constructors were defined as functions with the same name as the contract. + This syntax was deprecated and is not allowed anymore in version 0.5.0. .. index:: ! base;constructor @@ -1083,7 +1090,7 @@ The constructors of all the base contracts will be called following the linearization rules explained below. If the base constructors have arguments, derived contracts need to specify all of them. This can be done in two ways:: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract Base { uint x; @@ -1101,7 +1108,7 @@ derived contracts need to specify all of them. This can be done in two ways:: } One way is directly in the inheritance list (``is Base(7)``). The other is in -the way a modifier would be invoked as part of the header of +the way a modifier is invoked as part of the derived constructor (``Base(_y * _y)``). The first way to do it is more convenient if the constructor argument is a constant and defines the behaviour of the contract or @@ -1111,7 +1118,7 @@ derived contract. Arguments have to be given either in the inheritance list or in modifier-style in the derived constructor. Specifying arguments in both places is an error. -If a derived contract doesn't specify the arguments to all of its base +If a derived contract does not specify the arguments to all of its base contracts' constructors, it will be abstract. .. index:: ! inheritance;multiple, ! linearization, ! C3 linearization @@ -1124,7 +1131,7 @@ Multiple Inheritance and Linearization Languages that allow multiple inheritance have to deal with several problems. One is the `Diamond Problem <https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem>`_. Solidity is similar to Python in that it uses "`C3 Linearization <https://en.wikipedia.org/wiki/C3_linearization>`_" -to force a specific order in the DAG of base classes. This +to force a specific order in the directed acyclic graph of base classes. This results in the desirable property of monotonicity but disallows some inheritance graphs. Especially, the order in which the base classes are given in the ``is`` directive is @@ -1142,7 +1149,7 @@ error "Linearization of inheritance graph impossible". :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract X {} contract A is X {} @@ -1173,7 +1180,7 @@ Abstract Contracts Contracts are marked as abstract when at least one of their functions lacks an implementation as in the following example (note that the function declaration header is terminated by ``;``):: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract Feline { function utterance() public returns (bytes32); @@ -1181,7 +1188,7 @@ Contracts are marked as abstract when at least one of their functions lacks an i Such contracts cannot be compiled (even if they contain implemented functions alongside non-implemented functions), but they can be used as base contracts:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract Feline { function utterance() public returns (bytes32); @@ -1218,36 +1225,40 @@ Interfaces Interfaces are similar to abstract contracts, but they cannot have any functions implemented. There are further restrictions: -- Cannot inherit other contracts or interfaces. +- They cannot inherit other contracts or interfaces. - All declared functions must be external. -- Cannot define constructor. -- Cannot define variables. -- Cannot define structs. +- They cannot declare a constructor. +- They cannot declare state variables. Some of these restrictions might be lifted in the future. Interfaces are basically limited to what the Contract ABI can represent, and the conversion between the ABI and -an Interface should be possible without any information loss. +an interface should be possible without any information loss. Interfaces are denoted by their own keyword: :: - pragma solidity ^0.4.11; + pragma solidity >=0.4.11 <0.6.0; interface Token { + enum TokenType { Fungible, NonFungible } + struct Coin { string obverse; string reverse; } function transfer(address recipient, uint amount) external; } Contracts can inherit interfaces as they would inherit other contracts. +Types defined inside interfaces and other contract-like structures +can be accessed from other contracts: ``Token.TokenType`` or ``Token.Coin``. + .. index:: ! library, callcode, delegatecall .. _libraries: -************ +********* Libraries -************ +********* Libraries are similar to contracts, but their purpose is that they are deployed only once at a specific address and their code is reused using the ``DELEGATECALL`` @@ -1261,7 +1272,14 @@ would have no way to name them, otherwise). Library functions can only be called directly (i.e. without the use of ``DELEGATECALL``) if they do not modify the state (i.e. if they are ``view`` or ``pure`` functions), because libraries are assumed to be stateless. In particular, it is -not possible to destroy a library unless Solidity's type system is circumvented. +not possible to destroy a library. + +.. note:: + Until version 0.4.20, it was possible to destroy libraries by + circumventing Solidity's type system. Starting from that version, + libraries contain a :ref:`mechanism<call-protection>` that + disallows state-modifying functions + to be called directly (i.e. without ``DELEGATECALL``). Libraries can be seen as implicit base contracts of the contracts that use them. They will not be explicitly visible in the inheritance hierarchy, but calls @@ -1277,13 +1295,13 @@ contract, and a regular ``JUMP`` call will be used instead of a ``DELEGATECALL`` .. index:: using for, set -The following example illustrates how to use libraries (but +The following example illustrates how to use libraries (butmanual method be sure to check out :ref:`using for <using-for>` for a more advanced example to implement a set). :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; library Set { // We define a new struct datatype that will be used to @@ -1345,7 +1363,7 @@ parameters and in any position. The calls to ``Set.contains``, ``Set.insert`` and ``Set.remove`` are all compiled as calls (``DELEGATECALL``) to an external -contract/library. If you use libraries, take care that an +contract/library. If you use libraries, be aware that an actual external function call is performed. ``msg.sender``, ``msg.value`` and ``this`` will retain their values in this call, though (prior to Homestead, because of the use of ``CALLCODE``, ``msg.sender`` and @@ -1357,7 +1375,7 @@ custom types without the overhead of external function calls: :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; library BigInt { struct bigint { @@ -1423,6 +1441,14 @@ will contain placeholders of the form ``__Set______`` (where manually by replacing all those 40 symbols by the hex encoding of the address of the library contract. +.. note:: + Manually linking libraries on the generated bytecode is discouraged, because + it is restricted to 36 characters. + You should ask the compiler to link the libraries at the time + a contract is compiled by either using + the ``--libraries`` option of ``solc`` or the ``libraries`` key if you use + the standard-JSON interface to the compiler. + Restrictions for libraries in comparison to contracts: - No state variables @@ -1431,6 +1457,8 @@ Restrictions for libraries in comparison to contracts: (These might be lifted at a later point.) +.. _call-protection: + Call Protection For Libraries ============================= @@ -1488,7 +1516,7 @@ available without having to add further code. Let us rewrite the set example from the :ref:`libraries` in this way:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; // This is the same code as before, just without comments library Set { @@ -1538,7 +1566,7 @@ Let us rewrite the set example from the It is also possible to extend elementary types in that way:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; library Search { function indexOf(uint[] storage self, uint value) 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/control-structures.rst b/docs/control-structures.rst index 745a0599..80311a63 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -14,13 +14,13 @@ parameters as output. Input Parameters ---------------- -The input parameters are declared the same way as variables are. As an -exception, unused parameters can omit the variable name. +The input parameters are declared the same way as variables are. +The name of unused parameters can be omitted. For example, suppose we want our contract to accept one kind of external calls with two integers, we would write something like:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract Simple { uint sum; @@ -29,6 +29,9 @@ something like:: } } +Input parameters can be used just as any other local variable +can be used, they can also be assigned to. + Output Parameters ----------------- @@ -37,7 +40,7 @@ The output parameters can be declared with the same syntax after the the sum and the product of the two given integers, then we would write:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract Simple { function arithmetic(uint _a, uint _b) @@ -51,24 +54,20 @@ write:: } The names of output parameters can be omitted. -The output values can also be specified using ``return`` statements. -The ``return`` statements are also capable of returning multiple -values, see :ref:`multi-return`. -Return parameters are initialized to zero; if they are not explicitly -set, they stay to be zero. - -Input parameters and output parameters can be used as expressions in -the function body. There, they are also usable in the left-hand side -of assignment. +The output values can also be specified using ``return`` statements, +which are also capable of :ref:`returning multiple values<multi-return>`. +Return parameters can be used as any other local variable and they +are zero-initialized; if they are not explicitly +set, they stay zero. .. index:: if, else, while, do/while, for, break, continue, return, switch, goto Control Structures =================== -Most of the control structures from JavaScript are available in Solidity -except for ``switch`` and ``goto``. So -there is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, ``? :``, with +Most of the control structures known from curly-braces languages are available in Solidity: + +There is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, with the usual semantics known from C or JavaScript. Parentheses can *not* be omitted for conditionals, but curly brances can be omitted @@ -100,7 +99,7 @@ Internal Function Calls Functions of the current contract can be called directly ("internally"), also recursively, as seen in this nonsensical example:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { function g(uint a) public pure returns (uint ret) { return a + f(); } @@ -112,6 +111,9 @@ the effect that the current memory is not cleared, i.e. passing memory reference to internally-called functions is very efficient. Only functions of the same contract can be called internally. +You should still avoid excessive recursion, as every internal function call +uses up at least one stack slot and there are at most 1024 slots available. + External Function Calls ----------------------- @@ -127,7 +129,7 @@ all function arguments have to be copied to memory. When calling functions of other contracts, the amount of Wei sent with the call and the gas can be specified with special options ``.value()`` and ``.gas()``, respectively:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract InfoFeed { function info() public payable returns (uint ret) { return 42; } @@ -143,7 +145,7 @@ You need to use the modifier ``payable`` with the ``info`` function because otherwise, the ``.value()`` option would not be available. .. warning:: - Be careful that ``feed.info.value(10).gas(800)`` only locally sets the ``value`` and amount of ``gas`` sent with the function call, and the parentheses at the end perform the actual call. + Be careful that ``feed.info.value(10).gas(800)`` only locally sets the ``value`` and amount of ``gas`` sent with the function call, and the parentheses at the end perform the actual call. So in this case, the function is not called. Function calls cause exceptions if the called contract does not exist (in the sense that the account does not contain code) or if the called contract itself @@ -167,14 +169,14 @@ throws an exception or goes out of gas. Named Calls and Anonymous Function Parameters --------------------------------------------- -Function call arguments can also be given by name, in any order, +Function call arguments can be given by name, in any order, if they are enclosed in ``{ }`` as can be seen in the following example. The argument list has to coincide by name with the list of parameters from the function declaration, but can be in arbitrary order. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { mapping(uint => uint) data; @@ -197,7 +199,7 @@ Those parameters will still be present on the stack, but they are inaccessible. :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { // omitted name for parameter @@ -214,13 +216,13 @@ Those parameters will still be present on the stack, but they are inaccessible. Creating Contracts via ``new`` ============================== -A contract can create a new contract using the ``new`` keyword. The full -code of the contract being created has to be known in advance, so recursive -creation-dependencies are not possible. +A contract can create other contracts using the ``new`` keyword. The full +code of the contract being created has to be known when the creating contract +is compiled so recursive creation-dependencies are not possible. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract D { uint public x; @@ -244,7 +246,7 @@ creation-dependencies are not possible. } } -As seen in the example, it is possible to forward Ether while creating +As seen in the example, it is possible to send Ether while creating an instance of ``D`` using the ``.value()`` option, but it is not possible to limit the amount of gas. If the creation fails (due to out-of-stack, not enough balance or other problems), @@ -269,8 +271,11 @@ Assignment Destructuring Assignments and Returning Multiple Values ------------------------------------------------------- -Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose size is a constant at compile-time. Those tuples can be used to return multiple values at the same time. -These can then either be assigned to newly declared variables or to pre-existing variables (or LValues in general): +Solidity internally allows tuple types, i.e. a list of objects of potentially different types whose number is a constant at compile-time. Those tuples can be used to return multiple values at the same time. +These can then either be assigned to newly declared variables or to pre-existing variables (or LValues in general). + +Tuples are not proper types in Solidity, they can only be used to form syntactic +groupings of expressions. :: @@ -294,15 +299,23 @@ These can then either be assigned to newly declared variables or to pre-existing } } +It is not possible to mix variable declarations and non-declaration assignments, +i.e. the following is not valid: ``(x, uint y) = (1, 2);`` + .. note:: Prior to version 0.5.0 it was possible to assign to tuples of smaller size, either filling up on the left or on the right side (which ever was empty). This is now disallowed, so both sides have to have the same number of components. +.. warning:: + Be careful when assigning to multiple variables at the same time when + reference types are involved, because it could lead to unexpected + copying behaviour. + Complications for Arrays and Structs ------------------------------------ -The semantics of assignment are a bit more complicated for non-value types like arrays and structs. +The semantics of assignments are a bit more complicated for non-value types like arrays and structs. Assigning *to* a state variable always creates an independent copy. On the other hand, assigning to a local variable creates an independent copy only for elementary types, i.e. static types that fit into 32 bytes. If structs or arrays (including ``bytes`` and ``string``) are assigned from a state variable to a local variable, the local variable holds a reference to the original state variable. A second assignment to the local variable does not modify the state but only changes the reference. Assignments to members (or elements) of the local variable *do* change the state. .. index:: ! scoping, declarations, default value @@ -320,11 +333,11 @@ and ``string``, the default value is an empty array or string. Scoping in Solidity follows the widespread scoping rules of C99 (and many other languages): Variables are visible from the point right after their declaration -until the end of a ``{ }``-block. As an exception to this rule, variables declared in the +until the end of the smallest ``{ }``-block that contains the declaration. As an exception to this rule, variables declared in the initialization part of a for-loop are only visible until the end of the for-loop. Variables and other items declared outside of a code block, for example functions, contracts, -user-defined types, etc., do not change their scoping behaviour. This means you can +user-defined types, etc., are visible even before they were declared. This means you can use state variables before they are declared and call functions recursively. As a consequence, the following examples will compile without warnings, since @@ -332,7 +345,7 @@ the two variables have the same name but disjoint scopes. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract C { function minimalScoping() pure public { { @@ -353,7 +366,7 @@ In any case, you will get a warning about the outer variable being shadowed. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; // This will report a warning contract C { function f() pure public returns (uint) { @@ -368,12 +381,12 @@ In any case, you will get a warning about the outer variable being shadowed. .. warning:: Before version 0.5.0 Solidity followed the same scoping rules as JavaScript, that is, a variable declared anywhere within a function would be in scope - for the entire function, regardless where it was declared. Note that this is a breaking change. The following example shows a code snippet that used + for the entire function, regardless where it was declared. The following example shows a code snippet that used to compile but leads to an error starting from version 0.5.0. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; // This will not compile contract C { function f() pure public returns (uint) { @@ -385,6 +398,8 @@ In any case, you will get a warning about the outer variable being shadowed. .. index:: ! exception, ! throw, ! assert, ! require, ! revert +.. _assert-and-require: + Error handling: Assert, Require, Revert and Exceptions ====================================================== @@ -398,17 +413,17 @@ If used properly, analysis tools can evaluate your contract to identify the cond There are two other ways to trigger exceptions: The ``revert`` function can be used to flag an error and revert the current call. It is possible to provide a string message containing details about the error that will be passed back to the caller. -The deprecated keyword ``throw`` can also be used as an alternative to ``revert()`` (but only without error message). .. note:: - From version 0.4.13 the ``throw`` keyword is deprecated and will be phased out in the future. + There used to be a keyword called ``throw`` with the same semantics as ``revert()`` which + whas deprecated in version 0.4.13 and removed in version 0.5.0. When exceptions happen in a sub-call, they "bubble up" (i.e. exceptions are rethrown) automatically. Exceptions to this rule are ``send`` -and the low-level functions ``call``, ``delegatecall``, ``callcode`` and ``staticcall`` -- those return ``false`` in case +and the low-level functions ``call``, ``delegatecall`` and ``staticcall`` -- those return ``false`` as their first return value in case of an exception instead of "bubbling up". .. warning:: - The low-level ``call``, ``delegatecall``, ``callcode`` and ``staticcall`` will return success if the called account is non-existent, as part of the design of EVM. Existence must be checked prior to calling if desired. + The low-level functions ``call``, ``delegatecall`` and ``staticcall`` return ``true`` as their first return value if the called account is non-existent, as part of the design of EVM. Existence must be checked prior to calling if desired. Catching exceptions is not yet possible. @@ -418,7 +433,7 @@ a message string for ``require``, but not for ``assert``. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract Sharer { function sendHalf(address payable addr) public payable returns (uint balance) { @@ -445,7 +460,6 @@ An ``assert``-style exception is generated in the following situations: A ``require``-style exception is generated in the following situations: -#. Calling ``throw``. #. Calling ``require`` with an argument that evaluates to ``false``. #. If you call a function via a message call but it does not finish properly (i.e. it runs out of gas, has no matching function, or throws an exception itself), except when a low level operation ``call``, ``send``, ``delegatecall``, ``callcode`` or ``staticcall`` is used. The low level operations never throw exceptions but indicate failures by returning ``false``. #. If you create a contract using the ``new`` keyword but the contract creation does not finish properly (see above for the definition of "not finish properly"). @@ -465,7 +479,7 @@ The following example shows how an error string can be used together with revert :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract VendingMachine { function buy(uint amount) public payable { diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index d2b7de9c..7b7dd0b0 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -57,7 +57,7 @@ array in the return statement. Pretty cool, huh? Example:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { function f() public pure returns (uint8[5] memory) { @@ -87,7 +87,7 @@ should be noted that you must declare them as static memory arrays. Examples:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { struct S { @@ -127,7 +127,7 @@ which will be extended in the future. In addition, Arachnid has written `solidit For now, if you want to modify a string (even when you only want to know its length), you should always convert it to a ``bytes`` first:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { string s; @@ -282,7 +282,7 @@ In the case of a ``contract A`` calling a new instance of ``contract B``, parent You will need to make sure that you have both contracts aware of each other's presence and that ``contract B`` has a ``payable`` constructor. In this example:: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract B { constructor() public payable {} @@ -330,7 +330,7 @@ Can a contract pass an array (static size) or string or ``bytes`` (dynamic size) Sure. Take care that if you cross the memory / storage boundary, independent copies will be created:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { uint[20] x; @@ -367,7 +367,7 @@ contract level) with ``arrayname.length = <some new length>;``. If you get the :: - pragma solidity ^0.4.18; + pragma solidity >=0.4.18 <0.6.0; // This will not compile contract C { 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 5ba7ed12..2d4777e8 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -16,7 +16,7 @@ Storage :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract SimpleStorage { uint storedData; @@ -80,7 +80,7 @@ registering with username and password — all you need is an Ethereum keypair. :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; contract Coin { // The keyword "public" makes those variables diff --git a/docs/layout-of-source-files.rst b/docs/layout-of-source-files.rst index 11f85aac..d89ecded 100644 --- a/docs/layout-of-source-files.rst +++ b/docs/layout-of-source-files.rst @@ -13,6 +13,12 @@ and :ref:`pragma directives<pragma>`. Pragmas ======= +The ``pragma`` keyword can be used to enable certain compiler features +or checks. A pragma directive is always local to a source file, so +you have to add the pragma to all your files if you want enable it +in all of your project. If you :ref:`import<import>` another file, the pragma +from that file will not automatically apply to the importing file. + .. index:: ! pragma, version .. _version_pragma: @@ -43,6 +49,13 @@ the exact version of the compiler, so that bugfix releases are still possible. It is possible to specify much more complex rules for the compiler version, the expression follows those used by `npm <https://docs.npmjs.com/misc/semver>`_. +.. note:: + Using the version pragma will *not* change the version of the compiler. + It will also *not* enable or disable features of the compiler. It will just + instruct the compiler to check whether its version matches the one + required by the pragma. If it does not match, the compiler will issue + an error. + .. index:: ! pragma, experimental .. _experimental_pragma: @@ -261,7 +274,7 @@ for the two input parameters and two returned values. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; /** @title Shape calculator. */ contract ShapeCalculator { diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index d96ff166..12603f2e 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -48,7 +48,7 @@ non-elementary type, the positions are found by adding an offset of ``keccak256( So for the following contract snippet:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { struct s { uint a; uint b; } @@ -64,20 +64,20 @@ The position of ``data[4][9].b`` is at ``keccak256(uint256(9) . keccak256(uint25 Layout in Memory **************** -Solidity reserves four 32 byte slots: +Solidity reserves four 32-byte slots, with specific byte ranges (inclusive of endpoints) being used as follows: -- ``0x00`` - ``0x3f``: scratch space for hashing methods -- ``0x40`` - ``0x5f``: currently allocated memory size (aka. free memory pointer) -- ``0x60`` - ``0x7f``: zero slot +- ``0x00`` - ``0x3f`` (64 bytes): scratch space for hashing methods +- ``0x40`` - ``0x5f`` (32 bytes): currently allocated memory size (aka. free memory pointer) +- ``0x60`` - ``0x7f`` (32 bytes): zero slot -Scratch space can be used between statements (ie. within inline assembly). The zero slot +Scratch space can be used between statements (i.e. within inline assembly). The zero slot is used as initial value for dynamic memory arrays and should never be written to (the free memory pointer points to ``0x80`` initially). Solidity always places new objects at the free memory pointer and memory is never freed (this might change in the future). .. warning:: - There are some operations in Solidity that need a temporary memory area larger than 64 bytes and therefore will not fit into the scratch space. They will be placed where the free memory points to, but given their short lifecycle, the pointer is not updated. The memory may or may not be zeroed out. Because of this, one shouldn't expect the free memory to be zeroed out. + There are some operations in Solidity that need a temporary memory area larger than 64 bytes and therefore will not fit into the scratch space. They will be placed where the free memory points to, but given their short lifetime, the pointer is not updated. The memory may or may not be zeroed out. Because of this, one shouldn't expect the free memory to point to zeroed out memory. While it may seem like a good idea to use ``msize`` to arrive at a definitely zeroed out memory area, using such a pointer non-temporarily without updating the free memory pointer can have adverse results. @@ -242,7 +242,6 @@ Tips and Tricks * Use shorter types for struct elements and sort them such that short types are grouped together. This can lower the gas costs as multiple ``SSTORE`` operations might be combined into a single (``SSTORE`` costs 5000 or 20000 gas, so this is what you want to optimise). Use the gas price estimator (with optimiser enabled) to check! * Make your state variables public - the compiler will create :ref:`getters <visibility-and-getters>` for you automatically. * If you end up checking conditions on input or state a lot at the beginning of your functions, try using :ref:`modifiers`. -* If your contract has a function called ``send`` but you want to use the built-in send-function, use ``address(contractVariable).send(amount)``. * Initialize storage structs with a single assignment: ``x = MyStruct({a: 1, b: 2});`` .. note:: @@ -278,7 +277,7 @@ The following is the order of precedence for operators, listed in order of evalu +------------+-------------------------------------+--------------------------------------------+ | *2* | Prefix increment and decrement | ``++``, ``--`` | + +-------------------------------------+--------------------------------------------+ -| | Unary plus and minus | ``+``, ``-`` | +| | Unary minus | ``-`` | + +-------------------------------------+--------------------------------------------+ | | Unary operations | ``delete`` | + +-------------------------------------+--------------------------------------------+ @@ -322,13 +321,12 @@ The following is the order of precedence for operators, listed in order of evalu Global Variables ================ -- ``abi.decode(bytes encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes the provided data. The types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` -- ``abi.encode(...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments -- ``abi.encodePacked(...) returns (bytes)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments -- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: :ref:`ABI <ABI>`-encodes the given arguments +- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: :ref:`ABI <ABI>`-decodes the provided data. The types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` +- ``abi.encode(...) returns (bytes memory)``: :ref:`ABI <ABI>`-encodes the given arguments +- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments +- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: :ref:`ABI <ABI>`-encodes the given arguments starting from the second and prepends the given four-byte selector -- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)``` -- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``. +- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature)), ...)``` - ``block.coinbase`` (``address payable``): current block miner's address - ``block.difficulty`` (``uint``): current block difficulty - ``block.gaslimit`` (``uint``): current block gaslimit @@ -336,7 +334,6 @@ Global Variables - ``block.timestamp`` (``uint``): current block timestamp - ``gasleft() returns (uint256)``: remaining gas - ``msg.data`` (``bytes``): complete calldata -- ``msg.gas`` (``uint``): remaining gas - deprecated in version 0.4.21 and to be replaced by ``gasleft()`` - ``msg.sender`` (``address payable``): sender of the message (current call) - ``msg.value`` (``uint``): number of wei sent with the message - ``now`` (``uint``): current block timestamp (alias for ``block.timestamp``) @@ -344,21 +341,19 @@ Global Variables - ``tx.origin`` (``address payable``): sender of the transaction (full call chain) - ``assert(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for internal error) - ``require(bool condition)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component) -- ``require(bool condition, string message)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component). Also provide error message. +- ``require(bool condition, string memory message)``: abort execution and revert state changes if condition is ``false`` (use for malformed input or error in external component). Also provide error message. - ``revert()``: abort execution and revert state changes -- ``revert(string message)``: abort execution and revert state changes providing an explanatory string +- ``revert(string memory message)``: abort execution and revert state changes providing an explanatory string - ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent blocks -- ``keccak256(bytes memory) returns (bytes32)``: compute the Ethereum-SHA-3 (Keccak-256) hash of the input -- ``sha3(bytes memory) returns (bytes32)``: an alias to ``keccak256`` +- ``keccak256(bytes memory) returns (bytes32)``: compute the Keccak-256 hash of the input - ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input - ``ripemd160(bytes memory) returns (bytes20)``: compute the RIPEMD-160 hash of the input - ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: recover address associated with the public key from elliptic curve signature, return zero on error - ``addmod(uint x, uint y, uint k) returns (uint)``: compute ``(x + y) % k`` where the addition is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. - ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. -- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` +- ``this`` (current contract's type): the current contract, explicitly convertible to ``address`` or ``address payable`` - ``super``: the contract one level higher in the inheritance hierarchy -- ``selfdestruct(address recipient)``: destroy the current contract, sending its funds to the given address -- ``suicide(address recipient)``: a deprecated alias to ``selfdestruct`` +- ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given address - ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei - ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`, returns ``false`` on failure - ``<address payable>.transfer(uint256 amount)``: send given amount of Wei to :ref:`address`, throws on failure @@ -380,6 +375,11 @@ Global Variables You can only access the hashes of the most recent 256 blocks, all other values will be zero. +.. note:: + In version 0.5.0, the following aliases were removed: ``suicide`` as alias for ``selfdestruct``, + ``msg.gas`` as alias for ``gasleft``, ``block.blockhash`` as alias for ``blockhash`` and + ``sha3`` as alias for ``keccak256``. + .. index:: visibility, public, private, external, internal Function Visibility Specifiers diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 8df12b7c..3305c1e1 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -55,7 +55,7 @@ complete contract): :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; // THIS CONTRACT CONTAINS A BUG - DO NOT USE contract Fund { @@ -78,7 +78,7 @@ as it uses ``call`` which forwards all remaining gas by default: :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; // THIS CONTRACT CONTAINS A BUG - DO NOT USE contract Fund { @@ -97,7 +97,7 @@ outlined further below: :: - pragma solidity ^0.4.11; + pragma solidity >=0.4.11 <0.6.0; contract Fund { /// Mapping of ether shares of the contract. @@ -182,7 +182,7 @@ Never use tx.origin for authorization. Let's say you have a wallet contract like :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; // THIS CONTRACT CONTAINS A BUG - DO NOT USE contract TxUserWallet { @@ -202,7 +202,7 @@ Now someone tricks you into sending ether to the address of this attack wallet: :: - pragma solidity >0.4.24; + pragma solidity >0.4.99 <0.6.0; interface TxUserWallet { function transferTo(address payable dest, uint amount) external; diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index d01886f8..0f9a71ab 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -36,7 +36,7 @@ of votes. :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; /// @title Voting with delegation. contract Ballot { @@ -225,7 +225,7 @@ activate themselves. :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract SimpleAuction { // Parameters of the auction. Times are either @@ -542,7 +542,7 @@ Safe Remote Purchase :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract Purchase { uint public value; @@ -793,7 +793,7 @@ The full contract :: - pragma solidity ^0.4.24; + pragma solidity >=0.4.24 <0.6.0; contract ReceiverPays { address owner = msg.sender; @@ -988,7 +988,7 @@ The full contract :: - pragma solidity ^0.4.24; + pragma solidity >=0.4.24 <0.6.0; contract SimplePaymentChannel { address payable public sender; // The account sending payments. diff --git a/docs/structure-of-a-contract.rst b/docs/structure-of-a-contract.rst index d8bc51b8..582e5338 100644 --- a/docs/structure-of-a-contract.rst +++ b/docs/structure-of-a-contract.rst @@ -26,7 +26,7 @@ storage. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract SimpleStorage { uint storedData; // State variable @@ -46,7 +46,7 @@ Functions are the executable units of code within a contract. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract SimpleAuction { function bid() public payable { // Function @@ -68,7 +68,7 @@ Function modifiers can be used to amend the semantics of functions in a declarat :: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract Purchase { address public seller; @@ -95,7 +95,7 @@ Events are convenience interfaces with the EVM logging facilities. :: - pragma solidity ^0.4.21; + pragma solidity >=0.4.21 <0.6.0; contract SimpleAuction { event HighestBidIncreased(address bidder, uint amount); // Event @@ -119,7 +119,7 @@ Structs are custom defined types that can group several variables (see :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract Ballot { struct Voter { // Struct @@ -140,7 +140,7 @@ Enums can be used to create custom types with a finite set of 'constant values' :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract Purchase { enum State { Created, Locked, Inactive } // Enum diff --git a/docs/style-guide.rst b/docs/style-guide.rst index b97beebd..7b48ccad 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -52,7 +52,7 @@ Surround top level declarations in solidity source with two blank lines. Yes:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract A { // ... @@ -70,7 +70,7 @@ Yes:: No:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract A { // ... @@ -89,7 +89,7 @@ Blank lines may be omitted between groups of related one-liners (such as stub fu Yes:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract A { function spam() public pure; @@ -109,7 +109,7 @@ Yes:: No:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract A { function spam() public pure { @@ -237,7 +237,7 @@ Import statements should always be placed at the top of the file. Yes:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; import "./Owned.sol"; @@ -251,7 +251,7 @@ Yes:: No:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract A { // ... @@ -283,7 +283,7 @@ Within a grouping, place the ``view`` and ``pure`` functions last. Yes:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract A { constructor() public { @@ -315,7 +315,7 @@ Yes:: No:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract A { @@ -411,7 +411,7 @@ should: Yes:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract Coin { struct Bank { @@ -422,7 +422,7 @@ Yes:: No:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract Coin { @@ -723,7 +723,7 @@ manner as modifiers if the function declaration is long or hard to read. Yes:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; // Base contracts just to make this compile contract B { @@ -755,7 +755,7 @@ Yes:: No:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; // Base contracts just to make this compile contract B { @@ -955,7 +955,7 @@ As shown in the example below, if the contract name is `Congress` and the librar Yes:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; // Owned.sol contract Owned { @@ -984,7 +984,7 @@ Yes:: No:: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; // owned.sol contract owned { diff --git a/docs/types.rst b/docs/types.rst index 1cbbb1be..f9fc80ce 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -276,15 +276,19 @@ Contract Types -------------- Every :ref:`contract<contracts>` defines its own type. -You can implicitly convert contracts to contracts they inherit from, -and explicitly convert them to and from the ``address`` type, if they have no -payable fallback functions, or to and from the ``address payable`` type, if they do -have payable fallback functions. +You can implicitly convert contracts to contracts they inherit from. +Contracts can be explicitly converted to and from all other contract types +and the ``address`` type. + +Explicit conversion to and from the ``address payable`` type +is only possible if the contract type has a payable fallback function. +The conversion is still performed using ``address(x)`` and not +using ``address payable(x)``. You can find more information in the section about +the :ref:`address type<address>`. .. note:: - Starting with version 0.5.0 contracts do not derive from the address type, - but can still be explicitly converted to ``address``, resp. to ``address payable``, - if they have a payable fallback function. + Before version 0.5.0, contracts directly derived from the address type + and there was no distinction between ``address`` and ``address payable``. If you declare a local variable of contract type (`MyContract c`), you can call functions on that contract. Take care to assign it from somewhere that is the @@ -307,25 +311,29 @@ including public state variables. Fixed-size byte arrays ---------------------- -``bytes1``, ``bytes2``, ``bytes3``, ..., ``bytes32``. ``byte`` is an alias for ``bytes1``. +The value types ``bytes1``, ``bytes2``, ``bytes3``, ..., ``bytes32`` +hold a sequence of bytes from one to up to 32. +``byte`` is an alias for ``bytes1``. Operators: * Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``) -* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation), ``<<`` (left shift), ``>>`` (right shift) +* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation) +* Shift operators: ``<<`` (left shift), ``>>`` (right shift) * Index access: If ``x`` is of type ``bytesI``, then ``x[k]`` for ``0 <= k < I`` returns the ``k`` th byte (read-only). -The shifting operator works with any integer type as right operand (but will -return the type of the left operand), which denotes the number of bits to shift by. -Shifting by a negative amount will cause a runtime exception. +The shifting operator works with any integer type as right operand (but +returns the type of the left operand), which denotes the number of bits to shift by. +Shifting by a negative amount causes a runtime exception. Members: * ``.length`` yields the fixed length of the byte array (read-only). .. note:: - It is possible to use an array of bytes as ``byte[]``, but it is wasting a lot of space, 31 bytes every element, - to be exact, when passing in calls. It is better to use ``bytes``. + The type ``byte[]`` is an array of bytes, but due to padding rules, it wastes + 31 bytes of space for each element (except in storage). It is better to use the ``bytes`` + type instead. Dynamically-sized byte array ---------------------------- @@ -343,7 +351,7 @@ Address Literals ---------------- Hexadecimal literals that pass the address checksum test, for example -``0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF`` are of ``address`` type. +``0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF`` are of ``address payable`` type. Hexadecimal literals that are between 39 and 41 digits long and do not pass the checksum test produce a warning and are treated as regular rational number literals. @@ -371,10 +379,11 @@ Examples include ``2e10``, ``-2e10``, ``2e-10``, ``2.5e1``. Underscores can be used to separate the digits of a numeric literal to aid readability. For example, decimal ``123_000``, hexadecimal ``0x2eff_abde``, scientific decimal notation ``1_2e345_678`` are all valid. Underscores are only allowed between two digits and only one consecutive underscore is allowed. -There is no additional semantic meaning added to a number literal containing underscores. +There is no additional semantic meaning added to a number literal containing underscores, +the underscores are ignored. Number literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by -using them together with a non-literal expression). +using them together with a non-literal expression or by explicit conversion). This means that computations do not overflow and divisions do not truncate in number literal expressions. @@ -396,14 +405,15 @@ a non-rational number). belong to the same number literal type for the rational number three. .. warning:: - Division on integer literals used to truncate in earlier versions, but it will now convert into a rational number, i.e. ``5 / 2`` is not equal to ``2``, but to ``2.5``. + Division on integer literals used to truncate in Solidity prior to version 0.4.0, but it now converts into a rational number, i.e. ``5 / 2`` is not equal to ``2``, but to ``2.5``. .. note:: Number literal expressions are converted into a non-literal type as soon as they are used with non-literal - expressions. Even though we know that the value of the - expression assigned to ``b`` in the following example evaluates to - an integer, but the partial expression ``2.5 + a`` does not type check so the code - does not compile + expressions. Disregarding types, the value of the expression assigned to ``b`` + below evaluates to an integer. Because ``a`` is of type ``uint128``, the + expression ``2.5 + a`` has to have a proper type, though. Since there is no common type + for the type of ``2.5`` and ``uint128``, the Solidity compiler does not accept + this code. :: @@ -415,9 +425,37 @@ a non-rational number). String Literals --------------- -String literals are written with either double or single-quotes (``"foo"`` or ``'bar'``). They do not imply trailing zeroes as in C; ``"foo"`` represents three bytes not four. As with integer literals, their type can vary, but they are implicitly convertible to ``bytes1``, ..., ``bytes32``, if they fit, to ``bytes`` and to ``string``. +String literals are written with either double or single-quotes (``"foo"`` or ``'bar'``). They do not imply trailing zeroes as in C; ``"foo"`` represents three bytes, not four. As with integer literals, their type can vary, but they are implicitly convertible to ``bytes1``, ..., ``bytes32``, if they fit, to ``bytes`` and to ``string``. + +String literals support the following escape characters: + + - ``\<newline>`` (escapes an actual newline) + - ``\\`` (backslash) + - ``\'`` (single quote) + - ``\"`` (double quote) + - ``\b`` (backspace) + - ``\f`` (form feed) + - ``\n`` (newline) + - ``\r`` (carriage return) + - ``\t`` (tab) + - ``\v`` (vertical tab) + - ``\xNN`` (hex escape, see below) + - ``\uNNNN`` (unicode escape, see below) + +``\xNN`` takes a hex value and inserts the appropriate byte, while ``\uNNNN`` takes a Unicode codepoint and inserts an UTF-8 sequence. + +The string in the following example has a length of ten bytes. +It starts with a newline byte, followed by a double quote, a single +quote a backslash character and then (without separator) the +character sequence ``abcdef``. + +:: + + "\n\"\'\\abc\ + def" -String literals support escape characters, such as ``\n``, ``\xNN`` and ``\uNNNN``. ``\xNN`` takes a hex value and inserts the appropriate byte, while ``\uNNNN`` takes a Unicode codepoint and inserts an UTF-8 sequence. +Any unicode line terminator which is not a newline (i.e. LF, VF, FF, CR, NEL, LS, PS) is considered to +terminate the string literal. Newline only terminates the string literal if it is not preceded by a ``\``. .. index:: literal, bytes @@ -436,8 +474,9 @@ Enums ----- Enums are one way to create a user-defined type in Solidity. They are explicitly convertible -to and from all integer types but implicit conversion is not allowed. The explicit conversions -check the value ranges at runtime and a failure causes an exception. Enums needs at least one member. +to and from all integer types but implicit conversion is not allowed. The explicit conversion +from integer checks at runtime that the value lies inside the range of the enum and causes a failing assert otherwise. +Enums needs at least one member. The data representation is the same as for enums in C: The options are represented by subsequent unsigned integer values starting from ``0``. @@ -445,7 +484,7 @@ subsequent unsigned integer values starting from ``0``. :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract test { enum ActionChoices { GoLeft, GoRight, GoStraight, SitStill } @@ -505,6 +544,11 @@ omitted. Note that this only applies to function types. Visibility has to be specified explicitly for functions defined in contracts, they do not have a default. +Conversions: + +A value of external function type can be explicitly converted to ``address`` +resulting in the address of the contract of the function. + A function type ``A`` is implicitly convertible to a function type ``B`` if and only if their parameter types are identical, their return types are identical, their internal/external property is identical and the state mutability of ``A`` @@ -514,7 +558,7 @@ is not more restrictive than the state mutability of ``B``. In particular: - ``view`` functions can be converted to ``non-payable`` functions - ``payable`` functions can be converted to ``non-payable`` functions -No other conversions are possible. +No other conversions between function types are possible. The rule about ``payable`` and ``non-payable`` might be a little confusing, but in essence, if a function is ``payable``, this means that it @@ -534,10 +578,12 @@ 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``. -Additionally, public (or external) functions also have a special member called ``selector``, +Members: + +Public (or external) functions also have a special member called ``selector``, which returns the :ref:`ABI function selector <abi_function_selector>`:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract Selector { function f() public pure returns (bytes4) { @@ -547,7 +593,7 @@ which returns the :ref:`ABI function selector <abi_function_selector>`:: Example that shows how to use internal function types:: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; library ArrayUtils { // internal functions can be used in internal library functions because @@ -598,7 +644,7 @@ Example that shows how to use internal function types:: Another example that uses external function types:: - pragma solidity ^0.4.22; + pragma solidity >=0.4.22 <0.6.0; contract Oracle { struct Request { @@ -638,21 +684,27 @@ Another example that uses external function types:: .. index:: ! type;reference, ! reference type, storage, memory, location, array, struct Reference Types -================== +=============== -Complex types, i.e. types which do not always fit into 256 bits have to be handled -more carefully than the value-types we have already seen. Since copying -them can be quite expensive, we have to think about whether we want them to be -stored in **memory** (which is not persisting) or **storage** (where the state -variables are held). +Values of reference type can be modified through multiple different names. +Contrast this with value types where you get an independent copy whenever +a variable of value type is used. Because of that, reference types have to be handled +more carefully than value types. Currently, reference types comprise structs, +arrays and mappings. If you use a reference type, you always have to explicitly +provide the data area where the type is stored: ``memory`` (whose lifetime is limited +to a function call), ``storage`` (the location where the state variables are stored) +or ``calldata`` (special data location that contains the function arguments, +only available for external function call parameters). + +An assignment or type conversion that changes the data location will always incur an automatic copy operation, +while assignments inside the same data location only copy in some cases for storage types. .. _data-location: Data location ------------- - -Every complex type, i.e. *arrays* and *structs*, has an additional +Every reference type, i.e. *arrays* and *structs*, has an additional annotation, the "data location", about where it is stored. There are three data locations: ``memory``, ``storage`` and ``calldata``. Calldata is only valid for parameters of external contract functions and is required for this type of parameter. Calldata is a non-modifiable, @@ -675,7 +727,7 @@ memory-stored reference type do not create a copy. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract C { uint[] x; // the data location of x is storage @@ -757,7 +809,7 @@ or create a new memory array and copy every element. :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { function f(uint len) public pure { @@ -779,7 +831,7 @@ assigned to a variable right away. :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract C { function f() public pure { @@ -800,7 +852,7 @@ possible: :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; // This will not compile. contract C { @@ -820,13 +872,12 @@ Members ^^^^^^^ **length**: - Arrays have a ``length`` member to hold their number of elements. - Dynamic arrays can be resized in storage (not in memory) by changing the - ``.length`` member. This does not happen automatically when attempting to access elements outside the current length. The size of memory arrays is fixed (but dynamic, i.e. it can depend on runtime parameters) once they are created. + Arrays have a ``length`` member to read their number of elements. + Dynamically-sized arrays (only available for storage) have a read-write ``length`` member to resize the array. Increasing the length adds uninitialized elements to the array, this has *O(1)* complexity. Reducing the length performs :ref:``delete`` on each removed element and has *O(n)* complexity where *n* is the number of elements being deleted. Please note that calling ``length--`` on an empty array will set the length of the array to 2^256-1 due to ``uint256`` underflow wrapping. **push**: Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``push`` that can be used to append an element at the end of the array. The function returns the new length. **pop**: - Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``pop`` that can be used to remove an element from the end of the array. + Dynamic storage arrays and ``bytes`` (not ``string``) have a member function called ``pop`` that can be used to remove an element from the end of the array. This will also implicitly call :ref:``delete`` on the removed element. .. warning:: It is not yet possible to use arrays of arrays in external functions. @@ -839,7 +890,7 @@ Members :: - pragma solidity ^0.4.16; + pragma solidity >=0.4.16 <0.6.0; contract ArrayContract { uint[2**20] m_aLotOfIntegers; @@ -919,7 +970,7 @@ shown in the following example: :: - pragma solidity ^0.4.11; + pragma solidity >=0.4.11 <0.6.0; contract CrowdFunding { // Defines a new type with two fields. @@ -1015,7 +1066,7 @@ each ``_KeyType``, recursively. For example with a mapping: :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract MappingExample { mapping(address => uint) public balances; @@ -1050,15 +1101,17 @@ If ``a`` is an LValue (i.e. a variable or something that can be assigned to), th delete ------ -``delete a`` assigns the initial value for the type to ``a``. I.e. for integers it is equivalent to ``a = 0``, but it can also be used on arrays, where it assigns a dynamic array of length zero or a static array of the same length with all elements reset. For structs, it assigns a struct with all members reset. +``delete a`` assigns the initial value for the type to ``a``. I.e. for integers it is equivalent to ``a = 0``, but it can also be used on arrays, where it assigns a dynamic array of length zero or a static array of the same length with all elements reset. For structs, it assigns a struct with all members reset. In other words, the value of ``a`` after ``delete a`` is the same as if ``a`` would be declared without assignment, with the following caveat: -``delete`` has no effect on whole mappings (as the keys of mappings may be arbitrary and are generally unknown). So if you delete a struct, it will reset all members that are not mappings and also recurse into the members unless they are mappings. However, individual keys and what they map to can be deleted. +``delete`` has no effect on mappings (as the keys of mappings may be arbitrary and are generally unknown). So if you delete a struct, it will reset all members that are not mappings and also recurse into the members unless they are mappings. However, individual keys and what they map to can be deleted: If ``a`` is a mapping, then ``delete a[x]`` will delete the value stored at ``x``. It is important to note that ``delete a`` really behaves like an assignment to ``a``, i.e. it stores a new object in ``a``. +This distinction is visible when ``a`` is reference variable: It will only reset ``a`` itself, not the +value it referred to previously. :: - pragma solidity ^0.4.0; + pragma solidity >=0.4.0 <0.6.0; contract DeleteExample { uint data; @@ -1067,7 +1120,7 @@ It is important to note that ``delete a`` really behaves like an assignment to ` function f() public { uint x = data; delete x; // sets x to 0, does not affect data - delete data; // sets data to 0, does not affect x which still holds a copy + delete data; // sets data to 0, does not affect x uint[] storage y = dataArray; delete dataArray; // this sets dataArray.length to zero, but as uint[] is a complex object, also // y is affected which is an alias to the storage object @@ -1096,12 +1149,15 @@ makes sense semantically and no information is lost: ``uint8`` is convertible to (because ``uint256`` cannot hold e.g. ``-1``). Any integer type that can be converted to ``uint160`` can also be converted to ``address``. +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 so be sure to test to ensure that the +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``: @@ -1200,3 +1256,5 @@ 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`` results in ``address payable``.
\ No newline at end of file diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index d6ef393e..7f62e71e 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -7,15 +7,25 @@ Units and Globally Available Variables Ether Units =========== -A literal number can take a suffix of ``wei``, ``finney``, ``szabo`` or ``ether`` to convert between the subdenominations of Ether, where Ether currency numbers without a postfix are assumed to be Wei, e.g. ``2 ether == 2000 finney`` evaluates to ``true``. +A literal number can take a suffix of ``wei``, ``finney``, ``szabo`` or ``ether`` to specify a subdenomination of Ether, where Ether numbers without a postfix are assumed to be Wei. + +:: + + assert(1 wei == 1); + assert(1 szabo == 1e12); + assert(1 finney == 1e15); + assert(1 ether == 1e18); + +The only effect of the subdenomination suffix is a multiplication by a power of ten. + .. index:: time, seconds, minutes, hours, days, weeks, years Time Units ========== -Suffixes like ``seconds``, ``minutes``, ``hours``, ``days``, ``weeks`` and -``years`` after literal numbers can be used to convert between units of time where seconds are the base +Suffixes like ``seconds``, ``minutes``, ``hours``, ``days`` and ``weeks`` +after literal numbers can be used to specify units of time where seconds are the base unit and units are considered naively in the following way: * ``1 == 1 seconds`` @@ -23,7 +33,6 @@ unit and units are considered naively in the following way: * ``1 hours == 60 minutes`` * ``1 days == 24 hours`` * ``1 weeks == 7 days`` - * ``1 years == 365 days`` Take care if you perform calendar calculations using these units, because not every year equals 365 days and not even every day has 24 hours @@ -32,7 +41,7 @@ Due to the fact that leap seconds cannot be predicted, an exact calendar library has to be updated by an external oracle. .. note:: - The suffix ``years`` has been deprecated due to the reasons above and cannot be used starting version 0.5.0. + The suffix ``years`` has been removed in version 0.5.0 due to the reasons above. These suffixes cannot be applied to variables. If you want to interpret some input variable in e.g. days, you can do it in the following way:: @@ -56,15 +65,14 @@ or are general-use utility functions. Block and Transaction Properties -------------------------------- -- ``block.blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by ``blockhash(uint blockNumber)``. +- ``blockhash(uint blockNumber) returns (bytes32)``: hash of the given block - only works for 256 most recent, excluding current, blocks - ``block.coinbase`` (``address payable``): current block miner's address - ``block.difficulty`` (``uint``): current block difficulty - ``block.gaslimit`` (``uint``): current block gaslimit - ``block.number`` (``uint``): current block number - ``block.timestamp`` (``uint``): current block timestamp as seconds since unix epoch - ``gasleft() returns (uint256)``: remaining gas -- ``msg.data`` (``bytes``): complete calldata -- ``msg.gas`` (``uint``): remaining gas - deprecated in version 0.4.21 and to be replaced by ``gasleft()`` +- ``msg.data`` (``bytes calldata``): complete calldata - ``msg.sender`` (``address payable``): sender of the message (current call) - ``msg.sig`` (``bytes4``): first four bytes of the calldata (i.e. function identifier) - ``msg.value`` (``uint``): number of wei sent with the message @@ -94,20 +102,28 @@ Block and Transaction Properties You can only access the hashes of the most recent 256 blocks, all other values will be zero. +.. note:: + The function ``blockhash`` was previously known as ``block.blockhash``. It was deprecated in + version 0.4.22 and removed in version 0.5.0. + +.. note:: + The function ``gasleft`` was previously known as ``msg.gas``. It was deprecated in + version 0.4.21 and removed in version 0.5.0. + .. index:: abi, encoding, packed ABI Encoding and Decoding Functions ----------------------------------- -- ``abi.decode(bytes encodedData, (...)) returns (...)``: ABI-decodes the given data, while the types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` -- ``abi.encode(...) returns (bytes)``: ABI-encodes the given arguments -- ``abi.encodePacked(...) returns (bytes)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments -- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes)``: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector -- ``abi.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``` +- ``abi.decode(bytes memory encodedData, (...)) returns (...)``: ABI-decodes the given data, while the types are given in parentheses as second argument. Example: ``(uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))`` +- ``abi.encode(...) returns (bytes memory)``: ABI-encodes the given arguments +- ``abi.encodePacked(...) returns (bytes memory)``: Performs :ref:`packed encoding <abi_packed_mode>` of the given arguments +- ``abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory)``: ABI-encodes the given arguments starting from the second and prepends the given four-byte selector +- ``abi.encodeWithSignature(string memory signature, ...) returns (bytes memory)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``` .. note:: - These encoding functions can be used to craft data for function calls without actually - calling a function. Furthermore, ``keccak256(abi.encodePacked(a, b))`` is a way + These encoding functions can be used to craft data for external function calls without actually + calling an external function. Furthermore, ``keccak256(abi.encodePacked(a, b))`` is a way to compute the hash of structured data (although be aware that it is possible to craft a "hash collision" using different inputs types). @@ -119,15 +135,18 @@ See the documentation about the :ref:`ABI <ABI>` and the Error Handling -------------- +See the dedicated section on :ref:`assert and require<assert-and-require>` for +more details on error handling and when to use which function. + ``assert(bool condition)``: - invalidates the transaction if the condition is not met - to be used for internal errors. + causes an invalid opcode and thus state change reversion if the condition is not met - to be used for internal errors. ``require(bool condition)``: reverts if the condition is not met - to be used for errors in inputs or external components. -``require(bool condition, string message)``: +``require(bool condition, string memory message)``: reverts if the condition is not met - to be used for errors in inputs or external components. Also provides an error message. ``revert()``: abort execution and revert state changes -``revert(string reason)``: +``revert(string memory reason)``: abort execution and revert state changes, providing an explanatory string .. index:: keccak256, ripemd160, sha256, ecrecover, addmod, mulmod, cryptography, @@ -140,11 +159,9 @@ Mathematical and Cryptographic Functions ``mulmod(uint x, uint y, uint k) returns (uint)``: compute ``(x * y) % k`` where the multiplication is performed with arbitrary precision and does not wrap around at ``2**256``. Assert that ``k != 0`` starting from version 0.5.0. ``keccak256(bytes memory) returns (bytes32)``: - compute the Ethereum-SHA-3 (Keccak-256) hash of the input + compute the Keccak-256 hash of the input ``sha256(bytes memory) returns (bytes32)``: compute the SHA-256 hash of the input -``sha3(bytes memory) returns (bytes32)``: - alias to ``keccak256`` ``ripemd160(bytes memory) returns (bytes20)``: compute RIPEMD-160 hash of the input ``ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)``: @@ -158,26 +175,27 @@ Mathematical and Cryptographic Functions It might be that you run into Out-of-Gas for ``sha256``, ``ripemd160`` or ``ecrecover`` on a *private blockchain*. The reason for this is that those are implemented as so-called precompiled contracts and these contracts only really exist after they received the first message (although their contract code is hardcoded). Messages to non-existing contracts are more expensive and thus the execution runs into an Out-of-Gas error. A workaround for this problem is to first send e.g. 1 Wei to each of the contracts before you use them in your actual contracts. This is not an issue on the official or test net. +.. note:: + There used to be an alias for ``keccak256`` called ``sha3``, which was removed in version 0.5.0. + .. index:: balance, send, transfer, call, callcode, delegatecall, staticcall .. _address_related: -Address Related ---------------- +Members of Address Types +------------------------ ``<address>.balance`` (``uint256``): balance of the :ref:`address` in Wei ``<address payable>.transfer(uint256 amount)``: - send given amount of Wei to :ref:`address`, throws on failure, forwards 2300 gas stipend, not adjustable + send given amount of Wei to :ref:`address`, reverts on failure, forwards 2300 gas stipend, not adjustable ``<address payable>.send(uint256 amount) returns (bool)``: send given amount of Wei to :ref:`address`, returns ``false`` on failure, forwards 2300 gas stipend, not adjustable -``<address>.call(bytes memory) returns (bool)``: - issue low-level ``CALL`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable -``<address>.callcode(bytes memory) returns (bool)``: - issue low-level ``CALLCODE`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable -``<address>.delegatecall(bytes memory) returns (bool)``: - issue low-level ``DELEGATECALL`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable -``<address>.staticcall(bytes memory) returns (bool)``: - issue low-level ``STATICCALL`` with the given payload, returns ``false`` on failure, forwards all available gas, adjustable +``<address>.call(bytes memory) returns (bool, bytes memory)``: + issue low-level ``CALL`` with the given payload, returns success condition and return data, forwards all available gas, adjustable +``<address>.delegatecall(bytes memory) returns (bool, bytes memory)``: + issue low-level ``DELEGATECALL`` with the given payload, returns success condition and return data, forwards all available gas, adjustable +``<address>.staticcall(bytes memory) returns (bool, bytes memory)``: + issue low-level ``STATICCALL`` with the given payload, returns success condition and return data, forwards all available gas, adjustable For more information, see the section on :ref:`address`. @@ -192,14 +210,19 @@ For more information, see the section on :ref:`address`. This is now forbidden and an explicit conversion to address must be done: ``address(this).balance``. .. note:: - If storage variables are accessed via a low-level delegatecall, the storage layout of the two contracts + If state variables are accessed via a low-level delegatecall, the storage layout of the two contracts must align in order for the called contract to correctly access the storage variables of the calling contract by name. This is of course not the case if storage pointers are passed as function arguments as in the case for the high-level libraries. +.. note:: + Prior to version 0.5.0, ``.call``, ``.delegatecall`` and ``.staticcall`` only returned the + success condition and not the return data. .. note:: - The use of ``callcode`` is discouraged and will be removed in the future. + Prior to version 0.5.0, there was a member called ``callcode`` with similar but slightly different + semantics than ``delegatecall``. + .. index:: this, selfdestruct @@ -212,8 +235,9 @@ Contract Related ``selfdestruct(address payable recipient)``: destroy the current contract, sending its funds to the given :ref:`address` -``suicide(address payable recipient)``: - deprecated alias to ``selfdestruct`` - Furthermore, all functions of the current contract are callable directly including the current function. +.. note:: + Prior to version 0.5.0, there was a function called ``suicide`` with the same + semantics as ``selfdestruct``. + 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 |