Skip to content

Commit

Permalink
Document some pitfalls in connection with "send".
Browse files Browse the repository at this point in the history
  • Loading branch information
chriseth committed May 31, 2016
1 parent 4be92c0 commit 9474594
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
12 changes: 12 additions & 0 deletions docs/miscellaneous.rst
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,18 @@ 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.

**********
Cheatsheet
Expand Down
6 changes: 6 additions & 0 deletions docs/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,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,
Expand Down

0 comments on commit 9474594

Please sign in to comment.