aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-05-31 20:13:02 +0800
committerDenton Liu <liu.denton+github@gmail.com>2016-06-02 01:22:15 +0800
commit84a8c0c008acf80a70c60dbfc0f5c3666abcd676 (patch)
tree16c8cabaee18151c5432afb2d284cbccfec25705 /docs
parent9da7a4c17c2245e869475d031cb23587c33f5045 (diff)
downloaddexon-solidity-84a8c0c008acf80a70c60dbfc0f5c3666abcd676.tar.gz
dexon-solidity-84a8c0c008acf80a70c60dbfc0f5c3666abcd676.tar.zst
dexon-solidity-84a8c0c008acf80a70c60dbfc0f5c3666abcd676.zip
Document some pitfalls in connection with "send".
Diffstat (limited to 'docs')
-rw-r--r--docs/miscellaneous.rst18
-rw-r--r--docs/types.rst6
2 files changed, 24 insertions, 0 deletions
diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst
index b7a4bb7a..504c4e0e 100644
--- a/docs/miscellaneous.rst
+++ b/docs/miscellaneous.rst
@@ -148,6 +148,24 @@ Pitfalls
Unfortunately, there are some subtleties the compiler does not yet warn you about.
- In ``for (var i = 0; i < arrayName.length; i++) { ... }``, the type of ``i`` will be ``uint8``, because this is the smallest type that is required to hold the value ``0``. If the array has more than 255 elements, the loop will not terminate.
+- If a contract receives Ether (without a function being called), the fallback function is executed. The contract can only rely
+ on the "gas stipend" (2300 gas) being available to it at that time. This stipend is not enough to access storage in any way.
+ To be sure that your contract can receive Ether in that way, check the gas requirements of the fallback function.
+- If you want to send ether using ``address.send``, there are certain details to be aware of:
+ 1. If the recipient is a contract, it causes its fallback function to be executed which can in turn call back into the sending contract
+ 2. Sending Ether can fail due to the call depth going above 1024. Since the caller is in total control of the call
+ depth, they can force the transfer to fail, so make sure to always check the return value of ``send``. Better yet,
+ write your contract using a pattern where the recipient can withdraw Ether instead.
+ 2. Sending Ether can also fail because the recipient goes out of gas (either explicitly by using ``throw`` or
+ because the operation is just too expensive). If the return value of ``send`` is checked, this might provide a
+ means for the recipient to block progress in the sending contract. Again, the best practise here is to use
+ a "withdraw" pattern instead of a "send" pattern.
+- Loops that do not have a fixed number of iterations, e.g. loops that depends on storage values, have to be used carefully:
+ Due to the block gas limit, transactions can only consume a certain amount of gas. Either explicitly or just due to
+ normal operation, the number of iterations in a loop can grow beyond the block gas limit, which can cause the complete
+ contract to be stalled at a certain point. This does not apply at full extent to ``constant`` functions that are only executed
+ to read data from the blockchain. Still, such functions may be called by other contracts as part of on-chain operations
+ and stall those. Please be explicit about such cases in the documentation of your contracts.
**********
Cheatsheet
diff --git a/docs/types.rst b/docs/types.rst
index 2cd3654b..6d4e928c 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -86,6 +86,12 @@ and to send Ether (in units of wei) to an address using the ``send`` function:
.. note::
If ``x`` is a contract address, its code (more specifically: its fallback function, if present) will be executed together with the ``send`` call (this is a limitation of the EVM and cannot be prevented). If that execution runs out of gas or fails in any way, the Ether transfer will be reverted. In this case, ``send`` returns ``false``.
+.. warning::
+ There are some dangers in using ``send``: The transfer fails if the call stack depth is at 1023
+ (this can always be forced by the caller) and it also fails if the recipient runs out of gas. So in order
+ to make safe Ether transfers, always check the return value of ``send`` or even better:
+ Use a pattern where the recipient withdraws the money.
+
* ``call``, ``callcode`` and ``delegatecall``
Furthermore, to interface with contracts that do not adhere to the ABI,