mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' into rlpx
This commit is contained in:
commit
5ca31adda6
@ -74,7 +74,9 @@ target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
|
||||
target_link_libraries(testeth ${CURL_LIBRARIES})
|
||||
target_link_libraries(testeth ethereum)
|
||||
target_link_libraries(testeth ethcore)
|
||||
target_link_libraries(testeth secp256k1)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(testeth secp256k1)
|
||||
endif()
|
||||
|
||||
if (JSCONSOLE)
|
||||
target_link_libraries(testeth jsengine)
|
||||
|
@ -4493,7 +4493,7 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer)
|
||||
}
|
||||
}
|
||||
contract Main is Base {
|
||||
function Main(bytes s, uint x) Base(x, s){}//f(s)) {}
|
||||
function Main(bytes s, uint x) Base(x, f(s)) {}
|
||||
function f(bytes s) returns (bytes) {
|
||||
return s;
|
||||
}
|
||||
@ -4517,6 +4517,45 @@ BOOST_AUTO_TEST_CASE(bytes_in_constructors_packer)
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(arrays_in_constructors)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Base {
|
||||
uint public m_x;
|
||||
address[] m_s;
|
||||
function Base(uint x, address[] s) {
|
||||
m_x = x;
|
||||
m_s = s;
|
||||
}
|
||||
function part(uint i) returns (address) {
|
||||
return m_s[i];
|
||||
}
|
||||
}
|
||||
contract Main is Base {
|
||||
function Main(address[] s, uint x) Base(x, f(s)) {}
|
||||
function f(address[] s) returns (address[]) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
contract Creator {
|
||||
function f(uint x, address[] s) returns (uint r, address ch) {
|
||||
var c = new Main(s, x);
|
||||
r = c.m_x();
|
||||
ch = c.part(x);
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Creator");
|
||||
vector<u256> s1{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
||||
bytes dyn1 = encodeArgs(u256(s1.size()), s1);
|
||||
u256 x = 7;
|
||||
bytes args1 = encodeArgs(x, u256(0x40)) + dyn1;
|
||||
BOOST_REQUIRE(
|
||||
callContractFunction("f(uint256,address[])", asString(args1)) ==
|
||||
encodeArgs(x, s1[unsigned(x)])
|
||||
);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(arrays_from_and_to_storage)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -4691,6 +4730,35 @@ BOOST_AUTO_TEST_CASE(memory_types_initialisation)
|
||||
BOOST_CHECK(callContractFunction("nestedStat()") == encodeArgs(vector<u256>(3 * 7)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_arrays_delete)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Test {
|
||||
function del() returns (uint24[3][4]) {
|
||||
uint24[3][4] memory x;
|
||||
for (uint24 i = 0; i < x.length; i ++)
|
||||
for (uint24 j = 0; j < x[i].length; j ++)
|
||||
x[i][j] = i * 0x10 + j;
|
||||
delete x[1];
|
||||
delete x[3][2];
|
||||
return x;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
|
||||
vector<u256> data(3 * 4);
|
||||
for (unsigned i = 0; i < 4; i++)
|
||||
for (unsigned j = 0; j < 3; j++)
|
||||
{
|
||||
u256 v = 0;
|
||||
if (!(i == 1 || (i == 3 && j == 2)))
|
||||
v = i * 0x10 + j;
|
||||
data[i * 3 + j] = v;
|
||||
}
|
||||
BOOST_CHECK(callContractFunction("del()") == encodeArgs(data));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_arrays_index_access_write)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -4738,6 +4806,201 @@ BOOST_AUTO_TEST_CASE(memory_arrays_dynamic_index_access_write)
|
||||
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x20), u256(4), data));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_structs_read_write)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Test {
|
||||
struct S { uint8 x; uint16 y; uint z; uint8[2] a; }
|
||||
S[5] data;
|
||||
function testInit() returns (uint8 x, uint16 y, uint z, uint8 a, bool flag) {
|
||||
S[2] memory d;
|
||||
x = d[0].x;
|
||||
y = d[0].y;
|
||||
z = d[0].z;
|
||||
a = d[0].a[1];
|
||||
flag = true;
|
||||
}
|
||||
function testCopyRead() returns (uint8 x, uint16 y, uint z, uint8 a) {
|
||||
data[2].x = 1;
|
||||
data[2].y = 2;
|
||||
data[2].z = 3;
|
||||
data[2].a[1] = 4;
|
||||
S memory s = data[2];
|
||||
x = s.x;
|
||||
y = s.y;
|
||||
z = s.z;
|
||||
a = s.a[1];
|
||||
}
|
||||
function testAssign() returns (uint8 x, uint16 y, uint z, uint8 a) {
|
||||
S memory s;
|
||||
s.x = 1;
|
||||
s.y = 2;
|
||||
s.z = 3;
|
||||
s.a[1] = 4;
|
||||
x = s.x;
|
||||
y = s.y;
|
||||
z = s.z;
|
||||
a = s.a[1];
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
|
||||
BOOST_CHECK(callContractFunction("testInit()") == encodeArgs(u256(0), u256(0), u256(0), u256(0), true));
|
||||
BOOST_CHECK(callContractFunction("testCopyRead()") == encodeArgs(u256(1), u256(2), u256(3), u256(4)));
|
||||
BOOST_CHECK(callContractFunction("testAssign()") == encodeArgs(u256(1), u256(2), u256(3), u256(4)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_structs_as_function_args)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Test {
|
||||
struct S { uint8 x; uint16 y; uint z; }
|
||||
function test() returns (uint x, uint y, uint z) {
|
||||
S memory data = combine(1, 2, 3);
|
||||
x = extract(data, 0);
|
||||
y = extract(data, 1);
|
||||
z = extract(data, 2);
|
||||
}
|
||||
function extract(S s, uint which) internal returns (uint x) {
|
||||
if (which == 0) return s.x;
|
||||
else if (which == 1) return s.y;
|
||||
else return s.z;
|
||||
}
|
||||
function combine(uint8 x, uint16 y, uint z) internal returns (S s) {
|
||||
s.x = x;
|
||||
s.y = y;
|
||||
s.z = z;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(1), u256(2), u256(3)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_structs_nested)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Test {
|
||||
struct S { uint8 x; uint16 y; uint z; }
|
||||
struct X { uint8 x; S s; }
|
||||
function test() returns (uint a, uint x, uint y, uint z) {
|
||||
X memory d = combine(1, 2, 3, 4);
|
||||
a = extract(d, 0);
|
||||
x = extract(d, 1);
|
||||
y = extract(d, 2);
|
||||
z = extract(d, 3);
|
||||
}
|
||||
function extract(X s, uint which) internal returns (uint x) {
|
||||
if (which == 0) return s.x;
|
||||
else if (which == 1) return s.s.x;
|
||||
else if (which == 2) return s.s.y;
|
||||
else return s.s.z;
|
||||
}
|
||||
function combine(uint8 a, uint8 x, uint16 y, uint z) internal returns (X s) {
|
||||
s.x = a;
|
||||
s.s.x = x;
|
||||
s.s.y = y;
|
||||
s.s.z = z;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(1), u256(2), u256(3), u256(4)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_structs_nested_load)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract Test {
|
||||
struct S { uint8 x; uint16 y; uint z; }
|
||||
struct X { uint8 x; S s; uint8[2] a; }
|
||||
X m_x;
|
||||
function load() returns (uint a, uint x, uint y, uint z, uint a1, uint a2) {
|
||||
m_x.x = 1;
|
||||
m_x.s.x = 2;
|
||||
m_x.s.y = 3;
|
||||
m_x.s.z = 4;
|
||||
m_x.a[0] = 5;
|
||||
m_x.a[1] = 6;
|
||||
X memory d = m_x;
|
||||
a = d.x;
|
||||
x = d.s.x;
|
||||
y = d.s.y;
|
||||
z = d.s.z;
|
||||
a1 = d.a[0];
|
||||
a2 = d.a[1];
|
||||
}
|
||||
function store() returns (uint a, uint x, uint y, uint z, uint a1, uint a2) {
|
||||
X memory d;
|
||||
d.x = 1;
|
||||
d.s.x = 2;
|
||||
d.s.y = 3;
|
||||
d.s.z = 4;
|
||||
d.a[0] = 5;
|
||||
d.a[1] = 6;
|
||||
m_x = d;
|
||||
a = m_x.x;
|
||||
x = m_x.s.x;
|
||||
y = m_x.s.y;
|
||||
z = m_x.s.z;
|
||||
a1 = m_x.a[0];
|
||||
a2 = m_x.a[1];
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "Test");
|
||||
|
||||
auto out = encodeArgs(u256(1), u256(2), u256(3), u256(4), u256(5), u256(6));
|
||||
BOOST_CHECK(callContractFunction("load()") == out);
|
||||
BOOST_CHECK(callContractFunction("store()") == out);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(struct_constructor_nested)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
struct X { uint x1; uint x2; }
|
||||
struct S { uint s1; uint[3] s2; X s3; }
|
||||
S s;
|
||||
function C() {
|
||||
uint[3] memory s2;
|
||||
s2[1] = 9;
|
||||
s = S(1, s2, X(4, 5));
|
||||
}
|
||||
function get() returns (uint s1, uint[3] s2, uint x1, uint x2)
|
||||
{
|
||||
s1 = s.s1;
|
||||
s2 = s.s2;
|
||||
x1 = s.s3.x1;
|
||||
x2 = s.s3.x2;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
|
||||
auto out = encodeArgs(u256(1), u256(0), u256(9), u256(0), u256(4), u256(5));
|
||||
BOOST_CHECK(callContractFunction("get()") == out);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(struct_named_constructor)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
struct S { uint a; bool x; }
|
||||
S public s;
|
||||
function C() {
|
||||
s = S({a: 1, x: true});
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
|
||||
BOOST_CHECK(callContractFunction("s()") == encodeArgs(u256(1), true));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -403,6 +403,23 @@ BOOST_AUTO_TEST_CASE(abstract_contract)
|
||||
BOOST_CHECK(derived->getDefinedFunctions()[0]->isFullyImplemented());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
|
||||
{
|
||||
ASTPointer<SourceUnit> sourceUnit;
|
||||
char const* text = R"(
|
||||
contract base { function foo(bool); }
|
||||
contract derived is base { function foo(uint) {} }
|
||||
)";
|
||||
ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed");
|
||||
std::vector<ASTPointer<ASTNode>> nodes = sourceUnit->getNodes();
|
||||
ContractDefinition* base = dynamic_cast<ContractDefinition*>(nodes[0].get());
|
||||
ContractDefinition* derived = dynamic_cast<ContractDefinition*>(nodes[1].get());
|
||||
BOOST_REQUIRE(base);
|
||||
BOOST_CHECK(!base->isFullyImplemented());
|
||||
BOOST_REQUIRE(derived);
|
||||
BOOST_CHECK(!derived->isFullyImplemented());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(create_abstract_contract)
|
||||
{
|
||||
ASTPointer<SourceUnit> sourceUnit;
|
||||
@ -1900,6 +1917,18 @@ BOOST_AUTO_TEST_CASE(storage_location_local_variables)
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(no_mappings_in_memory_array)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
function f() {
|
||||
mapping(uint=>uint)[] memory x;
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(assignment_mem_to_local_storage_variable)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -1931,6 +1960,20 @@ BOOST_AUTO_TEST_CASE(storage_assign_to_different_local_variable)
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(no_delete_on_storage_pointers)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
uint[] data;
|
||||
function f() {
|
||||
var x = data;
|
||||
delete x;
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(assignment_mem_storage_variable_directly)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -2000,6 +2043,60 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
function f() {
|
||||
uint[] memory x;
|
||||
x.length = 2;
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(struct_constructor)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
struct S { uint a; bool x; }
|
||||
function f() {
|
||||
S memory s = S(1, true);
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(struct_constructor_nested)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
struct X { uint x1; uint x2; }
|
||||
struct S { uint s1; uint[3] s2; X s3; }
|
||||
function f() {
|
||||
uint[3] memory s2;
|
||||
S memory s = S(1, s2, X(4, 5));
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(struct_named_constructor)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
struct S { uint a; bool x; }
|
||||
function f() {
|
||||
S memory s = S({a: 1, x: true});
|
||||
}
|
||||
}
|
||||
)";
|
||||
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
}
|
||||
|
@ -200,17 +200,17 @@ contract multiowned {
|
||||
}
|
||||
|
||||
// the number of owners that must confirm the same operation before it is run.
|
||||
uint m_required;
|
||||
uint public m_required;
|
||||
// pointer used to find a free slot in m_owners
|
||||
uint m_numOwners;
|
||||
uint public m_numOwners;
|
||||
// list of owners
|
||||
uint[256] m_owners;
|
||||
uint[256] public m_owners;
|
||||
uint constant c_maxOwners = 250;
|
||||
// index on the list of owners to allow reverse lookup
|
||||
mapping(uint => uint) m_ownerIndex;
|
||||
mapping(uint => uint) public m_ownerIndex;
|
||||
// the ongoing operations.
|
||||
mapping(bytes32 => PendingState) m_pending;
|
||||
bytes32[] m_pendingIndex;
|
||||
mapping(bytes32 => PendingState) public m_pending;
|
||||
bytes32[] public m_pendingIndex;
|
||||
}
|
||||
|
||||
// inheritable "property" contract that enables methods to be protected by placing a linear limit (specifiable)
|
||||
@ -251,9 +251,9 @@ contract daylimit is multiowned {
|
||||
}
|
||||
// determines today's index.
|
||||
function today() private constant returns (uint) { return now / 1 days; }
|
||||
uint m_spentToday;
|
||||
uint m_dailyLimit;
|
||||
uint m_lastDay;
|
||||
uint public m_spentToday;
|
||||
uint public m_dailyLimit;
|
||||
uint public m_lastDay;
|
||||
}
|
||||
// interface contract for multisig proxy contracts; see below for docs.
|
||||
contract multisig {
|
||||
@ -275,11 +275,14 @@ contract Wallet is multisig, multiowned, daylimit {
|
||||
uint value;
|
||||
bytes data;
|
||||
}
|
||||
/*
|
||||
// logged events:
|
||||
// Funds has arrived into the wallet (record how much).
|
||||
event Deposit(address from, uint value);
|
||||
// Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going).
|
||||
event SingleTransact(address owner, uint value, address to, bytes data);
|
||||
// Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going).
|
||||
event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data);*/
|
||||
// constructor - just pass on the owner arra to the multiowned.
|
||||
event Created();
|
||||
function Wallet() {
|
||||
@ -299,7 +302,7 @@ contract Wallet is multisig, multiowned, daylimit {
|
||||
// If not, goes into multisig process. We provide a hash on return to allow the sender to provide
|
||||
// shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value
|
||||
// and _data arguments). They still get the option of using them if they want, anyways.
|
||||
function execute(address _to, uint _value, bytes _data) onlyowner external returns (bytes32 _r) {
|
||||
function execute(address _to, uint _value, bytes _data) external onlyowner returns (bytes32 _r) {
|
||||
// first, take the opportunity to check that we're under the daily limit.
|
||||
if (underLimit(_value)) {
|
||||
SingleTransact(msg.sender, _value, _to, _data);
|
||||
@ -332,8 +335,14 @@ contract Wallet is multisig, multiowned, daylimit {
|
||||
delete m_txs[m_pendingIndex[i]];
|
||||
super.clearPending();
|
||||
}
|
||||
// // internally confirm transaction with all of the info. returns true iff confirmed good and executed.
|
||||
// function confirmVerbose(bytes32 _h, address _to, uint _value, bytes _data) private onlymanyowners(_h) returns (bool) {
|
||||
// _to.call.value(_value)(_data);
|
||||
// MultiTransact("out", msg.sender, _h, _value, _to);
|
||||
// return true;
|
||||
// }
|
||||
// pending transactions we have at present.
|
||||
mapping (bytes32 => Transaction) m_txs;
|
||||
mapping (bytes32 => Transaction) public m_txs;
|
||||
}
|
||||
)DELIMITER";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user