From 8743b2ceadd4a50e7137aca99b4fceeef780b55c Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 29 Aug 2017 22:48:54 +0100 Subject: Document call/gas modifiers properly --- docs/frequently-asked-questions.rst | 17 ----------------- docs/types.rst | 12 ++++++++++++ 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index 5f1a981e..ed09044e 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -503,23 +503,6 @@ Note2: Optimizing storage access can pull the gas costs down considerably, becau currently do not work across loops and also have a problem with bounds checking. You might get much better results in the future, though. -What does ``p.recipient.call.value(p.amount)(p.data)`` do? -========================================================== - -Every external function call in Solidity can be modified in two ways: - -1. You can add Ether together with the call -2. You can limit the amount of gas available to the call - -This is done by "calling a function on the function": - -``f.gas(2).value(20)()`` calls the modified function ``f`` and thereby sending 20 -Wei and limiting the gas to 2 (so this function call will most likely go out of -gas and return your 20 Wei). - -In the above example, the low-level function ``call`` is used to invoke another -contract with ``p.data`` as payload and ``p.amount`` Wei is sent with that call. - What happens to a ``struct``'s mapping when copying over a ``struct``? ====================================================================== diff --git a/docs/types.rst b/docs/types.rst index aa4589de..098d0380 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -127,6 +127,18 @@ the function ``call`` is provided which takes an arbitrary number of arguments o ``call`` returns a boolean indicating whether the invoked function terminated (``true``) or caused an EVM exception (``false``). It is not possible to access the actual data returned (for this we would need to know the encoding and size in advance). +It is possible to adjust the supplied gas with the ``.gas()`` modifier:: + + namReg.call.gas(1000000)("register", "MyName"); + +Similarly, the supplied Ether value can be controlled too:: + + nameReg.call.value(1 ether)("register", "MyName"); + +Lastly, these modifiers can be combined. Their order does not matter:: + + nameReg.call.gas(1000000).value(1 ether)("register", "MyName"); + 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. -- cgit From f787ecae5a0186bb19a99ac8577123700b0c93a7 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 29 Aug 2017 22:53:50 +0100 Subject: Document byte[] vs bytes --- docs/frequently-asked-questions.rst | 7 ------- docs/types.rst | 4 ++++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index ed09044e..694b28d5 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -441,13 +441,6 @@ The correct way to do this is the following:: } } -What is the difference between ``bytes`` and ``byte[]``? -======================================================== - -``bytes`` is usually more efficient: When used as arguments to functions (i.e. in -CALLDATA) or in memory, every single element of a ``byte[]`` is padded to 32 -bytes which wastes 31 bytes per element. - Is it possible to send a value while calling an overloaded function? ==================================================================== diff --git a/docs/types.rst b/docs/types.rst index 098d0380..23a70837 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -181,6 +181,10 @@ 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``. + Dynamically-sized byte array ---------------------------- -- cgit From 8e1aae2e1a5c47fe11b5e17e670fcbb09ebda365 Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 29 Aug 2017 22:56:05 +0100 Subject: Document gas/value modifiers with overloading --- docs/frequently-asked-questions.rst | 10 ---------- docs/types.rst | 6 ++++++ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index 694b28d5..8fd0c041 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -441,16 +441,6 @@ The correct way to do this is the following:: } } -Is it possible to send a value while calling an overloaded function? -==================================================================== - -It's a known missing feature. https://www.pivotaltracker.com/story/show/92020468 -as part of https://www.pivotaltracker.com/n/projects/1189488 - -Best solution currently see is to introduce a special case for gas and value and -just re-check whether they are present at the point of overload resolution. - - ****************** Advanced Questions ****************** diff --git a/docs/types.rst b/docs/types.rst index 23a70837..d3ebfe14 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -139,6 +139,12 @@ Lastly, these modifiers can be combined. Their order does not matter:: nameReg.call.gas(1000000).value(1 ether)("register", "MyName"); +.. note:: + It is not yet possible to use the gas or value modifiers on overloaded functions. + + A workaround is to introduce a special case for gas and value and just re-check + whether they are present at the point of overload resolution. + In a similar way, the function ``delegatecall`` can be used: the difference is that only the code of the given address is used, all other aspects (storage, balance, ...) are taken from the current contract. The purpose of ``delegatecall`` is to use library code which is stored in another contract. The user has to ensure that the layout of storage in both contracts is suitable for delegatecall to be used. 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. -- cgit From f3230a41cebe4778c5c831e2bfa4fb3b7e10f4cb Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 29 Aug 2017 23:34:53 +0100 Subject: Document caveats about timestamp and blockhash --- docs/frequently-asked-questions.rst | 18 ------------------ docs/units-and-global-variables.rst | 12 ++++++++++++ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index 8fd0c041..e4eee32b 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -125,24 +125,6 @@ Example:: } } -Are timestamps (``now,`` ``block.timestamp``) reliable? -======================================================= - -This depends on what you mean by "reliable". -In general, they are supplied by miners and are therefore vulnerable. - -Unless someone really messes up the blockchain or the clock on -your computer, you can make the following assumptions: - -You publish a transaction at a time X, this transaction contains same -code that calls ``now`` and is included in a block whose timestamp is Y -and this block is included into the canonical chain (published) at a time Z. - -The value of ``now`` will be identical to Y and X <= Y <= Z. - -Never use ``now`` or ``block.hash`` as a source of randomness, unless you know -what you are doing! - Can a contract function return a ``struct``? ============================================ diff --git a/docs/units-and-global-variables.rst b/docs/units-and-global-variables.rst index 64795306..887535da 100644 --- a/docs/units-and-global-variables.rst +++ b/docs/units-and-global-variables.rst @@ -72,6 +72,18 @@ Block and Transaction Properties ``msg.value`` can change for every **external** function call. This includes calls to library functions. +.. note:: + Do not rely on ``block.timestamp``, ``now`` and ``block.blockhash`` as a source of randomness, + unless you know what you are doing. + + Both the timestamp and the block hash can be influenced by miners to some degree. + Bad actors in the mining community can for example run a casino payout function on a chosen hash + and just retry a different hash if they did not receive any money. + + The current block timestamp must be strictly larger than the timestamp of the last block, + but the only guarantee is that it will be somewhere between the timestamps of two + consecutive blocks in the canonical chain. + .. note:: If you want to implement access restrictions in library functions using ``msg.sender``, you have to manually supply the value of -- cgit From cbd729957b60599f55dfd1f3c7b64a7e4540c6ce Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Tue, 29 Aug 2017 23:39:28 +0100 Subject: Document character set --- docs/frequently-asked-questions.rst | 7 ------- docs/introduction-to-smart-contracts.rst | 4 ++++ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index e4eee32b..c4de60cd 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -212,13 +212,6 @@ Better use ``for (uint i = 0; i < a.length...`` See `struct_and_for_loop_tester.sol `_. -What character set does Solidity use? -===================================== - -Solidity is character set agnostic concerning strings in the source code, although -UTF-8 is recommended. Identifiers (variables, functions, ...) can only use -ASCII. - What are some examples of basic string manipulation (``substring``, ``indexOf``, ``charAt``, etc)? ================================================================================================== diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 1a3cf638..33a8ad10 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -57,6 +57,10 @@ and overwrite your number, but the number will still be stored in the history of the blockchain. Later, we will see how you can impose access restrictions so that only you can alter the number. +.. note:: + All identifiers (contract names, function names and variable names) are restricted to + the ASCII character set. It is possible to store UTF-8 encoded data in string variables. + .. index:: ! subcurrency Subcurrency Example -- cgit From 88bce877c467982be049b4f6515974cec3ebd89e Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Wed, 30 Aug 2017 02:31:54 +0100 Subject: Clarify some subtleties of the fallback function --- docs/contracts.rst | 21 ++++++++++++++++++--- docs/frequently-asked-questions.rst | 31 ------------------------------- 2 files changed, 18 insertions(+), 34 deletions(-) diff --git a/docs/contracts.rst b/docs/contracts.rst index aa3f8fa6..a1a44665 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -543,9 +543,12 @@ functions match the given function identifier (or if no data was supplied at all). Furthermore, this function is executed whenever the contract receives plain -Ether (without data). In such a context, there is usually very little gas available to -the function call (to be precise, 2300 gas), so it is important to make fallback functions as cheap as -possible. +Ether (without data). Additionally, in order to receive Ether, the fallback function +must be marked ``payable``. If no such function exists, the contract cannot receive +Ether through regular transactions. + +In such a context, there is usually very little gas available to the function call (to be precise, 2300 gas), +so it is important to make fallback functions as cheap as possible. In particular, the following operations will consume more gas than the stipend provided to a fallback function: @@ -556,6 +559,10 @@ In particular, the following operations will consume more gas than the stipend p Please ensure you test your fallback function thoroughly to ensure the execution cost is less than 2300 gas before deploying a contract. +.. note:: + Even though the fallback function cannot have arguments, one can still use ``msg.data`` to retrieve + any payload supplied with the call. + .. warning:: Contracts that receive Ether directly (without a function call, i.e. using ``send`` or ``transfer``) but do not define a fallback function @@ -563,6 +570,14 @@ Please ensure you test your fallback function thoroughly to ensure the execution before Solidity v0.4.0). So if you want your contract to receive Ether, you have to implement a fallback function. +.. warning:: + A contract without a payable fallback function can receive Ether as a recipient of a `coinbase transaction` (aka `miner block reward`) + or as a destination of a ``selfdestruct``. + + A contract cannot react to such Ether transfers and thus also cannot reject them. This is a design choice of the EVM and Solidity cannot work around it. + + It also means that ``this.balance`` can be higher than the sum of some manual accounting implemented in a contract (i.e. having a counter updated in the fallback function). + :: pragma solidity ^0.4.0; diff --git a/docs/frequently-asked-questions.rst b/docs/frequently-asked-questions.rst index c4de60cd..9edfb4fb 100644 --- a/docs/frequently-asked-questions.rst +++ b/docs/frequently-asked-questions.rst @@ -137,37 +137,6 @@ Enums are not supported by the ABI, they are just supported by Solidity. You have to do the mapping yourself for now, we might provide some help later. -What is the deal with ``function () { ... }`` inside Solidity contracts? How can a function not have a name? -============================================================================================================ - -This function is called "fallback function" and it -is called when someone just sent Ether to the contract without -providing any data or if someone messed up the types so that they tried to -call a function that does not exist. - -The default behaviour (if no fallback function is explicitly given) in -these situations is to throw an exception. - -If the contract is meant to receive Ether with simple transfers, you -should implement the fallback function as - -``function() payable { }`` - -Another use of the fallback function is to e.g. register that your -contract received ether by using an event. - -*Attention*: If you implement the fallback function take care that it uses as -little gas as possible, because ``send()`` will only supply a limited amount. - -Is it possible to pass arguments to the fallback function? -========================================================== - -The fallback function cannot take parameters. - -Under special circumstances, you can send data. If you take care -that none of the other functions is invoked, you can access the data -by ``msg.data``. - Can state variables be initialized in-line? =========================================== -- cgit From ac5fd64c238a88493d24a33cc7bc20313799385f Mon Sep 17 00:00:00 2001 From: Alex Beregszaszi Date: Fri, 1 Sep 2017 19:18:46 +0100 Subject: Mention that different Unicode codepoint can look the same --- docs/introduction-to-smart-contracts.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/introduction-to-smart-contracts.rst b/docs/introduction-to-smart-contracts.rst index 33a8ad10..fd12e97b 100644 --- a/docs/introduction-to-smart-contracts.rst +++ b/docs/introduction-to-smart-contracts.rst @@ -61,6 +61,10 @@ so that only you can alter the number. All identifiers (contract names, function names and variable names) are restricted to the ASCII character set. It is possible to store UTF-8 encoded data in string variables. +.. warning:: + Be careful with using Unicode text as similarly looking (or even identical) can have different + code points and as such will be encoded as a different byte array. + .. index:: ! subcurrency Subcurrency Example -- cgit