From 9c4a02db0fb901cea81bca06e3f0b73f3c9e5f16 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 19 Mar 2020 17:57:55 +0100 Subject: [PATCH] Documentation for immutables. --- docs/contracts/constant-state-variables.rst | 73 ++++++++++++++++----- docs/miscellaneous.rst | 1 + docs/types/reference-types.rst | 6 ++ 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/docs/contracts/constant-state-variables.rst b/docs/contracts/constant-state-variables.rst index 33511f020..7a0a7380a 100644 --- a/docs/contracts/constant-state-variables.rst +++ b/docs/contracts/constant-state-variables.rst @@ -1,11 +1,49 @@ .. index:: ! constant -************************ -Constant State Variables -************************ +************************************** +Constant and Immutable State Variables +************************************** -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 +State variables can be declared as ``constant`` or ``immutable``. +In both cases, the variables cannot be modified after the contract has been constructed. +For ``constant`` variables, the value has to be fixed at compile-time, while +for ``immutable``, it can still be assigned at construction time. + +The compiler does not reserve a storage slot for these variables, and every occurrence is +replaced by the respective value. + +Not all types for constants and immutables are implemented at this time. The only supported types are +`strings `_ (only for constants) and `value types `_. + +:: + + pragma solidity >0.6.4 <0.7.0; + + contract C { + uint constant X = 32**22 + 8; + string constant TEXT = "abc"; + bytes32 constant MY_HASH = keccak256("abc"); + uint immutable decimals; + uint immutable maxBalance; + address immutable owner = msg.sender; + + constructor(uint _decimals, address _reference) public { + decimals = _decimals; + // Assignments to immutables can even access the environment. + maxBalance = _reference.balance; + } + + function isBalanceTooHigh(address _other) public view returns (bool) { + return _other.balance > maxBalance; + } + } + + +Constant +======== + +For ``constant`` variables, the value has to be a constant at compile time and it has to be +assigned where the variable is declared. Any expression that accesses storage, blockchain data (e.g. ``now``, ``address(this).balance`` or ``block.number``) or execution data (``msg.value`` or ``gasleft()``) or makes calls to external contracts is disallowed. Expressions @@ -18,18 +56,17 @@ The reason behind allowing side-effects on the memory allocator is that it should be possible to construct complex objects like e.g. lookup-tables. This feature is not yet fully usable. -The compiler does not reserve a storage slot for these variables, and every occurrence is -replaced by the respective constant expression (which might be computed to a single value by the optimizer). +Immutable +========= -Not all types for constants are implemented at this time. The only supported types are -value types and strings. +Variables declared as ``immutable`` are a bit less restricted than those +declared as ``constant``: Immutable variables can be assigned an arbitrary +value in the constructor of the contract or at the point of their declaration. +They cannot be read during construction time and can only be assigned once. -:: - - pragma solidity >=0.4.0 <0.7.0; - - contract C { - uint constant X = 32**22 + 8; - string constant TEXT = "abc"; - bytes32 constant MY_HASH = keccak256("abc"); - } +The contract creation code generated by the compiler will modify the +contract's runtime code before it is returned by replacing all references +to immutables by the values assigned to the them. This is important if +you are comparing the +runtime code generated by the compiler with the one actually stored in the +blockchain. diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index b4082fced..3c30fec86 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -788,6 +788,7 @@ Modifiers - ``view`` for functions: Disallows modification of state. - ``payable`` for functions: Allows them to receive Ether together with a call. - ``constant`` for state variables: Disallows assignment (except initialisation), does not occupy storage slot. +- ``immutable`` for state variables: Allows exactly one assignment at construction time and is constant afterwards. Is stored in code. - ``anonymous`` for events: Does not store event signature as topic. - ``indexed`` for event parameters: Stores the parameter as topic. - ``virtual`` for functions and modifiers: Allows the function's or modifier's diff --git a/docs/types/reference-types.rst b/docs/types/reference-types.rst index 275e8b575..1566a8859 100644 --- a/docs/types/reference-types.rst +++ b/docs/types/reference-types.rst @@ -124,6 +124,12 @@ Accessing an array past its end causes a failing assertion. Methods ``.push()`` to append a new element at the end of the array, where ``.push()`` appends a zero-initialized element and returns a reference to it. +.. index:: ! string, ! bytes + +.. _strings: + +.. _bytes: + ``bytes`` and ``strings`` as Arrays ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^