Browse Source

Merge branch 'develop'

cl-refactor
Gav Wood 10 years ago
parent
commit
f1996c62d2
  1. 2
      alethzero/MainWin.cpp
  2. 2
      libdevcore/FixedHash.h
  3. 2
      libdevcrypto/CryptoPP.cpp
  4. 2
      libethcore/ProofOfWork.h
  5. 2
      libethereum/EthereumHost.h
  6. 2
      libethereum/Transaction.h
  7. 12
      libsolidity/AST.cpp
  8. 7
      libsolidity/CompilerContext.cpp
  9. 96
      libsolidity/ExpressionCompiler.cpp
  10. 19
      libsolidity/Types.cpp
  11. 1
      libsolidity/Types.h
  12. 4
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  13. 2
      libwhisper/Common.cpp
  14. 4
      mix/ClientModel.cpp
  15. 103
      test/SolidityEndToEndTest.cpp
  16. 104
      test/stSolidityTestFiller.json

2
alethzero/MainWin.cpp

@ -1629,7 +1629,7 @@ void Main::on_net_triggered()
{
web3()->setIdealPeerCount(ui->idealPeers->value());
web3()->setNetworkPreferences(netPrefs());
ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : 0);
ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256());
// TODO: p2p
// if (m_networkConfig.size()/* && ui->usePast->isChecked()*/)
// web3()->restoreNetwork(bytesConstRef((byte*)m_networkConfig.data(), m_networkConfig.size()));

2
libdevcore/FixedHash.h

@ -80,7 +80,7 @@ public:
operator Arith() const { return fromBigEndian<Arith>(m_data); }
/// @returns true iff this is the empty hash.
operator bool() const { return ((Arith)*this) != 0; }
explicit operator bool() const { return ((Arith)*this) != 0; }
// The obvious comparison operators.
bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }

2
libdevcrypto/CryptoPP.cpp

@ -134,7 +134,7 @@ bool Secp256k1::verify(Signature const& _signature, bytesConstRef _message)
bool Secp256k1::verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed)
{
// todo: verify w/o recovery (if faster)
return _p == _hashed ? recover(_sig, _message) : recover(_sig, sha3(_message).ref());
return (bool)_p == _hashed ? (bool)recover(_sig, _message) : (bool)recover(_sig, sha3(_message).ref());
}
Public Secp256k1::recover(Signature _signature, bytesConstRef _message)

2
libethcore/ProofOfWork.h

@ -82,7 +82,7 @@ template <class Evaluator>
std::pair<MineInfo, h256> ProofOfWorkEngine<Evaluator>::mine(h256 const& _root, u256 const& _difficulty, unsigned _msTimeout, bool _continue, bool _turbo)
{
std::pair<MineInfo, h256> ret;
static std::mt19937_64 s_eng((time(0) + (unsigned)m_last));
static std::mt19937_64 s_eng((time(0) + *reinterpret_cast<unsigned*>(m_last.data())));
u256 s = (m_last = h256::random(s_eng));
bigint d = (bigint(1) << 256) / _difficulty;

2
libethereum/EthereumHost.h

@ -94,7 +94,7 @@ private:
h256Set neededBlocks(h256Set const& _exclude);
/// Check to see if the network peer-state initialisation has happened.
bool isInitialised() const { return m_latestBlockSent; }
bool isInitialised() const { return (bool)m_latestBlockSent; }
/// Initialises the network peer-state, doing the stuff that needs to be once-only. @returns true if it really was first.
bool ensureInitialised();

2
libethereum/Transaction.h

@ -81,7 +81,7 @@ public:
Address safeSender() const noexcept;
/// @returns true if transaction is non-null.
operator bool() const { return m_type != NullTransaction; }
explicit operator bool() const { return m_type != NullTransaction; }
/// @returns true if transaction is contract-creation.
bool isCreation() const { return m_type == ContractCreation; }

12
libsolidity/AST.cpp

@ -603,7 +603,17 @@ void MemberAccess::checkTypeRequirements()
if (!m_type)
BOOST_THROW_EXCEPTION(createTypeError("Member \"" + *m_memberName + "\" not found or not "
"visible in " + type.toString()));
m_isLValue = (type.getCategory() == Type::Category::Struct);
// This should probably move somewhere else.
if (type.getCategory() == Type::Category::Struct)
m_isLValue = true;
else if (type.getCategory() == Type::Category::Array)
{
auto const& arrayType(dynamic_cast<ArrayType const&>(type));
m_isLValue = (*m_memberName == "length" &&
arrayType.getLocation() != ArrayType::Location::CallData && arrayType.isDynamicallySized());
}
else
m_isLValue = false;
}
void IndexAccess::checkTypeRequirements()

7
libsolidity/CompilerContext.cpp

@ -40,7 +40,12 @@ void CompilerContext::addMagicGlobal(MagicVariableDeclaration const& _declaratio
void CompilerContext::addStateVariable(VariableDeclaration const& _declaration)
{
m_stateVariables[&_declaration] = m_stateVariablesSize;
m_stateVariablesSize += _declaration.getType()->getStorageSize();
bigint newSize = bigint(m_stateVariablesSize) + _declaration.getType()->getStorageSize();
if (newSize >= bigint(1) << 256)
BOOST_THROW_EXCEPTION(TypeError()
<< errinfo_comment("State variable does not fit in storage.")
<< errinfo_sourceLocation(_declaration.getLocation()));
m_stateVariablesSize = u256(newSize);
}
void CompilerContext::startFunction(Declaration const& _function)

96
libsolidity/ExpressionCompiler.cpp

@ -534,19 +534,25 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
{
solAssert(member == "length", "Illegal array member.");
auto const& type = dynamic_cast<ArrayType const&>(*_memberAccess.getExpression().getType());
solAssert(type.isByteArray(), "Non byte arrays not yet implemented here.");
switch (type.getLocation())
if (!type.isDynamicallySized())
{
case ArrayType::Location::CallData:
m_context << eth::Instruction::SWAP1 << eth::Instruction::POP;
break;
case ArrayType::Location::Storage:
m_context << eth::Instruction::SLOAD;
break;
default:
solAssert(false, "Unsupported array location.");
break;
CompilerUtils(m_context).popStackElement(type);
m_context << type.getLength();
}
else
switch (type.getLocation())
{
case ArrayType::Location::CallData:
m_context << eth::Instruction::SWAP1 << eth::Instruction::POP;
break;
case ArrayType::Location::Storage:
m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _memberAccess.getType());
m_currentLValue.retrieveValueIfLValueNotRequested(_memberAccess);
break;
default:
solAssert(false, "Unsupported array location.");
break;
}
break;
}
default:
@ -559,19 +565,55 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
_indexAccess.getBaseExpression().accept(*this);
Type const& baseType = *_indexAccess.getBaseExpression().getType();
solAssert(baseType.getCategory() == Type::Category::Mapping, "");
Type const& keyType = *dynamic_cast<MappingType const&>(baseType).getKeyType();
m_context << u256(0);
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
appendExpressionCopyToMemory(keyType, *_indexAccess.getIndexExpression());
solAssert(baseType.getSizeOnStack() == 1,
"Unexpected: Not exactly one stack slot taken by subscriptable expression.");
m_context << eth::Instruction::SWAP1;
appendTypeMoveToMemory(IntegerType(256));
m_context << u256(0) << eth::Instruction::SHA3;
m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _indexAccess.getType());
m_currentLValue.retrieveValueIfLValueNotRequested(_indexAccess);
if (baseType.getCategory() == Type::Category::Mapping)
{
Type const& keyType = *dynamic_cast<MappingType const&>(baseType).getKeyType();
m_context << u256(0);
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
appendExpressionCopyToMemory(keyType, *_indexAccess.getIndexExpression());
solAssert(baseType.getSizeOnStack() == 1,
"Unexpected: Not exactly one stack slot taken by subscriptable expression.");
m_context << eth::Instruction::SWAP1;
appendTypeMoveToMemory(IntegerType(256));
m_context << u256(0) << eth::Instruction::SHA3;
m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _indexAccess.getType());
m_currentLValue.retrieveValueIfLValueNotRequested(_indexAccess);
}
else if (baseType.getCategory() == Type::Category::Array)
{
ArrayType const& arrayType = dynamic_cast<ArrayType const&>(baseType);
solAssert(arrayType.getLocation() == ArrayType::Location::Storage,
"TODO: Index acces only implemented for storage arrays.");
solAssert(!arrayType.isByteArray(), "TODO: Index acces not implemented for byte arrays.");
solAssert(_indexAccess.getIndexExpression(), "Index expression expected.");
_indexAccess.getIndexExpression()->accept(*this);
// retrieve length
if (arrayType.isDynamicallySized())
m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD;
else
m_context << arrayType.getLength();
// stack: <base_ref> <index> <length>
// check out-of-bounds access
m_context << eth::Instruction::DUP2 << eth::Instruction::LT;
eth::AssemblyItem legalAccess = m_context.appendConditionalJump();
// out-of-bounds access throws exception (just STOP for now)
m_context << eth::Instruction::STOP;
m_context << legalAccess;
// stack: <base_ref> <index>
m_context << arrayType.getBaseType()->getStorageSize() << eth::Instruction::MUL;
if (arrayType.isDynamicallySized())
{
m_context << eth::Instruction::SWAP1;
CompilerUtils(m_context).computeHashStatic();
}
m_context << eth::Instruction::ADD;
m_currentLValue = LValue(m_context, LValue::LValueType::Storage, _indexAccess.getType());
m_currentLValue.retrieveValueIfLValueNotRequested(_indexAccess);
}
else
solAssert(false, "Index access only allowed for mappings or arrays.");
return false;
}
@ -1049,7 +1091,7 @@ void ExpressionCompiler::LValue::retrieveValue(Location const& _location, bool _
{
case LValueType::Stack:
{
unsigned stackPos = m_context->baseToCurrentStackOffset(unsigned(m_baseStackOffset));
unsigned stackPos = m_context->baseToCurrentStackOffset(m_baseStackOffset);
if (stackPos >= 15) //@todo correct this by fetching earlier or moving to memory
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_location)
<< errinfo_comment("Stack too deep."));
@ -1098,7 +1140,7 @@ void ExpressionCompiler::LValue::storeValue(Type const& _sourceType, Location co
{
case LValueType::Stack:
{
unsigned stackDiff = m_context->baseToCurrentStackOffset(unsigned(m_baseStackOffset)) - m_size + 1;
unsigned stackDiff = m_context->baseToCurrentStackOffset(m_baseStackOffset) - m_size + 1;
if (stackDiff > 16)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_location)
<< errinfo_comment("Stack too deep."));
@ -1201,7 +1243,7 @@ void ExpressionCompiler::LValue::setToZero(Location const& _location) const
{
case LValueType::Stack:
{
unsigned stackDiff = m_context->baseToCurrentStackOffset(unsigned(m_baseStackOffset));
unsigned stackDiff = m_context->baseToCurrentStackOffset(m_baseStackOffset);
if (stackDiff > 16)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_location)
<< errinfo_comment("Stack too deep."));

19
libsolidity/Types.cpp

@ -555,6 +555,19 @@ bool ArrayType::operator==(Type const& _other) const
return other.m_location == m_location;
}
u256 ArrayType::getStorageSize() const
{
if (isDynamicallySized())
return 1;
else
{
bigint size = bigint(getLength()) * getBaseType()->getStorageSize();
if (size >= bigint(1) << 256)
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Array too large for storage."));
return max<u256>(1, u256(size));
}
}
unsigned ArrayType::getSizeOnStack() const
{
if (m_location == Location::CallData)
@ -665,10 +678,12 @@ bool StructType::operator==(Type const& _other) const
u256 StructType::getStorageSize() const
{
u256 size = 0;
bigint size = 0;
for (pair<string, TypePointer> const& member: getMembers())
size += member.second->getStorageSize();
return max<u256>(1, size);
if (size >= bigint(1) << 256)
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Struct too large for storage."));
return max<u256>(1, u256(size));
}
bool StructType::canLiveOutsideStorage() const

1
libsolidity/Types.h

@ -303,6 +303,7 @@ public:
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual bool operator==(const Type& _other) const override;
virtual bool isDynamicallySized() const { return m_hasDynamicLength; }
virtual u256 getStorageSize() const override;
virtual unsigned getSizeOnStack() const override;
virtual std::string toString() const override;
virtual MemberList const& getMembers() const override { return s_arrayTypeMemberList; }

4
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -701,10 +701,10 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
{
std::string ret;
TransactionSkeleton t = toTransaction(_json);
if (t.creation)
ret = right160(sha3(rlpList(t.from, client()->countAt(t.from))));;
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
if (t.creation)
ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));;
if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas)

2
libwhisper/Common.cpp

@ -71,7 +71,7 @@ bool TopicFilter::matches(Envelope const& _e) const
for (unsigned i = 0; i < t.size(); ++i)
{
for (auto et: _e.topic())
if (((t[i].first ^ et) & t[i].second) == 0)
if (((t[i].first ^ et) & t[i].second) == CollapsedTopicPart())
goto NEXT_TOPICPART;
// failed to match topicmask against any topics: move on to next mask
goto NEXT_TOPICMASK;

4
mix/ClientModel.cpp

@ -370,7 +370,7 @@ void ClientModel::onNewTransaction()
QString function;
QString returned;
bool creation = tr.contractAddress != 0;
bool creation = (bool)tr.contractAddress;
//TODO: handle value transfer
FixedHash<4> functionHash;
@ -403,7 +403,7 @@ void ClientModel::onNewTransaction()
if (creation)
returned = QString::fromStdString(toJS(tr.contractAddress));
Address contractAddress = tr.address != 0 ? tr.address : tr.contractAddress;
Address contractAddress = (bool)tr.address ? tr.address : tr.contractAddress;
auto contractAddressIter = m_contractNames.find(contractAddress);
if (contractAddressIter != m_contractNames.end())
{

103
test/SolidityEndToEndTest.cpp

@ -2137,7 +2137,7 @@ BOOST_AUTO_TEST_CASE(event_lots_of_data)
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_CHECK(m_logs[0].data == encodeArgs((u160)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)")));
}
@ -2667,6 +2667,107 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments)
== encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length())));
}
BOOST_AUTO_TEST_CASE(fixed_arrays_in_storage)
{
char const* sourceCode = R"(
contract c {
struct Data { uint x; uint y; }
Data[2**10] data;
uint[2**10 + 3] ids;
function setIDStatic(uint id) { ids[2] = id; }
function setID(uint index, uint id) { ids[index] = id; }
function setData(uint index, uint x, uint y) { data[index].x = x; data[index].y = y; }
function getID(uint index) returns (uint) { return ids[index]; }
function getData(uint index) returns (uint x, uint y) { x = data[index].x; y = data[index].y; }
function getLengths() returns (uint l1, uint l2) { l1 = data.length; l2 = ids.length; }
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("setIDStatic(uint256)", 11) == bytes());
BOOST_CHECK(callContractFunction("getID(uint256)", 2) == encodeArgs(11));
BOOST_CHECK(callContractFunction("setID(uint256,uint256)", 7, 8) == bytes());
BOOST_CHECK(callContractFunction("getID(uint256)", 7) == encodeArgs(8));
BOOST_CHECK(callContractFunction("setData(uint256,uint256,uint256)", 7, 8, 9) == bytes());
BOOST_CHECK(callContractFunction("setData(uint256,uint256,uint256)", 8, 10, 11) == bytes());
BOOST_CHECK(callContractFunction("getData(uint256)", 7) == encodeArgs(8, 9));
BOOST_CHECK(callContractFunction("getData(uint256)", 8) == encodeArgs(10, 11));
BOOST_CHECK(callContractFunction("getLengths()") == encodeArgs(u256(1) << 10, (u256(1) << 10) + 3));
}
BOOST_AUTO_TEST_CASE(dynamic_arrays_in_storage)
{
char const* sourceCode = R"(
contract c {
struct Data { uint x; uint y; }
Data[] data;
uint[] ids;
function setIDStatic(uint id) { ids[2] = id; }
function setID(uint index, uint id) { ids[index] = id; }
function setData(uint index, uint x, uint y) { data[index].x = x; data[index].y = y; }
function getID(uint index) returns (uint) { return ids[index]; }
function getData(uint index) returns (uint x, uint y) { x = data[index].x; y = data[index].y; }
function getLengths() returns (uint l1, uint l2) { l1 = data.length; l2 = ids.length; }
function setLengths(uint l1, uint l2) { data.length = l1; ids.length = l2; }
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("getLengths()") == encodeArgs(0, 0));
BOOST_CHECK(callContractFunction("setLengths(uint256,uint256)", 48, 49) == bytes());
BOOST_CHECK(callContractFunction("getLengths()") == encodeArgs(48, 49));
BOOST_CHECK(callContractFunction("setIDStatic(uint256)", 11) == bytes());
BOOST_CHECK(callContractFunction("getID(uint256)", 2) == encodeArgs(11));
BOOST_CHECK(callContractFunction("setID(uint256,uint256)", 7, 8) == bytes());
BOOST_CHECK(callContractFunction("getID(uint256)", 7) == encodeArgs(8));
BOOST_CHECK(callContractFunction("setData(uint256,uint256,uint256)", 7, 8, 9) == bytes());
BOOST_CHECK(callContractFunction("setData(uint256,uint256,uint256)", 8, 10, 11) == bytes());
BOOST_CHECK(callContractFunction("getData(uint256)", 7) == encodeArgs(8, 9));
BOOST_CHECK(callContractFunction("getData(uint256)", 8) == encodeArgs(10, 11));
}
BOOST_AUTO_TEST_CASE(fixed_out_of_bounds_array_access)
{
char const* sourceCode = R"(
contract c {
uint[4] data;
function set(uint index, uint value) returns (bool) { data[index] = value; return true; }
function get(uint index) returns (uint) { return data[index]; }
function length() returns (uint) { return data.length; }
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("length()") == encodeArgs(4));
BOOST_CHECK(callContractFunction("set(uint256,uint256)", 3, 4) == encodeArgs(true));
BOOST_CHECK(callContractFunction("set(uint256,uint256)", 4, 5) == bytes());
BOOST_CHECK(callContractFunction("set(uint256,uint256)", 400, 5) == bytes());
BOOST_CHECK(callContractFunction("get(uint256)", 3) == encodeArgs(4));
BOOST_CHECK(callContractFunction("get(uint256)", 4) == bytes());
BOOST_CHECK(callContractFunction("get(uint256)", 400) == bytes());
BOOST_CHECK(callContractFunction("length()") == encodeArgs(4));
}
BOOST_AUTO_TEST_CASE(dynamic_out_of_bounds_array_access)
{
char const* sourceCode = R"(
contract c {
uint[] data;
function enlarge(uint amount) returns (uint) { return data.length += amount; }
function set(uint index, uint value) returns (bool) { data[index] = value; return true; }
function get(uint index) returns (uint) { return data[index]; }
function length() returns (uint) { return data.length; }
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(callContractFunction("length()") == encodeArgs(0));
BOOST_CHECK(callContractFunction("get(uint256)", 3) == bytes());
BOOST_CHECK(callContractFunction("enlarge(uint256)", 4) == encodeArgs(4));
BOOST_CHECK(callContractFunction("length()") == encodeArgs(4));
BOOST_CHECK(callContractFunction("set(uint256,uint256)", 3, 4) == encodeArgs(true));
BOOST_CHECK(callContractFunction("get(uint256)", 3) == encodeArgs(4));
BOOST_CHECK(callContractFunction("length()") == encodeArgs(4));
BOOST_CHECK(callContractFunction("set(uint256,uint256)", 4, 8) == bytes());
BOOST_CHECK(callContractFunction("length()") == encodeArgs(4));
}
BOOST_AUTO_TEST_SUITE_END()
}

104
test/stSolidityTestFiller.json

@ -76,14 +76,6 @@
"//" : " if (!testCryptographicFunctions()) ",
"//" : " res = hash(int(res) + int(0x00000f0000000000000000000000000000000000000000000000000000000000)); ",
"//" : " ",
"//" : " //Tested 27.01.2015 ",
"//" : " //should run out of gas ",
"//" : " //if (!testInfiniteLoop()) ",
"//" : " // res = hash(int(res) + int(0x000f000000000000000000000000000000000000000000000000000000000000)); ",
"//" : " // ",
"//" : " //should run out of gas ",
"//" : " //if (!testRecursiveMethods()) ",
"//" : " // res = hash(int(res) + int(0x0000000000000000000000000000000000000000000000000000000000000000)); ",
"//" : " } ",
"//" : " ",
"//" : " function testCryptographicFunctions() returns (bool res) ",
@ -155,25 +147,6 @@
"//" : " ",
"//" : " } ",
"//" : " ",
"//" : " function testInfiniteLoop() returns (bool res) ",
"//" : " { ",
"//" : " res = false; ",
"//" : " while(true){} ",
"//" : " return true; ",
"//" : " } ",
"//" : " ",
"//" : " function testRecursiveMethods() returns (bool res) ",
"//" : " { ",
"//" : " res = false; ",
"//" : " testRecursiveMethods2(); ",
"//" : " return true; ",
"//" : " } ",
"//" : " function testRecursiveMethods2() ",
"//" : " { ",
"//" : " testRecursiveMethods(); ",
"//" : "} ",
"//" : " ",
"//" : " ",
"//" : " function testContractSuicide() returns (bool res) ",
"//" : " { ",
"//" : " TestContract a = new TestContract(); ",
@ -219,7 +192,6 @@
"//" : " } ",
"//" : " } ",
"//" : " ",
"//" : " ",
"//" : " if (i == 0) ",
"//" : " return true; ",
"//" : " ",
@ -361,7 +333,7 @@
{
"//" : "testRecursiveMethods()",
"data" : "0x981a3165",
"gasLimit" : "7000",
"gasLimit" : "2000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
@ -500,7 +472,7 @@
}
},
"AmbigiousMethod" : {
"AmbiguousMethod" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
@ -513,6 +485,23 @@
{
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "100000",
"//" : "contract contract1 ",
"//" : "{ ",
"//" : " uint value; ",
"//" : " function run() ",
"//" : " { ",
"//" : " value = 225; ",
"//" : " } ",
"//" : "} ",
"//" : " ",
"//" : "contract contract2 ",
"//" : "{ ",
"//" : " uint value2; ",
"//" : " function run() ",
"//" : " { ",
"//" : " value2 = 335; ",
"//" : " } ",
"//" : "} ",
"code" : "0x60003560e060020a90048063c040622614601557005b601b6021565b60006000f35b61014f60008190555056",
"nonce" : "0",
"storage" : {
@ -536,5 +525,60 @@
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "1"
}
},
"QuadraticComplexity" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "100000000",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" :
{
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "10000000",
"//" : "contract caller ",
"//" : "{ ",
"//" : " int value; ",
"//" : " function run(int count) ",
"//" : " { ",
"//" : " value = count; ",
"//" : " address a = 0xb94f5374fce5edbc8e2a8697c15331677e6ebf0b; ",
"//" : " while(count > 0) ",
"//" : " { ",
"//" : " a.call('just', 'call'); ",
"//" : " count = count - 1; ",
"//" : " } ",
"//" : " } ",
"//" : "} ",
"code" : "0x60003560e060020a9004806361a4770614601557005b601e6004356024565b60006000f35b60008160008190555073b94f5374fce5edbc8e2a8697c15331677e6ebf0b90505b600082131560bf5780600160a060020a03166000600060007f6a7573740000000000000000000000000000000000000000000000000000000081526004017f63616c6c000000000000000000000000000000000000000000000000000000008152602001600060008560155a03f150506001820391506045565b505056",
"nonce" : "0",
"storage" : {
}
},
"b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "100000",
"code" : "{ (CALLDATACOPY 0 0 32) }",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"//" : "run(int256)",
"data" : "0x61a47706000000000000000000000000000000000000000000000000000000000000c350",
"gasLimit" : "904+68*x+e",
"gasLimit" : "3500000",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "a94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "1"
}
}
}

Loading…
Cancel
Save