diff options
Diffstat (limited to 'SolidityEndToEndTest.cpp')
-rw-r--r-- | SolidityEndToEndTest.cpp | 695 |
1 files changed, 693 insertions, 2 deletions
diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index b79e9c4b..f248a5a0 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -92,6 +92,26 @@ BOOST_AUTO_TEST_CASE(multiple_functions) BOOST_CHECK(callContractFunction("i_am_not_there()", bytes()) == bytes()); } +BOOST_AUTO_TEST_CASE(named_args) +{ + char const* sourceCode = "contract test {\n" + " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n" + " function b() returns (uint r) { r = a({a: 1, b: 2, c: 3}); }\n" + "}\n"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123))); +} + +BOOST_AUTO_TEST_CASE(disorder_named_args) +{ + char const* sourceCode = "contract test {\n" + " function a(uint a, uint b, uint c) returns (uint r) { r = a * 100 + b * 10 + c * 1; }\n" + " function b() returns (uint r) { r = a({c: 3, a: 1, b: 2}); }\n" + "}\n"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("b()", bytes()) == toBigEndian(u256(123))); +} + BOOST_AUTO_TEST_CASE(while_loop) { char const* sourceCode = "contract test {\n" @@ -772,6 +792,94 @@ BOOST_AUTO_TEST_CASE(struct_reference) BOOST_CHECK(callContractFunction("check()") == encodeArgs(true)); } +BOOST_AUTO_TEST_CASE(deleteStruct) +{ + char const* sourceCode = R"( + contract test { + struct topStruct { + nestedStruct nstr; + emptyStruct empty; + uint topValue; + mapping (uint => uint) topMapping; + } + uint toDelete; + topStruct str; + struct nestedStruct { + uint nestedValue; + mapping (uint => bool) nestedMapping; + } + struct emptyStruct{ + } + function test(){ + toDelete = 5; + str.topValue = 1; + str.topMapping[0] = 1; + str.topMapping[1] = 2; + + str.nstr.nestedValue = 2; + str.nstr.nestedMapping[0] = true; + str.nstr.nestedMapping[1] = false; + delete str; + delete toDelete; + } + function getToDelete() returns (uint res){ + res = toDelete; + } + function getTopValue() returns(uint topValue){ + topValue = str.topValue; + } + function getNestedValue() returns(uint nestedValue){ + nestedValue = str.nstr.nestedValue; + } + function getTopMapping(uint index) returns(uint ret) { + ret = str.topMapping[index]; + } + function getNestedMapping(uint index) returns(bool ret) { + return str.nstr.nestedMapping[index]; + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getToDelete()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("getTopValue()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("getNestedValue()") == encodeArgs(0)); + // mapping values should be the same + BOOST_CHECK(callContractFunction("getTopMapping(uint256)", 0) == encodeArgs(1)); + BOOST_CHECK(callContractFunction("getTopMapping(uint256)", 1) == encodeArgs(2)); + BOOST_CHECK(callContractFunction("getNestedMapping(uint256)", 0) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("getNestedMapping(uint256)", 1) == encodeArgs(false)); +} + +BOOST_AUTO_TEST_CASE(deleteLocal) +{ + char const* sourceCode = R"( + contract test { + function delLocal() returns (uint res){ + uint v = 5; + delete v; + res = v; + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(0)); +} + +BOOST_AUTO_TEST_CASE(deleteLocals) +{ + char const* sourceCode = R"( + contract test { + function delLocal() returns (uint res1, uint res2){ + uint v = 5; + uint w = 6; + uint x = 7; + delete v; + res1 = w; + res2 = x; + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(6, 7)); +} + BOOST_AUTO_TEST_CASE(constructor) { char const* sourceCode = "contract test {\n" @@ -794,6 +902,63 @@ BOOST_AUTO_TEST_CASE(constructor) testSolidityAgainstCpp("get(uint256)", get, u256(7)); } +BOOST_AUTO_TEST_CASE(simple_accessor) +{ + char const* sourceCode = "contract test {\n" + " uint256 public data;\n" + " function test() {\n" + " data = 8;\n" + " }\n" + "}\n"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); +} + +BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) +{ + char const* sourceCode = "contract test {\n" + " uint256 public data;\n" + " string6 public name;\n" + " hash public a_hash;\n" + " address public an_address;\n" + " function test() {\n" + " data = 8;\n" + " name = \"Celina\";\n" + " a_hash = sha3(123);\n" + " an_address = address(0x1337);\n" + " super_secret_data = 42;\n" + " }\n" + " uint256 super_secret_data;" + "}\n"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("data()") == encodeArgs(8)); + BOOST_CHECK(callContractFunction("name()") == encodeArgs("Celina")); + BOOST_CHECK(callContractFunction("a_hash()") == encodeArgs(dev::sha3(toBigEndian(u256(123))))); + BOOST_CHECK(callContractFunction("an_address()") == encodeArgs(toBigEndian(u160(0x1337)))); + BOOST_CHECK(callContractFunction("super_secret_data()") == bytes()); +} + +BOOST_AUTO_TEST_CASE(complex_accessors) +{ + char const* sourceCode = "contract test {\n" + " mapping(uint256 => string4) public to_string_map;\n" + " mapping(uint256 => bool) public to_bool_map;\n" + " mapping(uint256 => uint256) public to_uint_map;\n" + " mapping(uint256 => mapping(uint256 => uint256)) public to_multiple_map;\n" + " function test() {\n" + " to_string_map[42] = \"24\";\n" + " to_bool_map[42] = false;\n" + " to_uint_map[42] = 12;\n" + " to_multiple_map[42][23] = 31;\n" + " }\n" + "}\n"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("to_string_map(uint256)", 42) == encodeArgs("24")); + BOOST_CHECK(callContractFunction("to_bool_map(uint256)", 42) == encodeArgs(false)); + BOOST_CHECK(callContractFunction("to_uint_map(uint256)", 42) == encodeArgs(12)); + BOOST_CHECK(callContractFunction("to_multiple_map(uint256,uint256)", 42, 23) == encodeArgs(31)); +} + BOOST_AUTO_TEST_CASE(balance) { char const* sourceCode = "contract test {\n" @@ -852,6 +1017,97 @@ BOOST_AUTO_TEST_CASE(type_conversions_cleanup) 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x00, 0x11, 0x22})); } +BOOST_AUTO_TEST_CASE(convert_string_to_string) +{ + char const* sourceCode = R"( + contract Test { + function pipeTrough(string3 input) returns (string3 ret) { + return string3(input); + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("pipeTrough(string3)", "abc") == encodeArgs("abc")); +} + +BOOST_AUTO_TEST_CASE(convert_hash_to_string_same_size) +{ + char const* sourceCode = R"( + contract Test { + function hashToString(hash h) returns (string32 s) { + return string32(h); + } + })"; + compileAndRun(sourceCode); + u256 a("0x6162630000000000000000000000000000000000000000000000000000000000"); + BOOST_CHECK(callContractFunction("hashToString(hash256)", a) == encodeArgs(a)); +} + +BOOST_AUTO_TEST_CASE(convert_hash_to_string_different_size) +{ + char const* sourceCode = R"( + contract Test { + function hashToString(hash160 h) returns (string20 s) { + return string20(h); + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("hashToString(hash160)", u160("0x6161626361626361626361616263616263616263")) == + encodeArgs(string("aabcabcabcaabcabcabc"))); +} + +BOOST_AUTO_TEST_CASE(convert_string_to_hash_same_size) +{ + char const* sourceCode = R"( + contract Test { + function stringToHash(string32 s) returns (hash h) { + return hash(s); + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("stringToHash(string32)", string("abc2")) == + encodeArgs(u256("0x6162633200000000000000000000000000000000000000000000000000000000"))); +} + +BOOST_AUTO_TEST_CASE(convert_string_to_hash_different_size) +{ + char const* sourceCode = R"( + contract Test { + function stringToHash(string20 s) returns (hash160 h) { + return hash160(s); + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("stringToHash(string20)", string("aabcabcabcaabcabcabc")) == + encodeArgs(u160("0x6161626361626361626361616263616263616263"))); +} + + +BOOST_AUTO_TEST_CASE(convert_string_to_hash_different_min_size) +{ + char const* sourceCode = R"( + contract Test { + function stringToHash(string1 s) returns (hash8 h) { + return hash8(s); + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("stringToHash(string1)", string("a")) == + encodeArgs(u256("0x61"))); +} + + +BOOST_AUTO_TEST_CASE(convert_hash_to_string_different_min_size) +{ + char const* sourceCode = R"( + contract Test { + function HashToString(hash8 h) returns (string1 s) { + return string1(h); + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("HashToString(hash8)", u256("0x61")) == + encodeArgs(string("a"))); +} BOOST_AUTO_TEST_CASE(send_ether) { @@ -1243,6 +1499,7 @@ BOOST_AUTO_TEST_CASE(constructor_arguments) contract Helper { string3 name; bool flag; + function Helper(string3 x, bool f) { name = x; flag = f; @@ -1273,8 +1530,7 @@ BOOST_AUTO_TEST_CASE(functions_called_by_constructor) setName("abc"); } function getName() returns (string3 ret) { return name; } - private: - function setName(string3 _name) { name = _name; } + function setName(string3 _name) private { name = _name; } })"; compileAndRun(sourceCode); BOOST_REQUIRE(callContractFunction("getName()") == encodeArgs("abc")); @@ -1404,6 +1660,441 @@ BOOST_AUTO_TEST_CASE(value_for_constructor) BOOST_REQUIRE(callContractFunction("getBalances()") == encodeArgs(12, 10)); } +BOOST_AUTO_TEST_CASE(virtual_function_calls) +{ + char const* sourceCode = R"( + contract Base { + function f() returns (uint i) { return g(); } + function g() returns (uint i) { return 1; } + } + contract Derived is Base { + function g() returns (uint i) { return 2; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(2)); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(access_base_storage) +{ + char const* sourceCode = R"( + contract Base { + uint dataBase; + function getViaBase() returns (uint i) { return dataBase; } + } + contract Derived is Base { + uint dataDerived; + function setData(uint base, uint derived) returns (bool r) { + dataBase = base; + dataDerived = derived; + return true; + } + function getViaDerived() returns (uint base, uint derived) { + base = dataBase; + derived = dataDerived; + } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("setData(uint256,uint256)", 1, 2) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("getViaBase()") == encodeArgs(1)); + BOOST_CHECK(callContractFunction("getViaDerived()") == encodeArgs(1, 2)); +} + +BOOST_AUTO_TEST_CASE(single_copy_with_multiple_inheritance) +{ + char const* sourceCode = R"( + contract Base { + uint data; + function setData(uint i) { data = i; } + function getViaBase() returns (uint i) { return data; } + } + contract A is Base { function setViaA(uint i) { setData(i); } } + contract B is Base { function getViaB() returns (uint i) { return getViaBase(); } } + contract Derived is Base, B, A { } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getViaB()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("setViaA(uint256)", 23) == encodeArgs()); + BOOST_CHECK(callContractFunction("getViaB()") == encodeArgs(23)); +} + +BOOST_AUTO_TEST_CASE(explicit_base_cass) +{ + char const* sourceCode = R"( + contract BaseBase { function g() returns (uint r) { return 1; } } + contract Base is BaseBase { function g() returns (uint r) { return 2; } } + contract Derived is Base { + function f() returns (uint r) { return BaseBase.g(); } + function g() returns (uint r) { return 3; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(3)); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(base_constructor_arguments) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + } + contract Base is BaseBase(7) { + function Base() { + m_a *= m_a; + } + } + contract Derived is Base() { + function getA() returns (uint r) { return m_a; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(7 * 7)); +} + +BOOST_AUTO_TEST_CASE(function_usage_in_constructor_arguments) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + function g() returns (uint r) { return 2; } + } + contract Base is BaseBase(BaseBase.g()) { + } + contract Derived is Base() { + function getA() returns (uint r) { return m_a; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(virtual_function_usage_in_constructor_arguments) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + function overridden() returns (uint r) { return 1; } + function g() returns (uint r) { return overridden(); } + } + contract Base is BaseBase(BaseBase.g()) { + } + contract Derived is Base() { + function getA() returns (uint r) { return m_a; } + function overridden() returns (uint r) { return 2; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(constructor_argument_overriding) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + } + contract Base is BaseBase(2) { } + contract Derived is BaseBase(3), Base { + function getA() returns (uint r) { return m_a; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(3)); +} + +BOOST_AUTO_TEST_CASE(function_modifier) +{ + char const* sourceCode = R"( + contract C { + function getOne() nonFree returns (uint r) { return 1; } + modifier nonFree { if (msg.value > 0) _ } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getOne()") == encodeArgs(0)); + BOOST_CHECK(callContractFunctionWithValue("getOne()", 1) == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_local_variables) +{ + char const* sourceCode = R"( + contract C { + modifier mod1 { var a = 1; var b = 2; _ } + modifier mod2(bool a) { if (a) return; else _ } + function f(bool a) mod1 mod2(a) returns (uint r) { return 3; } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(0)); + BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(3)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_loop) +{ + char const* sourceCode = R"( + contract C { + modifier repeat(uint count) { for (var i = 0; i < count; ++i) _ } + function f() repeat(10) returns (uint r) { r += 1; } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(10)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_multi_invocation) +{ + char const* sourceCode = R"( + contract C { + modifier repeat(bool twice) { if (twice) _ _ } + function f(bool twice) repeat(twice) returns (uint r) { r += 1; } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(1)); + BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_multi_with_return) +{ + // Here, the explicit return prevents the second execution + char const* sourceCode = R"( + contract C { + modifier repeat(bool twice) { if (twice) _ _ } + function f(bool twice) repeat(twice) returns (uint r) { r += 1; return r; } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f(bool)", false) == encodeArgs(1)); + BOOST_CHECK(callContractFunction("f(bool)", true) == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_overriding) +{ + char const* sourceCode = R"( + contract A { + function f() mod returns (bool r) { return true; } + modifier mod { _ } + } + contract C is A { + modifier mod { } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(false)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_calling_functions_in_creation_context) +{ + char const* sourceCode = R"( + contract A { + uint data; + function A() mod1 { f1(); } + function f1() mod2 { data |= 0x1; } + function f2() { data |= 0x20; } + function f3() { } + modifier mod1 { f2(); _ } + modifier mod2 { f3(); } + function getData() returns (uint r) { return data; } + } + contract C is A { + modifier mod1 { f4(); _ } + function f3() { data |= 0x300; } + function f4() { data |= 0x4000; } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getData()") == encodeArgs(0x4300)); +} + +BOOST_AUTO_TEST_CASE(function_modifier_for_constructor) +{ + char const* sourceCode = R"( + contract A { + uint data; + function A() mod1 { data |= 2; } + modifier mod1 { data |= 1; _ } + function getData() returns (uint r) { return data; } + } + contract C is A { + modifier mod1 { data |= 4; _ } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getData()") == encodeArgs(4 | 2)); +} + +BOOST_AUTO_TEST_CASE(use_std_lib) +{ + char const* sourceCode = R"( + import "mortal"; + contract Icarus is mortal { } + )"; + m_addStandardSources = true; + u256 amount(130); + u160 address(23); + compileAndRun(sourceCode, amount, "Icarus"); + u256 balanceBefore = m_state.balance(m_sender); + BOOST_CHECK(callContractFunction("kill()") == bytes()); + BOOST_CHECK(!m_state.addressHasCode(m_contractAddress)); + BOOST_CHECK(m_state.balance(m_sender) > balanceBefore); +} + +BOOST_AUTO_TEST_CASE(crazy_elementary_typenames_on_stack) +{ + char const* sourceCode = R"( + contract C { + function f() returns (uint r) { + uint; uint; uint; uint; + int x = -7; + var a = uint; + return a(x); + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(-7))); +} + +BOOST_AUTO_TEST_CASE(super) +{ + char const* sourceCode = R"( + contract A { function f() returns (uint r) { return 1; } } + contract B is A { function f() returns (uint r) { return super.f() | 2; } } + contract C is A { function f() returns (uint r) { return super.f() | 4; } } + contract D is B, C { function f() returns (uint r) { return super.f() | 8; } } + )"; + compileAndRun(sourceCode, 0, "D"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 | 2 | 4 | 8)); +} + +BOOST_AUTO_TEST_CASE(super_in_constructor) +{ + char const* sourceCode = R"( + contract A { function f() returns (uint r) { return 1; } } + contract B is A { function f() returns (uint r) { return super.f() | 2; } } + contract C is A { function f() returns (uint r) { return super.f() | 4; } } + contract D is B, C { uint data; function D() { data = super.f() | 8; } function f() returns (uint r) { return data; } } + )"; + compileAndRun(sourceCode, 0, "D"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 | 2 | 4 | 8)); +} + +BOOST_AUTO_TEST_CASE(fallback_function) +{ + char const* sourceCode = R"( + contract A { + uint data; + function() returns (uint r) { data = 1; return 2; } + function getData() returns (uint r) { return data; } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getData()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("") == encodeArgs(2)); + BOOST_CHECK(callContractFunction("getData()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(inherited_fallback_function) +{ + char const* sourceCode = R"( + contract A { + uint data; + function() returns (uint r) { data = 1; return 2; } + function getData() returns (uint r) { return data; } + } + contract B is A {} + )"; + compileAndRun(sourceCode, 0, "B"); + BOOST_CHECK(callContractFunction("getData()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("") == encodeArgs(2)); + BOOST_CHECK(callContractFunction("getData()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(event) +{ + char const* sourceCode = R"( + contract ClientReceipt { + event Deposit(address indexed _from, hash indexed _id, uint _value); + function deposit(hash _id, bool _manually) { + if (_manually) { + hash s = 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20; + log3(msg.value, s, hash32(msg.sender), _id); + } else + Deposit(hash32(msg.sender), _id, msg.value); + } + } + )"; + compileAndRun(sourceCode); + u256 value(18); + u256 id(0x1234); + for (bool manually: {true, false}) + { + callContractFunctionWithValue("deposit(hash256,bool)", value, id, manually); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK_EQUAL(h256(m_logs[0].data), h256(u256(value))); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 3); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,hash256,uint256)"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[1], h256(m_sender)); + BOOST_CHECK_EQUAL(m_logs[0].topics[2], h256(id)); + } +} + +BOOST_AUTO_TEST_CASE(event_no_arguments) +{ + char const* sourceCode = R"( + contract ClientReceipt { + event Deposit; + function deposit() { + Deposit(); + } + } + )"; + compileAndRun(sourceCode); + callContractFunction("deposit()"); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data.empty()); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit()"))); +} + +BOOST_AUTO_TEST_CASE(event_lots_of_data) +{ + char const* sourceCode = R"( + contract ClientReceipt { + event Deposit(address _from, hash _id, uint _value, bool _flag); + function deposit(hash _id) { + Deposit(msg.sender, hash32(_id), msg.value, true); + } + } + )"; + compileAndRun(sourceCode); + u256 value(18); + u256 id(0x1234); + callContractFunctionWithValue("deposit(hash256)", value, id); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data == encodeArgs(m_sender, id, value, true)); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,hash256,uint256,bool)"))); +} + BOOST_AUTO_TEST_SUITE_END() } |