diff options
Diffstat (limited to 'docs')
-rw-r--r-- | docs/bugs.json | 17 | ||||
-rw-r--r-- | docs/bugs.rst | 8 | ||||
-rw-r--r-- | docs/bugs_by_version.json | 62 | ||||
-rw-r--r-- | docs/contracts.rst | 81 | ||||
-rw-r--r-- | docs/control-structures.rst | 6 | ||||
-rw-r--r-- | docs/frequently-asked-questions.rst | 29 | ||||
-rw-r--r-- | docs/miscellaneous.rst | 1 | ||||
-rw-r--r-- | docs/security-considerations.rst | 3 | ||||
-rw-r--r-- | docs/solidity-by-example.rst | 2 | ||||
-rw-r--r-- | docs/types.rst | 8 | ||||
-rw-r--r-- | docs/units-and-global-variables.rst | 11 |
11 files changed, 168 insertions, 60 deletions
diff --git a/docs/bugs.json b/docs/bugs.json index b464be18..839ea128 100644 --- a/docs/bugs.json +++ b/docs/bugs.json @@ -1,4 +1,21 @@ [ + { + "name": "EventStructWrongData", + "summary": "Using structs in events logged wrong data.", + "description": "If a struct is used in an event, the address of the struct is logged instead of the actual data.", + "introduced": "0.4.17", + "fixed": "0.5.0", + "severity": "very low" + }, + { + "name": "NestedArrayFunctionCallDecoder", + "summary": "Calling functions that return multi-dimensional fixed-size arrays can result in memory corruption.", + "description": "If Solidity code calls a function that returns a multi-dimensional fixed-size array, array elements are incorrectly interpreted as memory pointers and thus can cause memory corruption if the return values are accessed. Calling functions with multi-dimensional fixed-size arrays is unaffected as is returning fixed-size arrays from function calls. The regular expression only checks if such functions are present, not if they are called, which is required for the contract to be affected.", + "introduced": "0.1.4", + "fixed": "0.4.22", + "severity": "medium", + "check": {"regex-source": "returns[^;{]*\\[\\s*[^\\] \\t\\r\\n\\v\\f][^\\]]*\\]\\s*\\[\\s*[^\\] \\t\\r\\n\\v\\f][^\\]]*\\][^{;]*[;{]"} + }, { "name": "OneOfTwoConstructorsSkipped", "summary": "If a contract has both a new-style constructor (using the constructor keyword) and an old-style constructor (a function with the same name as the contract) at the same time, one of them will be ignored.", diff --git a/docs/bugs.rst b/docs/bugs.rst index 7629830d..6f315a65 100644 --- a/docs/bugs.rst +++ b/docs/bugs.rst @@ -56,6 +56,14 @@ conditions is an object that can contain a boolean value ``optimizer``, which means that the optimizer has to be switched on to enable the bug. If no conditions are given, assume that the bug is present. +check + This field contains JavaScript regular expressions that are to be matched + against the source code ("source-regex") to find out if the + smart contract contains the bug or not. If there is no match, + then the bug is very likely not present. If there is a match, + the bug might be present. For improved accuracy, the regular + expression should be applied to the source code after stripping + comments. .. literalinclude:: bugs.json :language: js diff --git a/docs/bugs_by_version.json b/docs/bugs_by_version.json index 2fe1d226..560b6fa9 100644 --- a/docs/bugs_by_version.json +++ b/docs/bugs_by_version.json @@ -69,6 +69,7 @@ }, "0.1.4": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "ECRecoverMalformedInput", "SkipEmptyStringLiteral", @@ -86,6 +87,7 @@ }, "0.1.5": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "ECRecoverMalformedInput", "SkipEmptyStringLiteral", @@ -103,6 +105,7 @@ }, "0.1.6": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "ECRecoverMalformedInput", "SkipEmptyStringLiteral", @@ -121,6 +124,7 @@ }, "0.1.7": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "ECRecoverMalformedInput", "SkipEmptyStringLiteral", @@ -139,6 +143,7 @@ }, "0.2.0": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "ECRecoverMalformedInput", "SkipEmptyStringLiteral", @@ -157,6 +162,7 @@ }, "0.2.1": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "ECRecoverMalformedInput", "SkipEmptyStringLiteral", @@ -175,6 +181,7 @@ }, "0.2.2": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "ECRecoverMalformedInput", "SkipEmptyStringLiteral", @@ -193,6 +200,7 @@ }, "0.3.0": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -211,6 +219,7 @@ }, "0.3.1": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -228,6 +237,7 @@ }, "0.3.2": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -245,6 +255,7 @@ }, "0.3.3": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -261,6 +272,7 @@ }, "0.3.4": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -277,6 +289,7 @@ }, "0.3.5": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -293,6 +306,7 @@ }, "0.3.6": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -307,6 +321,7 @@ }, "0.4.0": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -321,6 +336,7 @@ }, "0.4.1": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -335,6 +351,7 @@ }, "0.4.10": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -345,6 +362,7 @@ }, "0.4.11": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -354,6 +372,7 @@ }, "0.4.12": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput" @@ -362,6 +381,7 @@ }, "0.4.13": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput" @@ -370,6 +390,7 @@ }, "0.4.14": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue" ], @@ -377,32 +398,43 @@ }, "0.4.15": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector" ], "released": "2017-08-08" }, "0.4.16": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector" ], "released": "2017-08-24" }, "0.4.17": { "bugs": [ + "EventStructWrongData", + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector" ], "released": "2017-09-21" }, "0.4.18": { - "bugs": [], + "bugs": [ + "EventStructWrongData", + "NestedArrayFunctionCallDecoder" + ], "released": "2017-10-18" }, "0.4.19": { - "bugs": [], + "bugs": [ + "EventStructWrongData", + "NestedArrayFunctionCallDecoder" + ], "released": "2017-11-30" }, "0.4.2": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -415,29 +447,41 @@ "released": "2016-09-17" }, "0.4.20": { - "bugs": [], + "bugs": [ + "EventStructWrongData", + "NestedArrayFunctionCallDecoder" + ], "released": "2018-02-14" }, "0.4.21": { - "bugs": [], + "bugs": [ + "EventStructWrongData", + "NestedArrayFunctionCallDecoder" + ], "released": "2018-03-07" }, "0.4.22": { "bugs": [ + "EventStructWrongData", "OneOfTwoConstructorsSkipped" ], "released": "2018-04-16" }, "0.4.23": { - "bugs": [], + "bugs": [ + "EventStructWrongData" + ], "released": "2018-04-19" }, "0.4.24": { - "bugs": [], + "bugs": [ + "EventStructWrongData" + ], "released": "2018-05-16" }, "0.4.3": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -450,6 +494,7 @@ }, "0.4.4": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -461,6 +506,7 @@ }, "0.4.5": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -473,6 +519,7 @@ }, "0.4.6": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -484,6 +531,7 @@ }, "0.4.7": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -494,6 +542,7 @@ }, "0.4.8": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", @@ -504,6 +553,7 @@ }, "0.4.9": { "bugs": [ + "NestedArrayFunctionCallDecoder", "ZeroFunctionSelector", "DelegateCallReturnValue", "ECRecoverMalformedInput", diff --git a/docs/contracts.rst b/docs/contracts.rst index ca15d814..669a374f 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -26,8 +26,8 @@ Creating contracts programmatically on Ethereum is best done via using the JavaS As of today it has a method 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. +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 overloading is not supported. @@ -261,7 +261,37 @@ it is evaluated as a state variable. If it is accessed externally } } -The next example is a bit more complex: +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 +``data(0)``. If you want to return an entire array in one call, then you need +to write a function, for example: + +:: + + pragma solidity ^0.4.0; + contract arrayExample { + // public state variable + uint[] public myArray; + + // Getter function generated by the compiler + /* + function myArray(uint i) returns (uint) { + return myArray[i]; + } + */ + + // function that returns entire array + function getArray() returns (uint[] memory) { + return myArray; + } + } + +Now you can use ``getArray()`` to retrieve the entire array, instead of +``myArray(i)``, which returns a single element per call. + +The next example is more complex: :: @@ -276,16 +306,16 @@ The next example is a bit more complex: mapping (uint => mapping(bool => Data[])) public data; } -It will generate a function of the following form:: +It generates a function of the following form. The mapping in the struct is omitted +because there is no good way to provide the key for the mapping: + +:: function data(uint arg1, bool arg2, uint arg3) public returns (uint a, bytes3 b) { a = data[arg1][arg2][arg3].a; b = data[arg1][arg2][arg3].b; } -Note that the mapping in the struct is omitted because there -is no good way to provide the key for the mapping. - .. index:: ! function;modifier .. _modifiers: @@ -842,13 +872,14 @@ Solidity supports multiple inheritance by copying code including polymorphism. All function calls are virtual, which means that the most derived function is called, except when the contract name is explicitly given. -When a contract inherits from multiple contracts, only a single +When a contract inherits from other contracts, only a single contract is created on the blockchain, and the code from all the base contracts is copied into the created contract. The general inheritance system is very similar to `Python's <https://docs.python.org/3/tutorial/classes.html#inheritance>`_, -especially concerning multiple inheritance. +especially concerning multiple inheritance, but there are also +some :ref:`differences <multi-inheritance>`. Details are given in the following example. @@ -993,12 +1024,26 @@ virtual method lookup. .. index:: ! constructor +.. _constructor: + Constructors ============ -A constructor is an optional function declared with the ``constructor`` keyword which is executed upon contract creation. -Constructor functions can be either ``public`` or ``internal``. If there is no constructor, the contract will assume the -default constructor: ``contructor() public {}``. +A constructor is an optional function declared with the ``constructor`` keyword +which is executed upon contract creation, and where you can run contract +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. + +Constructor functions can be either ``public`` or ``internal``. If there is no +constructor, the contract will assume the default constructor, which is +equivalent to ``constructor() public {}``. For example: :: @@ -1064,6 +1109,8 @@ contracts' constructors, it will be abstract. .. index:: ! inheritance;multiple, ! linearization, ! C3 linearization +.. _multi-inheritance: + Multiple Inheritance and Linearization ====================================== @@ -1076,7 +1123,13 @@ disallows some inheritance graphs. Especially, the order in which the base classes are given in the ``is`` directive is important: You have to list the direct base contracts in the order from "most base-like" to "most derived". -Note that this order is different from the one used in Python. +Note that this order is the reverse of the one used in Python. + +Another simplifying way to explain this is that when a function is called that +is defined multiple times in different contracts, the given bases +are searched from right to left (left to right in Python) in a depth-first manner, +stopping at the first match. If a base contract has already been searched, it is skipped. + In the following code, Solidity will give the error "Linearization of inheritance graph impossible". @@ -1094,6 +1147,8 @@ The reason for this is that ``C`` requests ``X`` to override ``A`` requests to override ``X``, which is a contradiction that cannot be resolved. + + Inheriting Different Kinds of Members of the Same Name ====================================================== diff --git a/docs/control-structures.rst b/docs/control-structures.rst index def75132..d0e58908 100644 --- a/docs/control-structures.rst +++ b/docs/control-structures.rst @@ -412,11 +412,11 @@ The deprecated keyword ``throw`` can also be used as an alternative to ``revert( From version 0.4.13 the ``throw`` keyword is deprecated and will be phased out in the future. 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`` and ``callcode`` -- those return ``false`` in case +and the low-level functions ``call``, ``delegatecall``, ``callcode`` and ``staticcall`` -- those return ``false`` in case of an exception instead of "bubbling up". .. warning:: - The low-level ``call``, ``delegatecall`` and ``callcode`` 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 ``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. Catching exceptions is not yet possible. @@ -455,7 +455,7 @@ 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`` or ``callcode`` is used. The low level operations never throw exceptions but indicate failures by returning ``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"). #. If you perform an external function call targeting a contract that contains no code. #. If your contract receives Ether via a public function without ``payable`` modifier (including the constructor and the fallback function). diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index 2c5f8661..d2b7de9c 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -238,13 +238,6 @@ The key point is that the calling contract needs to know about the function it i See `ping.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_ping.sol>`_ and `pong.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/45_pong.sol>`_. -Get contract to do something when it is first mined -=================================================== - -Use the constructor. Anything inside it will be executed when the contract is first mined. - -See `replicator.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/50_replicator.sol>`_. - How do you create 2-dimensional arrays? ======================================= @@ -410,28 +403,6 @@ Is it possible to return an array of strings (``string[]``) from a Solidity func Not yet, as this requires two levels of dynamic arrays (``string`` is a dynamic array itself). -If you issue a call for an array, it is possible to retrieve the whole array? Or must you write a helper function for that? -=========================================================================================================================== - -The automatic :ref:`getter function<getter-functions>` for a public state variable of array type only returns -individual elements. If you want to return the complete array, you have to -manually write a function to do that. - - -What could have happened if an account has storage value(s) but no code? Example: http://test.ether.camp/account/5f740b3a43fbb99724ce93a879805f4dc89178b5 -========================================================================================================================================================== - -The last thing a constructor does is returning the code of the contract. -The gas costs for this depend on the length of the code and it might be -that the supplied gas is not enough. This situation is the only one -where an "out of gas" exception does not revert changes to the state, -i.e. in this case the initialisation of the state variables. - -https://github.com/ethereum/wiki/wiki/Subtleties - -After a successful CREATE operation's sub-execution, if the operation returns x, 5 * len(x) gas is subtracted from the remaining gas before the contract is created. If the remaining gas is less than 5 * len(x), then no gas is subtracted, the code of the created contract becomes the empty string, but this is not treated as an exceptional condition - no reverts happen. - - What does the following strange check do in the Custom Token contract? ====================================================================== diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 7225144a..87041be6 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -322,6 +322,7 @@ 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 diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 5bb3d81d..066a31ea 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -171,7 +171,8 @@ before they interact with your contract. Note that ``.send()`` does **not** throw an exception if the call stack is depleted but rather returns ``false`` in that case. The low-level functions -``.call()``, ``.callcode()`` and ``.delegatecall()`` behave in the same way. +``.call()``, ``.callcode()``, ``.delegatecall()`` and ``.staticcall()`` behave +in the same way. tx.origin ========= diff --git a/docs/solidity-by-example.rst b/docs/solidity-by-example.rst index adf00546..72b3581b 100644 --- a/docs/solidity-by-example.rst +++ b/docs/solidity-by-example.rst @@ -907,7 +907,7 @@ Each message includes the following information: * The smart contract's address, used to prevent cross-contract replay attacks. * The total amount of Ether that is owed the recipient so far. -A payment channel is closed just once, at the of a series of transfers. +A payment channel is closed just once, at the end of a series of transfers. Because of this, only one of the messages sent will be redeemed. This is why each message specifies a cumulative total amount of Ether owed, rather than the amount of the individual micropayment. The recipient will naturally choose to diff --git a/docs/types.rst b/docs/types.rst index 6024cbb7..03fd36d9 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -91,7 +91,7 @@ Operators: defined in the latter. Generally, in floating point almost the entire space is used to represent the number, while only a small number of bits define where the decimal point is. -.. index:: address, balance, send, call, callcode, delegatecall, transfer +.. index:: address, balance, send, call, callcode, delegatecall, staticcall, transfer .. _address: @@ -146,7 +146,7 @@ Send is the low-level counterpart of ``transfer``. If the execution fails, the c to make safe Ether transfers, always check the return value of ``send``, use ``transfer`` or even better: use a pattern where the recipient withdraws the money. -* ``call``, ``callcode`` and ``delegatecall`` +* ``call``, ``callcode``, ``delegatecall`` and ``staticcall`` Furthermore, to interface with contracts that do not adhere to the ABI, or to get more direct control over the encoding, @@ -189,7 +189,9 @@ Lastly, these modifiers can be combined. Their order does not matter:: In a similar way, the function ``delegatecall`` can be used: the difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. Prior to homestead, only a limited variant called ``callcode`` was available that did not provide access to the original ``msg.sender`` and ``msg.value`` values. -All three functions ``call``, ``delegatecall`` and ``callcode`` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. +Since byzantium ``staticcall`` can be used as well. This is basically the same as ``call``, but will revert, if the called function modifies the state in any way. + +All four functions ``call``, ``delegatecall``, ``callcode`` and ``staticcall`` are very low-level functions and should only be used as a *last resort* as they break the type-safety of Solidity. The ``.gas()`` option is available on all three methods, while the ``.value()`` option is not supported for ``delegatecall``. diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index 6eae2804..28c9e6ab 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -96,13 +96,14 @@ Block and Transaction Properties .. index:: abi, encoding, packed -ABI Encoding Functions ----------------------- +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.encodeWithSignature(string signature, ...) returns (bytes)``: Equivalent to ``abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)``` .. note:: These encoding functions can be used to craft data for function calls without actually @@ -152,7 +153,7 @@ 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. -.. index:: balance, send, transfer, call, callcode, delegatecall +.. index:: balance, send, transfer, call, callcode, delegatecall, staticcall .. _address_related: Address Related @@ -170,6 +171,8 @@ Address Related 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 For more information, see the section on :ref:`address`. |