mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
commit
79f9a04236
@ -447,6 +447,12 @@ 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.
|
||||
|
||||
.. warning::
|
||||
Contracts that receive Ether 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.
|
||||
|
||||
::
|
||||
|
||||
contract Test {
|
||||
|
@ -103,7 +103,9 @@ and stall those. Please be explicit about such cases in the documentation of you
|
||||
Sending and Receiving Ether
|
||||
===========================
|
||||
|
||||
- If a contract receives Ether (without a function being called), the fallback function is executed. The contract can only rely
|
||||
- If a contract receives Ether (without a function being called), the fallback function is executed.
|
||||
If it does not have a fallback function, the Ether will be rejected (by throwing an exception).
|
||||
During the execution of the fallback function, 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
|
||||
(for example in the "details" section in browser-solidity).
|
||||
|
@ -92,6 +92,8 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
|
||||
else
|
||||
{
|
||||
fallbackFunction = function;
|
||||
if (_contract.isLibrary())
|
||||
typeError(fallbackFunction->location(), "Libraries cannot have fallback functions.");
|
||||
if (!fallbackFunction->parameters().empty())
|
||||
typeError(fallbackFunction->parameterList().location(), "Fallback function cannot take parameters.");
|
||||
if (!fallbackFunction->returnParameters().empty())
|
||||
|
@ -247,11 +247,8 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac
|
||||
m_context << returnTag;
|
||||
appendReturnValuePacker(FunctionType(*fallback).returnParameterTypes(), _contract.isLibrary());
|
||||
}
|
||||
else if (_contract.isLibrary())
|
||||
// Reject invalid library calls and ether sent to a library.
|
||||
m_context.appendJumpTo(m_context.errorTag());
|
||||
else
|
||||
m_context << Instruction::STOP; // function not found
|
||||
m_context.appendJumpTo(m_context.errorTag());
|
||||
|
||||
for (auto const& it: interfaceFunctions)
|
||||
{
|
||||
|
@ -114,7 +114,7 @@ BOOST_AUTO_TEST_CASE(location_test)
|
||||
shared_ptr<string const> n = make_shared<string>("source");
|
||||
AssemblyItems items = compileContract(sourceCode);
|
||||
vector<SourceLocation> locations =
|
||||
vector<SourceLocation>(17, SourceLocation(2, 75, n)) +
|
||||
vector<SourceLocation>(18, SourceLocation(2, 75, n)) +
|
||||
vector<SourceLocation>(28, SourceLocation(20, 72, n)) +
|
||||
vector<SourceLocation>{SourceLocation(42, 51, n), SourceLocation(65, 67, n)} +
|
||||
vector<SourceLocation>(4, SourceLocation(58, 67, n)) +
|
||||
|
@ -2053,6 +2053,7 @@ BOOST_AUTO_TEST_CASE(contracts_as_addresses)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract helper {
|
||||
function() { } // can receive ether
|
||||
}
|
||||
contract test {
|
||||
helper h;
|
||||
@ -2540,6 +2541,19 @@ BOOST_AUTO_TEST_CASE(inherited_fallback_function)
|
||||
BOOST_CHECK(callContractFunction("getData()") == encodeArgs(1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(default_fallback_throws)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract A {
|
||||
function f() returns (bool) {
|
||||
return this.call();
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("f()") == encodeArgs(0));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(event)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -5943,6 +5957,7 @@ BOOST_AUTO_TEST_CASE(reject_ether_sent_to_library)
|
||||
function f(address x) returns (bool) {
|
||||
return x.send(1);
|
||||
}
|
||||
function () {}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "lib");
|
||||
|
@ -1102,6 +1102,16 @@ BOOST_AUTO_TEST_CASE(fallback_function_with_arguments)
|
||||
BOOST_CHECK(expectError(text) == Error::Type::TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(fallback_function_in_library)
|
||||
{
|
||||
char const* text = R"(
|
||||
library C {
|
||||
function() {}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK(expectError(text) == Error::Type::TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(fallback_function_with_return_parameters)
|
||||
{
|
||||
char const* text = R"(
|
||||
|
Loading…
Reference in New Issue
Block a user