Merge pull request #2854 from ethereum/docs-faq

[WIP] Move content from FAQ to proper places
This commit is contained in:
chriseth 2017-09-04 18:51:49 +02:00 committed by GitHub
commit 8283f83653
5 changed files with 60 additions and 93 deletions

View File

@ -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;

View File

@ -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``?
============================================
@ -155,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?
===========================================
@ -230,13 +181,6 @@ Better use ``for (uint i = 0; i < a.length...``
See `struct_and_for_loop_tester.sol <https://github.com/fivedogit/solidity-baby-steps/blob/master/contracts/65_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)?
==================================================================================================
@ -441,23 +385,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?
====================================================================
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
******************
@ -503,23 +430,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``?
======================================================================

View File

@ -57,6 +57,14 @@ 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.
.. 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

View File

@ -127,6 +127,24 @@ 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");
.. 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.
@ -169,6 +187,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
----------------------------

View File

@ -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