14

Simply sending Ether to a contract, will run the contract's code. In Solidity, this code maps to what it calls the fallback function.

How much work can be done in a fallback function?

17

The fallback function can do as much computation as how much gas it gets.

There are 2 cases (basically recipient.send and recipient.call.value()) and case 2 has security implications and is a key part of how theDAO was attacked and exploited on June 17 2016.

Case 1: 2300 gas

A recipient contract's fallback function only gets a 2300 gas stipend if it was invoked with recipient.transfer or recipient.send. This is the same as an external account paying recipient with web3.eth.sendTransaction({to:recipient, gas:21000, ...}).

The last part of an Ethereum blog post explains:

If you want your contract to receive Ether, you have to make its fallback function cheap. It can only use 2300 gas which neither allows any storage write nor function calls that send along Ether. Basically the only thing you should do inside the fallback function is log an event so that external processes can react on the fact.

Examples of an external process include web3.js filters and watches.

Case 2: As much gas as it gets, watch out for security

recipient.call.value(...) (and using related functions like .callcode, .delegatecall) will provide the fallback function with virtually[1] as much gas as the caller has remaining.

To obtain the same effects (2300 gas stipend) and security as Case 1, callers must explicitly limit the gas to zero when invoking the recipient by: recipient.call.gas(0).value(...)

(theDAO did not limit the gas and suffered a reentrant attack on June 17 2016.)


Footnotes

[1] Explanation of why a fallback function gets almost all, but not all of the gas. chriseth (Solidity author) said:

This is one of the quirky places of the EVM. You cannot just say "send all my gas along with the call", you always have to give an explicit number. We do have the GAS opcode which gives us the amount of gas still available, but the problem is that performing the call itself also costs some gas, so we have to subtract the amount of gas the call costs from the value provided by GAS, and we also have to subtract the amount of gas it costs to perform the subtraction...

  • This requires additional information just for clarification (without clicking through). Fallback functions can do any amount of work. The reason why this is recommended is that send() specifically only has access to the gas stipend (it doesn't forward gas), of 2300 gas. And when using send(), it will trigger the fallback function since to no function signature is specified when send() is done. – Simon de la Rouviere Jun 18 '16 at 13:43
  • I was just about to update this independently after realizing the answer was far from complete. – eth Jun 18 '16 at 20:41
  • @eth: thanks for your answer. I have tested with a contract have a fallback function which updated a state variable (cost 5000 gas). I sent an amount of ether to this contract with 100000 gas limit. Transaction is valid. As you explained, it should be fail?. Why? – Luan Do The Jan 9 '17 at 6:24
  • 1
    @LuanDoThe just want to link to your question and answer: ethereum.stackexchange.com/questions/11237/… Basically we both have the same misunderstanding of the document, or the doc doesn't express it clearly. – nrek Dec 2 '17 at 8:28
  • 1
    @K._ No, the former sends 2300 more gas. – eth Dec 5 '17 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.