I am confused with the following sentence in the Solidity documentation:
During the execution of the fallback function, the contract can only rely on the “gas stipend” it is passed (2300 gas) being available to it at that time.
My post is a continuation of this one. This post has an answer which says
The 'stipend' applies to internal sends from one smart contract to another. Because send has no way to specify the gas amount, (whereas call does), Solidity imposes a maximum amount of gas (i.e. 2300).
Because the OP's transaction was not an internal contract-to-contract send the 2300 stipend did not apply and the transaction went through.
So, what does "internal" mean?
Suppose I (as an EOA) sign a transaction TX1 and broadcast it. This TX1 executes a function foo
within a contract A which transfers, say ethers, to another contract B.
contract contractA
{
//...
function foo() external
{
//...
contractB.transfer(1 ether);
}
//...
}
Is contractB.transfer(1 ether);
internal call? My guess it is external call because it calls on another contract.
What is the meaning of stipend if transactions always have gas limit set by sender? When, in what cases, does this damn 'stipend' apply?
Could someone please provide a piece of code or describe a scenario when 2300 stipend is not enough, and when we set gasLimit which is enough to execute transfer
function?
Best Answer
Not really. When EOA calls contract A, the gas limit is set in the transaction, this is true. However, when contract A calls contract B, contract A may set limit on how much gas the contract B is allowed to spend. This limit may be lower than the remaining gas contract A has by itself at the moment. In such case, even if call to contract B will run out of gas and thus fail, contract A will still have some gas to handle the situation.
There are several ways how one contract may call another contract, and these ways behave differently:
call
,delegatecall
, orstaticall
that allow explicitly specifying how much gas to called contract will be allowed to spend (though by default these functions allow spending all the gas remaining).transfer
ofsend
that allow called contract to spend at most 2300 gas, and this hardcoded value cannot be changed.Sure. Lets assume the following implementation of contract B:
The contract tries to count how much Ether it ever received via fallback function. This implementation has a problem, as it updates storage variable inside fallback function and such update costs 5000 gas or more. Thus,
transfer
to such contract from another contract will fail.Function
transfer
has hardcoded gas limit of 2300 which cannot be changed. However here is an example of a contract whose fallback function fits into this harsh limit and yet does something useful: