BREAKING: Implement delegatecall and make default for library calls.

This commit is contained in:
chriseth
2016-03-11 17:49:32 +01:00
parent 60a21c6487
commit e5514becb8
10 changed files with 122 additions and 45 deletions
+1 -1
View File
@@ -59,7 +59,7 @@ public:
void testCreationTimeGas(string const& _sourceCode)
{
EVMSchedule schedule;// TODO: make relevant to supposed context.
EVMSchedule schedule;
compileAndRun(_sourceCode);
auto state = make_shared<KnownState>();
+56
View File
@@ -2890,6 +2890,62 @@ BOOST_AUTO_TEST_CASE(generic_callcode)
BOOST_CHECK_EQUAL(m_state.balance(c_senderAddress), 50);
}
BOOST_AUTO_TEST_CASE(generic_delegatecall)
{
char const* sourceCode = R"**(
contract receiver {
uint public received;
address public sender;
uint public value;
function receive(uint256 x) { received = x; sender = msg.sender; value = msg.value; }
}
contract sender {
uint public received;
address public sender;
uint public value;
function doSend(address rec)
{
bytes4 signature = bytes4(bytes32(sha3("receive(uint256)")));
rec.delegatecall(signature, 23);
}
}
)**";
compileAndRun(sourceCode, 0, "receiver");
u160 const c_receiverAddress = m_contractAddress;
compileAndRun(sourceCode, 50, "sender");
u160 const c_senderAddress = m_contractAddress;
BOOST_CHECK(m_sender != c_senderAddress); // just for sanity
BOOST_CHECK(callContractFunctionWithValue("doSend(address)", 11, c_receiverAddress) == encodeArgs());
BOOST_CHECK(callContractFunction("received()") == encodeArgs(u256(23)));
BOOST_CHECK(callContractFunction("sender()") == encodeArgs(u160(m_sender)));
BOOST_CHECK(callContractFunction("value()") == encodeArgs(u256(11)));
m_contractAddress = c_receiverAddress;
BOOST_CHECK(callContractFunction("received()") == encodeArgs(u256(0)));
BOOST_CHECK(callContractFunction("sender()") == encodeArgs(u256(0)));
BOOST_CHECK(callContractFunction("value()") == encodeArgs(u256(0)));
BOOST_CHECK(m_state.storage(c_receiverAddress).empty());
BOOST_CHECK(!m_state.storage(c_senderAddress).empty());
BOOST_CHECK_EQUAL(m_state.balance(c_receiverAddress), 0);
BOOST_CHECK_EQUAL(m_state.balance(c_senderAddress), 50 + 11);
}
BOOST_AUTO_TEST_CASE(library_call_in_homestead)
{
char const* sourceCode = R"(
library Lib { function m() returns (address) { return msg.sender; } }
contract Test {
address public sender;
function f() {
sender = Lib.m();
}
}
)";
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}});
BOOST_CHECK(callContractFunction("f()") == encodeArgs());
BOOST_CHECK(callContractFunction("sender()") == encodeArgs(u160(m_sender)));
}
BOOST_AUTO_TEST_CASE(store_bytes)
{
// this test just checks that the copy loop does not mess up the stack
@@ -3232,6 +3232,19 @@ BOOST_AUTO_TEST_CASE(int10abc_is_identifier)
BOOST_CHECK(success(text));
}
BOOST_AUTO_TEST_CASE(library_functions_do_not_have_value)
{
char const* text = R"(
library L { function l() {} }
contract test {
function f() {
L.l.value;
}
}
)";
BOOST_CHECK(!success(text));
}
BOOST_AUTO_TEST_SUITE_END()
}