aboutsummaryrefslogtreecommitdiffstats
path: root/SolidityEndToEndTest.cpp
diff options
context:
space:
mode:
authorCJentzsch <jentzsch.software@gmail.com>2015-02-23 19:28:42 +0800
committerCJentzsch <jentzsch.software@gmail.com>2015-02-23 19:28:42 +0800
commitcd9262badfd1cd7425469d0eba94a5109c20960a (patch)
tree05cd1f06ecbd25ca6220cb3ef6c4948e25c4c3d1 /SolidityEndToEndTest.cpp
parent154d439cf8530528fc362f99461f9648ce3b5f45 (diff)
parent9a764055ac69ceb9e5a16c4c930730255db13236 (diff)
downloaddexon-solidity-cd9262badfd1cd7425469d0eba94a5109c20960a.tar
dexon-solidity-cd9262badfd1cd7425469d0eba94a5109c20960a.tar.gz
dexon-solidity-cd9262badfd1cd7425469d0eba94a5109c20960a.tar.bz2
dexon-solidity-cd9262badfd1cd7425469d0eba94a5109c20960a.tar.lz
dexon-solidity-cd9262badfd1cd7425469d0eba94a5109c20960a.tar.xz
dexon-solidity-cd9262badfd1cd7425469d0eba94a5109c20960a.tar.zst
dexon-solidity-cd9262badfd1cd7425469d0eba94a5109c20960a.zip
Merge remote-tracking branch 'upstream/develop' into addTests
Conflicts: test/CMakeLists.txt test/ttTransactionTestFiller.json
Diffstat (limited to 'SolidityEndToEndTest.cpp')
-rw-r--r--SolidityEndToEndTest.cpp580
1 files changed, 576 insertions, 4 deletions
diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp
index f248a5a0..20bc8159 100644
--- a/SolidityEndToEndTest.cpp
+++ b/SolidityEndToEndTest.cpp
@@ -56,6 +56,36 @@ BOOST_AUTO_TEST_CASE(empty_contract)
BOOST_CHECK(callContractFunction("i_am_not_there()", bytes()).empty());
}
+BOOST_AUTO_TEST_CASE(exp_operator)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) returns(uint d) { return 2 ** a; }
+ })";
+ compileAndRun(sourceCode);
+ testSolidityAgainstCppOnRange("f(uint256)", [](u256 const& a) -> u256 { return u256(1 << a.convert_to<int>()); }, 0, 16);
+}
+
+BOOST_AUTO_TEST_CASE(exp_operator_const)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f() returns(uint d) { return 2 ** 3; }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(8)));
+}
+
+BOOST_AUTO_TEST_CASE(exp_operator_const_signed)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f() returns(int d) { return (-2) ** 3; }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f()", bytes()) == toBigEndian(u256(-8)));
+}
+
BOOST_AUTO_TEST_CASE(recursive_calls)
{
char const* sourceCode = "contract test {\n"
@@ -576,7 +606,7 @@ BOOST_AUTO_TEST_CASE(simple_mapping)
" }\n"
"}";
compileAndRun(sourceCode);
-
+
BOOST_CHECK(callContractFunction("get(uint8)", byte(0)) == encodeArgs(byte(0x00)));
BOOST_CHECK(callContractFunction("get(uint8)", byte(0x01)) == encodeArgs(byte(0x00)));
BOOST_CHECK(callContractFunction("get(uint8)", byte(0xa7)) == encodeArgs(byte(0x00)));
@@ -638,7 +668,7 @@ BOOST_AUTO_TEST_CASE(mapping_state)
testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
- // voting without vote right shourd be rejected
+ // voting without vote right should be rejected
testSolidityAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testSolidityAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
@@ -933,7 +963,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors)
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("a_hash()") == encodeArgs(dev::sha3(bytes(1, 0x7b))));
BOOST_CHECK(callContractFunction("an_address()") == encodeArgs(toBigEndian(u160(0x1337))));
BOOST_CHECK(callContractFunction("super_secret_data()") == bytes());
}
@@ -959,6 +989,24 @@ BOOST_AUTO_TEST_CASE(complex_accessors)
BOOST_CHECK(callContractFunction("to_multiple_map(uint256,uint256)", 42, 23) == encodeArgs(31));
}
+BOOST_AUTO_TEST_CASE(struct_accessor)
+{
+ char const* sourceCode = R"(
+ contract test {
+ struct Data { uint a; uint8 b; mapping(uint => uint) c; bool d; }
+ mapping(uint => Data) public data;
+ function test() {
+ data[7].a = 1;
+ data[7].b = 2;
+ data[7].c[0] = 3;
+ data[7].d = true;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("data(uint256)", 7) == encodeArgs(1, 2, true));
+}
+
BOOST_AUTO_TEST_CASE(balance)
{
char const* sourceCode = "contract test {\n"
@@ -1621,7 +1669,6 @@ BOOST_AUTO_TEST_CASE(value_insane)
function test() { h = new helper(); }
function sendAmount(uint amount) returns (uint256 bal) {
var x1 = h.getBalance.value;
- uint someStackElement = 20;
var x2 = x1(amount).gas;
var x3 = x2(1000).value;
return x3(amount + 3)();// overwrite value
@@ -2095,6 +2142,531 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data)
BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,hash256,uint256,bool)")));
}
+BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint, uint k) returns(uint ret_k, uint ret_g){
+ uint g = 8;
+ ret_k = k;
+ ret_g = g;
+ }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) != encodeArgs(5, 8));
+ BOOST_CHECK(callContractFunction("f(uint256,uint256)", 5, 9) == encodeArgs(9, 8));
+}
+
+BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint k) returns(uint){
+ return k;
+ }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("f(uint256)", 9) == encodeArgs(9));
+}
+
+BOOST_AUTO_TEST_CASE(sha3_multiple_arguments)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function foo(uint a, uint b, uint c) returns (hash d)
+ {
+ d = sha3(a, b, c);
+ }
+ })";
+ compileAndRun(sourceCode);
+
+ BOOST_CHECK(callContractFunction("foo(uint256,uint256,uint256)", 10, 12, 13) == encodeArgs(
+ dev::sha3(
+ toBigEndian(u256(10)) +
+ toBigEndian(u256(12)) +
+ toBigEndian(u256(13)))));
+}
+
+BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_numeric_literals)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function foo(uint a, uint16 b) returns (hash d)
+ {
+ d = sha3(a, b, 145);
+ }
+ })";
+ compileAndRun(sourceCode);
+
+ BOOST_CHECK(callContractFunction("foo(uint256,uint16)", 10, 12) == encodeArgs(
+ dev::sha3(
+ toBigEndian(u256(10)) +
+ bytes{0x0, 0xc} +
+ bytes(1, 0x91))));
+}
+
+BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function foo() returns (hash d)
+ {
+ d = sha3("foo");
+ }
+ function bar(uint a, uint16 b) returns (hash d)
+ {
+ d = sha3(a, b, 145, "foo");
+ }
+ })";
+ compileAndRun(sourceCode);
+
+ BOOST_CHECK(callContractFunction("foo()") == encodeArgs(dev::sha3("foo")));
+
+ BOOST_CHECK(callContractFunction("bar(uint256,uint16)", 10, 12) == encodeArgs(
+ dev::sha3(
+ toBigEndian(u256(10)) +
+ bytes{0x0, 0xc} +
+ bytes(1, 0x91) +
+ bytes{0x66, 0x6f, 0x6f})));
+}
+
+BOOST_AUTO_TEST_CASE(generic_call)
+{
+ char const* sourceCode = R"**(
+ contract receiver {
+ uint public received;
+ function receive(uint256 x) { received = x; }
+ }
+ contract sender {
+ function doSend(address rec) returns (uint d)
+ {
+ string4 signature = string4(string32(sha3("receive(uint256)")));
+ rec.call.value(2)(signature, 23);
+ return receiver(rec).received();
+ }
+ }
+ )**";
+ compileAndRun(sourceCode, 0, "receiver");
+ u160 const c_receiverAddress = m_contractAddress;
+ compileAndRun(sourceCode, 50, "sender");
+ BOOST_REQUIRE(callContractFunction("doSend(address)", c_receiverAddress) == encodeArgs(23));
+ BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2);
+}
+
+BOOST_AUTO_TEST_CASE(store_bytes)
+{
+ // this test just checks that the copy loop does not mess up the stack
+ char const* sourceCode = R"(
+ contract C {
+ function save() returns (uint r) {
+ r = 23;
+ savedData = msg.data;
+ r = 24;
+ }
+ bytes savedData;
+ }
+ )";
+ compileAndRun(sourceCode);
+ // empty copy loop
+ BOOST_CHECK(callContractFunction("save()") == encodeArgs(24));
+ BOOST_CHECK(callContractFunction("save()", "abcdefg") == encodeArgs(24));
+}
+
+BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function() returns (hash) {
+ return sha3("abc", msg.data);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ bytes calldata1 = bytes(61, 0x22) + bytes(12, 0x12);
+ sendMessage(calldata1, false);
+ BOOST_CHECK(m_output == encodeArgs(dev::sha3(bytes{'a', 'b', 'c'} + calldata1)));
+}
+
+BOOST_AUTO_TEST_CASE(call_forward_bytes)
+{
+ char const* sourceCode = R"(
+ contract receiver {
+ uint public received;
+ function receive(uint x) { received += x + 1; }
+ function() { received = 0x80; }
+ }
+ contract sender {
+ function sender() { rec = new receiver(); }
+ function() { savedData = msg.data; }
+ function forward() returns (bool) { rec.call(savedData); return true; }
+ function clear() returns (bool) { delete savedData; return true; }
+ function val() returns (uint) { return rec.received(); }
+ receiver rec;
+ bytes savedData;
+ }
+ )";
+ compileAndRun(sourceCode, 0, "sender");
+ BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes());
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(0));
+ BOOST_CHECK(callContractFunction("forward()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(8));
+ BOOST_CHECK(callContractFunction("clear()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(8));
+ BOOST_CHECK(callContractFunction("forward()") == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80));
+}
+
+BOOST_AUTO_TEST_CASE(copying_bytes_multiassign)
+{
+ char const* sourceCode = R"(
+ contract receiver {
+ uint public received;
+ function receive(uint x) { received += x + 1; }
+ function() { received = 0x80; }
+ }
+ contract sender {
+ function sender() { rec = new receiver(); }
+ function() { savedData1 = savedData2 = msg.data; }
+ function forward(bool selector) returns (bool) {
+ if (selector) { rec.call(savedData1); delete savedData1; }
+ else { rec.call(savedData2); delete savedData2; }
+ return true;
+ }
+ function val() returns (uint) { return rec.received(); }
+ receiver rec;
+ bytes savedData1;
+ bytes savedData2;
+ }
+ )";
+ compileAndRun(sourceCode, 0, "sender");
+ BOOST_CHECK(callContractFunction("receive(uint256)", 7) == bytes());
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(0));
+ BOOST_CHECK(callContractFunction("forward(bool)", true) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(8));
+ BOOST_CHECK(callContractFunction("forward(bool)", false) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(16));
+ BOOST_CHECK(callContractFunction("forward(bool)", true) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("val()") == encodeArgs(0x80));
+}
+
+BOOST_AUTO_TEST_CASE(delete_removes_bytes_data)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function() { data = msg.data; }
+ function del() returns (bool) { delete data; return true; }
+ bytes data;
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("---", 7) == bytes());
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ BOOST_CHECK(callContractFunction("del()", 7) == encodeArgs(true));
+ BOOST_CHECK(m_state.storage(m_contractAddress).empty());
+}
+
+BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function set() returns (bool) { data = msg.data; return true; }
+ function() { data = msg.data; }
+ bytes data;
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5) == encodeArgs(true));
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ sendMessage(bytes(), false);
+ BOOST_CHECK(m_output == bytes());
+ BOOST_CHECK(m_state.storage(m_contractAddress).empty());
+}
+
+BOOST_AUTO_TEST_CASE(copy_removes_bytes_data)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function set() returns (bool) { data1 = msg.data; return true; }
+ function reset() returns (bool) { data1 = data2; return true; }
+ bytes data1;
+ bytes data2;
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5) == encodeArgs(true));
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ BOOST_CHECK(callContractFunction("reset()") == encodeArgs(true));
+ BOOST_CHECK(m_state.storage(m_contractAddress).empty());
+}
+
+BOOST_AUTO_TEST_CASE(bytes_inside_mappings)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function set(uint key) returns (bool) { data[key] = msg.data; return true; }
+ function copy(uint from, uint to) returns (bool) { data[to] = data[from]; return true; }
+ mapping(uint => bytes) data;
+ }
+ )";
+ compileAndRun(sourceCode);
+ // store a short byte array at 1 and a longer one at 2
+ BOOST_CHECK(callContractFunction("set(uint256)", 1, 2) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("set(uint256)", 2, 2, 3, 4, 5) == encodeArgs(true));
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ // copy shorter to longer
+ BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 1, 2) == encodeArgs(true));
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ // copy empty to both
+ BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 99, 1) == encodeArgs(true));
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 99, 2) == encodeArgs(true));
+ BOOST_CHECK(m_state.storage(m_contractAddress).empty());
+}
+
+BOOST_AUTO_TEST_CASE(bytes_length_member)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function set() returns (bool) { data = msg.data; return true; }
+ function getLength() returns (uint) { return data.length; }
+ bytes data;
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("getLength()") == encodeArgs(0));
+ BOOST_CHECK(callContractFunction("set()", 1, 2) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("getLength()") == encodeArgs(4+32+32));
+}
+
+BOOST_AUTO_TEST_CASE(struct_copy)
+{
+ char const* sourceCode = R"(
+ contract c {
+ struct Nested { uint x; uint y; }
+ struct Struct { uint a; mapping(uint => Struct) b; Nested nested; uint c; }
+ mapping(uint => Struct) public data;
+ function set(uint k) returns (bool) {
+ data[k].a = 1;
+ data[k].nested.x = 3;
+ data[k].nested.y = 4;
+ data[k].c = 2;
+ return true;
+ }
+ function copy(uint from, uint to) returns (bool) {
+ data[to] = data[from];
+ return true;
+ }
+ function retrieve(uint k) returns (uint a, uint x, uint y, uint c)
+ {
+ a = data[k].a;
+ x = data[k].nested.x;
+ y = data[k].nested.y;
+ c = data[k].c;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("set(uint256)", 7) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("retrieve(uint256)", 7) == encodeArgs(1, 3, 4, 2));
+ BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 7, 8) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("retrieve(uint256)", 7) == encodeArgs(1, 3, 4, 2));
+ BOOST_CHECK(callContractFunction("retrieve(uint256)", 8) == encodeArgs(1, 3, 4, 2));
+ BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 0, 7) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("retrieve(uint256)", 7) == encodeArgs(0, 0, 0, 0));
+ BOOST_CHECK(callContractFunction("retrieve(uint256)", 8) == encodeArgs(1, 3, 4, 2));
+ BOOST_CHECK(callContractFunction("copy(uint256,uint256)", 7, 8) == encodeArgs(true));
+ BOOST_CHECK(callContractFunction("retrieve(uint256)", 8) == encodeArgs(0, 0, 0, 0));
+}
+
+BOOST_AUTO_TEST_CASE(struct_containing_bytes_copy_and_delete)
+{
+ char const* sourceCode = R"(
+ contract c {
+ struct Struct { uint a; bytes data; uint b; }
+ Struct data1;
+ Struct data2;
+ function set(uint _a, bytes _data, uint _b) external returns (bool) {
+ data1.a = _a;
+ data1.b = _b;
+ data1.data = _data;
+ return true;
+ }
+ function copy() returns (bool) {
+ data1 = data2;
+ return true;
+ }
+ function del() returns (bool) {
+ delete data1;
+ return true;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ string data = "123456789012345678901234567890123";
+ BOOST_CHECK(m_state.storage(m_contractAddress).empty());
+ BOOST_CHECK(callContractFunction("set(uint256,bytes,uint256)", u256(data.length()), 12, data, 13) == encodeArgs(true));
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ BOOST_CHECK(callContractFunction("copy()") == encodeArgs(true));
+ BOOST_CHECK(m_state.storage(m_contractAddress).empty());
+ BOOST_CHECK(callContractFunction("set(uint256,bytes,uint256)", u256(data.length()), 12, data, 13) == encodeArgs(true));
+ BOOST_CHECK(!m_state.storage(m_contractAddress).empty());
+ BOOST_CHECK(callContractFunction("del()") == encodeArgs(true));
+ BOOST_CHECK(m_state.storage(m_contractAddress).empty());
+}
+
+BOOST_AUTO_TEST_CASE(struct_copy_via_local)
+{
+ char const* sourceCode = R"(
+ contract c {
+ struct Struct { uint a; uint b; }
+ Struct data1;
+ Struct data2;
+ function test() returns (bool) {
+ data1.a = 1;
+ data1.b = 2;
+ var x = data1;
+ data2 = x;
+ return data2.a == data1.a && data2.b == data1.b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(true));
+}
+
+BOOST_AUTO_TEST_CASE(using_enums)
+{
+ char const* sourceCode = R"(
+ contract test {
+ enum ActionChoices { GoLeft, GoRight, GoStraight, Sit }
+ function test()
+ {
+ choices = ActionChoices.GoStraight;
+ }
+ function getChoice() returns (uint d)
+ {
+ d = uint256(choices);
+ }
+ ActionChoices choices;
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("getChoice()") == encodeArgs(2));
+}
+
+BOOST_AUTO_TEST_CASE(constructing_enums_from_ints)
+{
+ char const* sourceCode = R"(
+ contract c {
+ enum Truth { False, True }
+ function test() returns (uint)
+ {
+ return uint(Truth(uint8(0x701)));
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test()") == encodeArgs(1));
+}
+
+BOOST_AUTO_TEST_CASE(inline_member_init)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function test(){
+ m_b = 6;
+ m_c = 8;
+ }
+ uint m_a = 5;
+ uint m_b;
+ uint m_c = 7;
+ function get() returns (uint a, uint b, uint c){
+ a = m_a;
+ b = m_b;
+ c = m_c;
+ }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("get()") == encodeArgs(5, 6, 8));
+}
+
+BOOST_AUTO_TEST_CASE(inline_member_init_inheritence)
+{
+ char const* sourceCode = R"(
+ contract Base {
+ function Base(){}
+ uint m_base = 5;
+ function getBMember() returns (uint i) { return m_base; }
+ }
+ contract Derived is Base {
+ function Derived(){}
+ uint m_derived = 6;
+ function getDMember() returns (uint i) { return m_derived; }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("getBMember()") == encodeArgs(5));
+ BOOST_CHECK(callContractFunction("getDMember()") == encodeArgs(6));
+}
+
+BOOST_AUTO_TEST_CASE(inline_member_init_inheritence_without_constructor)
+{
+ char const* sourceCode = R"(
+ contract Base {
+ uint m_base = 5;
+ function getBMember() returns (uint i) { return m_base; }
+ }
+ contract Derived is Base {
+ uint m_derived = 6;
+ function getDMember() returns (uint i) { return m_derived; }
+ })";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("getBMember()") == encodeArgs(5));
+ BOOST_CHECK(callContractFunction("getDMember()") == encodeArgs(6));
+}
+
+BOOST_AUTO_TEST_CASE(external_function)
+{
+ char const* sourceCode = R"(
+ contract c {
+ function f(uint a) returns (uint) { return a; }
+ function test(uint a, uint b) external returns (uint r_a, uint r_b) {
+ r_a = f(a + 7);
+ r_b = b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("test(uint256,uint256)", 2, 3) == encodeArgs(2+7, 3));
+}
+
+BOOST_AUTO_TEST_CASE(bytes_in_arguments)
+{
+ char const* sourceCode = R"(
+ contract c {
+ uint result;
+ function f(uint a, uint b) { result += a + b; }
+ function g(uint a) { result *= a; }
+ function test(uint a, bytes data1, bytes data2, uint b) external returns (uint r_a, uint r, uint r_b, uint l) {
+ r_a = a;
+ this.call(data1);
+ this.call(data2);
+ r = result;
+ r_b = b;
+ l = data1.length;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ string innercalldata1 = asString(FixedHash<4>(dev::sha3("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9));
+ bytes calldata1 = encodeArgs(u256(innercalldata1.length()), 12, innercalldata1, 13);
+ string innercalldata2 = asString(FixedHash<4>(dev::sha3("g(uint256)")).asBytes() + encodeArgs(3));
+ bytes calldata = encodeArgs(
+ u256(innercalldata1.length()), u256(innercalldata2.length()),
+ 12, innercalldata1, innercalldata2, 13);
+ BOOST_CHECK(callContractFunction("test(uint256,bytes,bytes,uint256)", calldata)
+ == encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length())));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}