Skip to content

Commit

Permalink
Clarify some subtleties of the fallback function
Browse files Browse the repository at this point in the history
  • Loading branch information
axic committed Sep 1, 2017
1 parent cbd7299 commit 88bce87
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 34 deletions.
21 changes: 18 additions & 3 deletions docs/contracts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -556,13 +559,25 @@ 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
throw an exception, sending back the Ether (this was different
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;
Expand Down
31 changes: 0 additions & 31 deletions docs/frequently-asked-questions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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?
===========================================

Expand Down

0 comments on commit 88bce87

Please sign in to comment.