From 7ed7a9a2539bb5e548643bdca920471bc5c0b0a4 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 09:16:32 +0100 Subject: [PATCH 01/49] create random state tests --- test/CMakeLists.txt | 5 + test/TestHelper.cpp | 32 +++--- test/createRandomStateTest.cpp | 186 +++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+), 16 deletions(-) create mode 100644 test/createRandomStateTest.cpp diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 292f62a03..83f61c769 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,6 +2,7 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") +list(REMOVE_ITEM SRC_LIST "./createRandomStateTest.cpp") list(REMOVE_ITEM SRC_LIST "./checkRandomTest.cpp") if (NOT JSONRPC) @@ -18,6 +19,7 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) +add_executable(createRandomStateTest createRandomStateTest.cpp state.cpp TestHelper.cpp) add_executable(checkRandomTest checkRandomTest.cpp vm.cpp TestHelper.cpp) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) @@ -38,6 +40,9 @@ endif() target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(createRandomTest ethereum) target_link_libraries(createRandomTest ethcore) +target_link_libraries(createRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(createRandomStateTest ethereum) +target_link_libraries(createRandomStateTest ethcore) target_link_libraries(checkRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(checkRandomTest ethereum) target_link_libraries(checkRandomTest ethcore) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 9ac64107d..4d5563415 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -84,12 +84,12 @@ ImportTest::ImportTest(json_spirit::mObject& _o, bool isFiller) : m_statePre(Add void ImportTest::importEnv(json_spirit::mObject& _o) { - BOOST_REQUIRE(_o.count("previousHash") > 0); - BOOST_REQUIRE(_o.count("currentGasLimit") > 0); - BOOST_REQUIRE(_o.count("currentDifficulty") > 0); - BOOST_REQUIRE(_o.count("currentTimestamp") > 0); - BOOST_REQUIRE(_o.count("currentCoinbase") > 0); - BOOST_REQUIRE(_o.count("currentNumber") > 0); + assert(_o.count("previousHash") > 0); + assert(_o.count("currentGasLimit") > 0); + assert(_o.count("currentDifficulty") > 0); + assert(_o.count("currentTimestamp") > 0); + assert(_o.count("currentCoinbase") > 0); + assert(_o.count("currentNumber") > 0); m_environment.previousBlock.hash = h256(_o["previousHash"].get_str()); m_environment.currentBlock.number = toInt(_o["currentNumber"]); @@ -108,10 +108,10 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) { json_spirit::mObject o = i.second.get_obj(); - BOOST_REQUIRE(o.count("balance") > 0); - BOOST_REQUIRE(o.count("nonce") > 0); - BOOST_REQUIRE(o.count("storage") > 0); - BOOST_REQUIRE(o.count("code") > 0); + assert(o.count("balance") > 0); + assert(o.count("nonce") > 0); + assert(o.count("storage") > 0); + assert(o.count("code") > 0); if (bigint(o["balance"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("State 'balance' is equal or greater than 2**256") ); @@ -144,12 +144,12 @@ void ImportTest::importTransaction(json_spirit::mObject& _o) { if (_o.count("secretKey") > 0) { - BOOST_REQUIRE(_o.count("nonce") > 0); - BOOST_REQUIRE(_o.count("gasPrice") > 0); - BOOST_REQUIRE(_o.count("gasLimit") > 0); - BOOST_REQUIRE(_o.count("to") > 0); - BOOST_REQUIRE(_o.count("value") > 0); - BOOST_REQUIRE(_o.count("data") > 0); + assert(_o.count("nonce") > 0); + assert(_o.count("gasPrice") > 0); + assert(_o.count("gasLimit") > 0); + assert(_o.count("to") > 0); + assert(_o.count("value") > 0); + assert(_o.count("data") > 0); if (bigint(_o["nonce"].get_str()) >= c_max256plus1) BOOST_THROW_EXCEPTION(ValueTooLarge() << errinfo_comment("Transaction 'nonce' is equal or greater than 2**256") ); diff --git a/test/createRandomStateTest.cpp b/test/createRandomStateTest.cpp new file mode 100644 index 000000000..2743ad191 --- /dev/null +++ b/test/createRandomStateTest.cpp @@ -0,0 +1,186 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file createRandomStateTest.cpp + * @author Christoph Jentzsch + * @date 2015 + * Creating a random state test. + */ + +#include +#include +#include + +#include +#include + +#pragma GCC diagnostic ignored "-Wunused-parameter" +#include +#include +#include +#include +#include +#include +#include +#include "TestHelper.h" +#include "vm.h" + +using namespace std; +using namespace json_spirit; +using namespace dev; + +void doStateTests(json_spirit::mValue& _v); + +int main(int argc, char *argv[]) +{ + g_logVerbosity = 0; + + // create random code + + boost::random::mt19937 gen; + + auto now = chrono::steady_clock::now().time_since_epoch(); + auto timeSinceEpoch = chrono::duration_cast(now).count(); + gen.seed(static_cast(timeSinceEpoch)); + boost::random::uniform_int_distribution<> lengthOfCodeDist(2, 16); + boost::random::uniform_int_distribution<> opcodeDist(0, 255); + boost::random::uniform_int_distribution<> BlockInfoOpcodeDist(0x40, 0x45); + boost::random::variate_generator > randGen(gen, opcodeDist); + boost::random::variate_generator > randGenBlockInfoOpcode(gen, BlockInfoOpcodeDist); + + int lengthOfCode = lengthOfCodeDist(gen); + string randomCode; + + for (int i = 0; i < lengthOfCode; ++i) + { + if (i < 8 && (randGen() < 192)) + { + randomCode += toHex(toCompactBigEndian((uint8_t)randGenBlockInfoOpcode())); + continue; + } + + uint8_t opcode = randGen(); + // disregard all invalid commands, except of one (0x0c) + if ((dev::eth::isValidInstruction(dev::eth::Instruction(opcode)) || (randGen() > 250))) + randomCode += toHex(toCompactBigEndian(opcode)); + else + i--; + } + + string const s = R"( + { + "randomStatetest" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "code" : "0x6001600101600055", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "code" : "0x", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "400000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000" + } + } + } +)"; + + + cout << "the test: " << s << endl; + + mValue v; + read_string(s, v); + + // insert new random code + v.get_obj().find("randomStatetest")->second.get_obj().find("pre")->second.get_obj().begin()->second.get_obj()["code"] = "0x" + randomCode + (randGen() > 128 ? "55" : ""); + + // fill test + doStateTests(v); + + // stream to output for further handling by the bash script + cout << json_spirit::write_string(v, true); + + return 0; +} + +void doStateTests(json_spirit::mValue& _v) +{ + try{ + for (auto& i: _v.get_obj()) + { + cerr << i.first << endl; + mObject& o = i.second.get_obj(); + + assert(o.count("env") > 0); + assert(o.count("pre") > 0); + assert(o.count("transaction") > 0); + + test::ImportTest importer(o, true); + + eth::State theState = importer.m_statePre; + bytes tx = importer.m_transaction.rlp(); + bytes output; + + try + { + theState.execute(test::lastHashes(importer.m_environment.currentBlock.number), tx, &output); + } + catch (Exception const& _e) + { + cnote << "state execution did throw an exception: " << diagnostic_information(_e); + theState.commit(); + } + catch (std::exception const& _e) + { + cnote << "state execution did throw an exception: " << _e.what(); + } +#if ETH_FATDB + importer.exportTest(output, theState); +#else + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("You can not fill tests when FATDB is switched off")); +#endif + } + } + catch (Exception const& _e) + { + cout << "problem: " << diagnostic_information(_e); + } +} + From 0fa604edd82f4f06fc8d955dd664e9dcf98ce4f3 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 11:01:06 +0100 Subject: [PATCH 02/49] add check random state test for jit --- test/CMakeLists.txt | 25 +- test/checkRandomStateTest.cpp | 219 ++++++++++++++++++ ...ckRandomTest.cpp => checkRandomVMTest.cpp} | 0 test/createRandomStateTest.cpp | 158 ++++++------- ...eRandomTest.cpp => createRandomVMTest.cpp} | 0 test/state.cpp | 33 +++ 6 files changed, 342 insertions(+), 93 deletions(-) create mode 100644 test/checkRandomStateTest.cpp rename test/{checkRandomTest.cpp => checkRandomVMTest.cpp} (100%) rename test/{createRandomTest.cpp => createRandomVMTest.cpp} (100%) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 83f61c769..45f83e5e3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,9 +1,10 @@ cmake_policy(SET CMP0015 NEW) aux_source_directory(. SRC_LIST) -list(REMOVE_ITEM SRC_LIST "./createRandomTest.cpp") +list(REMOVE_ITEM SRC_LIST "./createRandomVMTest.cpp") list(REMOVE_ITEM SRC_LIST "./createRandomStateTest.cpp") -list(REMOVE_ITEM SRC_LIST "./checkRandomTest.cpp") +list(REMOVE_ITEM SRC_LIST "./checkRandomVMTest.cpp") +list(REMOVE_ITEM SRC_LIST "./checkRandomStateTest.cpp") if (NOT JSONRPC) list(REMOVE_ITEM SRC_LIST "./AccountHolder.cpp") @@ -18,9 +19,10 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) -add_executable(createRandomTest createRandomTest.cpp vm.cpp TestHelper.cpp) +add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp) add_executable(createRandomStateTest createRandomStateTest.cpp state.cpp TestHelper.cpp) -add_executable(checkRandomTest checkRandomTest.cpp vm.cpp TestHelper.cpp) +add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp) +add_executable(checkRandomStateTest checkRandomStateTest.cpp state.cpp TestHelper.cpp) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) @@ -37,13 +39,16 @@ if (JSONRPC) target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES}) endif() -target_link_libraries(createRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(createRandomTest ethereum) -target_link_libraries(createRandomTest ethcore) +target_link_libraries(createRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(createRandomVMTest ethereum) +target_link_libraries(createRandomVMTest ethcore) target_link_libraries(createRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(createRandomStateTest ethereum) target_link_libraries(createRandomStateTest ethcore) -target_link_libraries(checkRandomTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) -target_link_libraries(checkRandomTest ethereum) -target_link_libraries(checkRandomTest ethcore) +target_link_libraries(checkRandomVMTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(checkRandomVMTest ethereum) +target_link_libraries(checkRandomVMTest ethcore) +target_link_libraries(checkRandomStateTest ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) +target_link_libraries(checkRandomStateTest ethereum) +target_link_libraries(checkRandomStateTest ethcore) diff --git a/test/checkRandomStateTest.cpp b/test/checkRandomStateTest.cpp new file mode 100644 index 000000000..29ccc2eb0 --- /dev/null +++ b/test/checkRandomStateTest.cpp @@ -0,0 +1,219 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file checkRandomTest.cpp + * @author Christoph Jentzsch + * @date 2015 + * Check a random test and return 0/1 for success or failure. To be used for efficiency in the random test simulation. + */ + +#include +#include +#include +#include +#include "TestHelper.h" +#include "vm.h" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +using namespace std; +using namespace json_spirit; +using namespace dev::test; +using namespace dev; + +bool doStateTest(mValue& v); + +int main(int argc, char *argv[]) +{ + g_logVerbosity = 0; + bool ret = false; + + try + { + mValue v; + string s; + for (int i = 1; i < argc; ++i) + s += argv[i]; + if (asserts(s.length() > 0)) + { + cout << "Content of argument is empty\n"; + return 1; + } + read_string(s, v); + ret = doStateTest(v); + } + catch (Exception const& _e) + { + cout << "Failed test with Exception: " << diagnostic_information(_e) << endl; + ret = false; + } + catch (std::exception const& _e) + { + cout << "Failed test with Exception: " << _e.what() << endl; + ret = false; + } + return ret; +} + +bool doStateTest(mValue& v) +{ + eth::VMFactory::setKind(eth::VMKind::JIT); + + for (auto& i: v.get_obj()) + { + //cerr << i.first << endl; + mObject& o = i.second.get_obj(); + + assert(o.count("env") > 0); + assert(o.count("pre") > 0); + assert(o.count("transaction") > 0); + + ImportTest importer(o, false); + + eth::State theState = importer.m_statePre; + bytes tx = importer.m_transaction.rlp(); + bytes output; + + try + { + theState.execute(lastHashes(importer.m_environment.currentBlock.number), tx, &output); + } + catch (Exception const& _e) + { + cnote << "state execution did throw an exception: " << diagnostic_information(_e); + theState.commit(); + } + catch (std::exception const& _e) + { + cnote << "state execution did throw an exception: " << _e.what(); + } + + assert(o.count("post") > 0); + assert(o.count("out") > 0); + + + //checkOutput(output, o); + int j = 0; + if (o["out"].type() == array_type) + for (auto const& d: o["out"].get_array()) + { + if (asserts(output[j] == toInt(d))) + { + cout << "Output byte [" << j << "] different!"; + return 1; + } + ++j; + } + else if (o["out"].get_str().find("0x") == 0) + { + if (asserts(output == fromHex(o["out"].get_str().substr(2)))) + return 1; + } + else + { + if (asserts(output == fromHex(o["out"].get_str()))) + return 1; + } + + + // check logs + //checkLog(theState.pending().size() ? theState.log(0) : LogEntries(), importer.m_environment.sub.logs); + eth::LogEntries logs = theState.pending().size() ? theState.log(0) : eth::LogEntries(); + + //checkLog(logs, importer.m_environment.sub.logs); + { + if (assertsEqual(logs.size(), importer.m_environment.sub.logs.size())) + return 1; + + for (size_t i = 0; i < logs.size(); ++i) + { + if (assertsEqual(logs[i].address, importer.m_environment.sub.logs[i].address)) + return 1; + if (assertsEqual(logs[i].topics, importer.m_environment.sub.logs[i].topics)) + return 1; + if (asserts(logs[i].data == importer.m_environment.sub.logs[i].data)) + return 1; + } + } + + // check addresses +#if ETH_FATDB + auto expectedAddrs = importer.m_statePost.addresses(); + auto resultAddrs = theState.addresses(); + for (auto& expectedPair : expectedAddrs) + { + auto& expectedAddr = expectedPair.first; + auto resultAddrIt = resultAddrs.find(expectedAddr); + if (resultAddrIt == resultAddrs.end()) + BOOST_ERROR("Missing expected address " << expectedAddr); + else + { + BOOST_CHECK_MESSAGE(importer.m_statePost.balance(expectedAddr) == theState.balance(expectedAddr), expectedAddr << ": incorrect balance " << theState.balance(expectedAddr) << ", expected " << importer.m_statePost.balance(expectedAddr)); + BOOST_CHECK_MESSAGE(importer.m_statePost.transactionsFrom(expectedAddr) == theState.transactionsFrom(expectedAddr), expectedAddr << ": incorrect txCount " << theState.transactionsFrom(expectedAddr) << ", expected " << importer.m_statePost.transactionsFrom(expectedAddr)); + BOOST_CHECK_MESSAGE(importer.m_statePost.code(expectedAddr) == theState.code(expectedAddr), expectedAddr << ": incorrect code"); + + //checkStorage(importer.m_statePost.storage(expectedAddr), theState.storage(expectedAddr), expectedAddr); + + map _resultStore = theState.storage(expectedAddr); + + for (auto&& expectedStorePair : importer.m_statePost.storage(expectedAddr)) + { + auto& expectedStoreKey = expectedStorePair.first; + auto resultStoreIt = _resultStore.find(expectedStoreKey); + if (resultStoreIt == _resultStore.end()) + { + cout << expectedAddr << ": missing store key " << expectedStoreKey << endl; + return 1; + } + else + { + auto& expectedStoreValue = expectedStorePair.second; + auto& resultStoreValue = resultStoreIt->second; + if (asserts(expectedStoreValue == resultStoreValue)) + { + cout << expectedAddr << ": store[" << expectedStoreKey << "] = " << resultStoreValue << ", expected " << expectedStoreValue << endl; + return 1; + } + } + } + if (assertsEqual(_resultStore.size(), importer.m_statePost.storage(expectedAddr).size())) + return 1; + for (auto&& resultStorePair: _resultStore) + { + if (!importer.m_statePost.storage(expectedAddr).count(resultStorePair.first)) + { + cout << expectedAddr << ": unexpected store key " << resultStorePair.first << endl; + return 1; + } + } + } + } + //checkAddresses >(expectedAddrs, resultAddrs); + for (auto& resultPair : resultAddrs) + { + auto& resultAddr = resultPair.first; + auto expectedAddrIt = expectedAddrs.find(resultAddr); + if (expectedAddrIt == expectedAddrs.end()) + return 1; + } + if(expectedAddrs != resultAddrs) + return 1; + +#endif + if(theState.rootHash() != h256(o["postStateRoot"].get_str()), "wrong post state root") + return 1; + } + return 0; +} diff --git a/test/checkRandomTest.cpp b/test/checkRandomVMTest.cpp similarity index 100% rename from test/checkRandomTest.cpp rename to test/checkRandomVMTest.cpp diff --git a/test/createRandomStateTest.cpp b/test/createRandomStateTest.cpp index 2743ad191..06a332e0e 100644 --- a/test/createRandomStateTest.cpp +++ b/test/createRandomStateTest.cpp @@ -82,57 +82,53 @@ int main(int argc, char *argv[]) i--; } - string const s = R"( - { - "randomStatetest" : { - "env" : { - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "256", - "currentGasLimit" : "1000000", - "currentNumber" : "0", - "currentTimestamp" : 1, - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "1000000000000000000", - "code" : "0x6001600101600055", - "nonce" : "0", - "storage" : { - } - }, - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "code" : "0x", - "nonce" : "0", - "storage" : { - } - } - }, - "transaction" : { - "data" : "", - "gasLimit" : "400000", - "gasPrice" : "1", - "nonce" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", - "value" : "100000" - } - } - } + string const s = R"( + { + "randomStatetest" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "256", + "currentGasLimit" : "1000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "code" : "0x6001600101600055", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "code" : "0x", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : { + "data" : "", + "gasLimit" : "400000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000" + } + } + } )"; - - - cout << "the test: " << s << endl; - - mValue v; + mValue v; read_string(s, v); // insert new random code - v.get_obj().find("randomStatetest")->second.get_obj().find("pre")->second.get_obj().begin()->second.get_obj()["code"] = "0x" + randomCode + (randGen() > 128 ? "55" : ""); + v.get_obj().find("randomStatetest")->second.get_obj().find("pre")->second.get_obj().begin()->second.get_obj()["code"] = "0x" + randomCode + (randGen() > 128 ? "55" : ""); - // fill test - doStateTests(v); + // fill test + doStateTests(v); // stream to output for further handling by the bash script cout << json_spirit::write_string(v, true); @@ -142,45 +138,41 @@ int main(int argc, char *argv[]) void doStateTests(json_spirit::mValue& _v) { - try{ - for (auto& i: _v.get_obj()) - { - cerr << i.first << endl; - mObject& o = i.second.get_obj(); - - assert(o.count("env") > 0); - assert(o.count("pre") > 0); - assert(o.count("transaction") > 0); - - test::ImportTest importer(o, true); - - eth::State theState = importer.m_statePre; - bytes tx = importer.m_transaction.rlp(); - bytes output; - - try - { - theState.execute(test::lastHashes(importer.m_environment.currentBlock.number), tx, &output); - } - catch (Exception const& _e) - { - cnote << "state execution did throw an exception: " << diagnostic_information(_e); - theState.commit(); - } - catch (std::exception const& _e) - { - cnote << "state execution did throw an exception: " << _e.what(); - } + eth::VMFactory::setKind(eth::VMKind::Interpreter); + + for (auto& i: _v.get_obj()) + { + //cerr << i.first << endl; + mObject& o = i.second.get_obj(); + + assert(o.count("env") > 0); + assert(o.count("pre") > 0); + assert(o.count("transaction") > 0); + + test::ImportTest importer(o, true); + + eth::State theState = importer.m_statePre; + bytes tx = importer.m_transaction.rlp(); + bytes output; + + try + { + theState.execute(test::lastHashes(importer.m_environment.currentBlock.number), tx, &output); + } + catch (Exception const& _e) + { + cnote << "state execution did throw an exception: " << diagnostic_information(_e); + theState.commit(); + } + catch (std::exception const& _e) + { + cnote << "state execution did throw an exception: " << _e.what(); + } #if ETH_FATDB - importer.exportTest(output, theState); + importer.exportTest(output, theState); #else - BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("You can not fill tests when FATDB is switched off")); + cout << "You can not fill tests when FATDB is switched off"; #endif - } - } - catch (Exception const& _e) - { - cout << "problem: " << diagnostic_information(_e); - } + } } diff --git a/test/createRandomTest.cpp b/test/createRandomVMTest.cpp similarity index 100% rename from test/createRandomTest.cpp rename to test/createRandomVMTest.cpp diff --git a/test/state.cpp b/test/state.cpp index 5202aff22..1c8f4301a 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -251,6 +251,39 @@ BOOST_AUTO_TEST_CASE(stCreateTest) } } +BOOST_AUTO_TEST_CASE(stRandom) +{ + string testPath = dev::test::getTestPath(); + testPath += "/StateTests/RandomTests"; + + vector testFiles; + boost::filesystem::directory_iterator iterator(testPath); + for(; iterator != boost::filesystem::directory_iterator(); ++iterator) + if (boost::filesystem::is_regular_file(iterator->path()) && iterator->path().extension() == ".json") + testFiles.push_back(iterator->path()); + + for (auto& path: testFiles) + { + try + { + cnote << "Testing ..." << path.filename(); + json_spirit::mValue v; + string s = asString(dev::contents(path.string())); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); + json_spirit::read_string(s, v); + dev::test::doStateTests(v, false); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e)); + } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed test with Exception: " << _e.what()); + } + } +} + BOOST_AUTO_TEST_CASE(userDefinedFileState) { dev::test::userDefinedTest("--singletest", dev::test::doStateTests); From 741194a2f50c317d221015f730aa6b9410cc7278 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 11:36:46 +0100 Subject: [PATCH 03/49] remove boost test lib macros from check random state test --- test/checkRandomStateTest.cpp | 42 ++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/test/checkRandomStateTest.cpp b/test/checkRandomStateTest.cpp index 29ccc2eb0..90a88d57e 100644 --- a/test/checkRandomStateTest.cpp +++ b/test/checkRandomStateTest.cpp @@ -73,7 +73,6 @@ bool doStateTest(mValue& v) for (auto& i: v.get_obj()) { - //cerr << i.first << endl; mObject& o = i.second.get_obj(); assert(o.count("env") > 0); @@ -103,7 +102,6 @@ bool doStateTest(mValue& v) assert(o.count("post") > 0); assert(o.count("out") > 0); - //checkOutput(output, o); int j = 0; if (o["out"].type() == array_type) @@ -132,20 +130,17 @@ bool doStateTest(mValue& v) //checkLog(theState.pending().size() ? theState.log(0) : LogEntries(), importer.m_environment.sub.logs); eth::LogEntries logs = theState.pending().size() ? theState.log(0) : eth::LogEntries(); - //checkLog(logs, importer.m_environment.sub.logs); + if (assertsEqual(logs.size(), importer.m_environment.sub.logs.size())) + return 1; + + for (size_t i = 0; i < logs.size(); ++i) { - if (assertsEqual(logs.size(), importer.m_environment.sub.logs.size())) + if (assertsEqual(logs[i].address, importer.m_environment.sub.logs[i].address)) + return 1; + if (assertsEqual(logs[i].topics, importer.m_environment.sub.logs[i].topics)) + return 1; + if (asserts(logs[i].data == importer.m_environment.sub.logs[i].data)) return 1; - - for (size_t i = 0; i < logs.size(); ++i) - { - if (assertsEqual(logs[i].address, importer.m_environment.sub.logs[i].address)) - return 1; - if (assertsEqual(logs[i].topics, importer.m_environment.sub.logs[i].topics)) - return 1; - if (asserts(logs[i].data == importer.m_environment.sub.logs[i].data)) - return 1; - } } // check addresses @@ -160,12 +155,23 @@ bool doStateTest(mValue& v) BOOST_ERROR("Missing expected address " << expectedAddr); else { - BOOST_CHECK_MESSAGE(importer.m_statePost.balance(expectedAddr) == theState.balance(expectedAddr), expectedAddr << ": incorrect balance " << theState.balance(expectedAddr) << ", expected " << importer.m_statePost.balance(expectedAddr)); - BOOST_CHECK_MESSAGE(importer.m_statePost.transactionsFrom(expectedAddr) == theState.transactionsFrom(expectedAddr), expectedAddr << ": incorrect txCount " << theState.transactionsFrom(expectedAddr) << ", expected " << importer.m_statePost.transactionsFrom(expectedAddr)); - BOOST_CHECK_MESSAGE(importer.m_statePost.code(expectedAddr) == theState.code(expectedAddr), expectedAddr << ": incorrect code"); + if (importer.m_statePost.balance(expectedAddr) != theState.balance(expectedAddr)) + { + cout << expectedAddr << ": incorrect balance " << theState.balance(expectedAddr) << ", expected " << importer.m_statePost.balance(expectedAddr); + return 1; + } + if (importer.m_statePost.transactionsFrom(expectedAddr) != theState.transactionsFrom(expectedAddr)) + { + cout << expectedAddr << ": incorrect txCount " << theState.transactionsFrom(expectedAddr) << ", expected " << importer.m_statePost.transactionsFrom(expectedAddr); + return 1; + } + if (importer.m_statePost.code(expectedAddr) != theState.code(expectedAddr)) + { + cout << expectedAddr << ": incorrect code"; + return 1; + } //checkStorage(importer.m_statePost.storage(expectedAddr), theState.storage(expectedAddr), expectedAddr); - map _resultStore = theState.storage(expectedAddr); for (auto&& expectedStorePair : importer.m_statePost.storage(expectedAddr)) From 77ea8e2fce1e7cf6e11d3deccc50da469c25f84d Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 11:42:16 +0100 Subject: [PATCH 04/49] remove unneccessary dependencies --- test/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 45f83e5e3..d7761b8d3 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,9 +20,9 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp) -add_executable(createRandomStateTest createRandomStateTest.cpp state.cpp TestHelper.cpp) +add_executable(createRandomStateTest createRandomStateTest.cpp TestHelper.cpp) add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp) -add_executable(checkRandomStateTest checkRandomStateTest.cpp state.cpp TestHelper.cpp) +add_executable(checkRandomStateTest checkRandomStateTest.cpp TestHelper.cpp) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) From 38a8a25322c037ab5fdd6b23beb6e08a33d80018 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 11:54:11 +0100 Subject: [PATCH 05/49] style fix --- test/checkRandomStateTest.cpp | 12 +++++++----- test/checkRandomVMTest.cpp | 6 +++--- test/createRandomVMTest.cpp | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/test/checkRandomStateTest.cpp b/test/checkRandomStateTest.cpp index 90a88d57e..4c07c3cf9 100644 --- a/test/checkRandomStateTest.cpp +++ b/test/checkRandomStateTest.cpp @@ -14,7 +14,7 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file checkRandomTest.cpp +/** @file checkRandomStateTest.cpp * @author Christoph Jentzsch * @date 2015 * Check a random test and return 0/1 for success or failure. To be used for efficiency in the random test simulation. @@ -33,7 +33,7 @@ using namespace json_spirit; using namespace dev::test; using namespace dev; -bool doStateTest(mValue& v); +bool doStateTest(mValue& _v); int main(int argc, char *argv[]) { @@ -67,11 +67,11 @@ int main(int argc, char *argv[]) return ret; } -bool doStateTest(mValue& v) +bool doStateTest(mValue& _v) { eth::VMFactory::setKind(eth::VMKind::JIT); - for (auto& i: v.get_obj()) + for (auto& i: _v.get_obj()) { mObject& o = i.second.get_obj(); @@ -152,7 +152,9 @@ bool doStateTest(mValue& v) auto& expectedAddr = expectedPair.first; auto resultAddrIt = resultAddrs.find(expectedAddr); if (resultAddrIt == resultAddrs.end()) - BOOST_ERROR("Missing expected address " << expectedAddr); + { + cout << "Missing expected address " << expectedAddr; + return 1; else { if (importer.m_statePost.balance(expectedAddr) != theState.balance(expectedAddr)) diff --git a/test/checkRandomVMTest.cpp b/test/checkRandomVMTest.cpp index e3442d438..c96357714 100644 --- a/test/checkRandomVMTest.cpp +++ b/test/checkRandomVMTest.cpp @@ -32,7 +32,7 @@ using namespace json_spirit; using namespace dev::test; using namespace dev; -bool doVMTest(mValue& v); +bool doVMTest(mValue& _v); int main(int argc, char *argv[]) { @@ -66,11 +66,11 @@ int main(int argc, char *argv[]) return ret; } -bool doVMTest(mValue& v) +bool doVMTest(mValue& _v) { eth::VMFactory::setKind(eth::VMKind::JIT); - for (auto& i: v.get_obj()) + for (auto& i: _v.get_obj()) { cnote << i.first; mObject& o = i.second.get_obj(); diff --git a/test/createRandomVMTest.cpp b/test/createRandomVMTest.cpp index 55e023759..de81099fe 100644 --- a/test/createRandomVMTest.cpp +++ b/test/createRandomVMTest.cpp @@ -41,7 +41,7 @@ using namespace std; using namespace json_spirit; using namespace dev; -void doMyTests(json_spirit::mValue& v); +void doMyTests(json_spirit::mValue& _v); int main(int argc, char *argv[]) { @@ -127,11 +127,11 @@ int main(int argc, char *argv[]) return 0; } -void doMyTests(json_spirit::mValue& v) +void doMyTests(json_spirit::mValue& _v) { eth::VMFactory::setKind(eth::VMKind::Interpreter); - for (auto& i: v.get_obj()) + for (auto& i: _v.get_obj()) { cnote << i.first; mObject& o = i.second.get_obj(); From 20654a1f71f0b871635e2babd6e5c024c1bf36b0 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 12:49:52 +0100 Subject: [PATCH 06/49] random state test optmization --- test/checkRandomStateTest.cpp | 1 + test/createRandomStateTest.cpp | 15 +++++++++++---- test/stSystemOperationsTestFiller.json | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/test/checkRandomStateTest.cpp b/test/checkRandomStateTest.cpp index 4c07c3cf9..ed12b7dc4 100644 --- a/test/checkRandomStateTest.cpp +++ b/test/checkRandomStateTest.cpp @@ -155,6 +155,7 @@ bool doStateTest(mValue& _v) { cout << "Missing expected address " << expectedAddr; return 1; + } else { if (importer.m_statePost.balance(expectedAddr) != theState.balance(expectedAddr)) diff --git a/test/createRandomStateTest.cpp b/test/createRandomStateTest.cpp index 06a332e0e..6b24f1216 100644 --- a/test/createRandomStateTest.cpp +++ b/test/createRandomStateTest.cpp @@ -87,10 +87,10 @@ int main(int argc, char *argv[]) "randomStatetest" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "256", - "currentGasLimit" : "1000000", + "currentDifficulty" : "0x945304eb96065b2a98b57a48a06ae28d285a71b5", + "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", "currentNumber" : "0", - "currentTimestamp" : 1, + "currentTimestamp" : "1", "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" }, "pre" : { @@ -101,6 +101,13 @@ int main(int argc, char *argv[]) "storage" : { } }, + "945304eb96065b2a98b57a48a06ae28d285a71b5" : { + "balance" : "46", + "code" : "0x6000355415600957005b60203560003555", + "nonce" : "0", + "storage" : { + } + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "code" : "0x", @@ -110,7 +117,7 @@ int main(int argc, char *argv[]) } }, "transaction" : { - "data" : "", + "data" : "0x42", "gasLimit" : "400000", "gasPrice" : "1", "nonce" : "0", diff --git a/test/stSystemOperationsTestFiller.json b/test/stSystemOperationsTestFiller.json index 7460ca94e..e26308e28 100644 --- a/test/stSystemOperationsTestFiller.json +++ b/test/stSystemOperationsTestFiller.json @@ -389,7 +389,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) (MSTORE 32 0xaaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffaa ) [[ 0 ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 23 0 64 64 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { @@ -410,7 +410,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", From 440edfd2448391bf840544407342ff4dff10ed3f Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 4 Mar 2015 11:41:15 +0100 Subject: [PATCH 07/49] start of cleanup --- libsolidity/Token.h | 99 +++++++++++++++---------------------------- libsolidity/Types.cpp | 2 +- 2 files changed, 34 insertions(+), 67 deletions(-) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 85979b566..7c1de60bb 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -253,75 +253,42 @@ namespace solidity K(UInt248, "uint248", 0) \ K(UInt256, "uint256", 0) \ K(Hash, "hash", 0) \ - K(Hash8, "hash8", 0) \ - K(Hash16, "hash16", 0) \ - K(Hash24, "hash24", 0) \ - K(Hash32, "hash32", 0) \ - K(Hash40, "hash40", 0) \ - K(Hash48, "hash48", 0) \ - K(Hash56, "hash56", 0) \ - K(Hash64, "hash64", 0) \ - K(Hash72, "hash72", 0) \ - K(Hash80, "hash80", 0) \ - K(Hash88, "hash88", 0) \ - K(Hash96, "hash96", 0) \ - K(Hash104, "hash104", 0) \ - K(Hash112, "hash112", 0) \ - K(Hash120, "hash120", 0) \ - K(Hash128, "hash128", 0) \ - K(Hash136, "hash136", 0) \ - K(Hash144, "hash144", 0) \ - K(Hash152, "hash152", 0) \ - K(Hash160, "hash160", 0) \ - K(Hash168, "hash168", 0) \ - K(Hash176, "hash178", 0) \ - K(Hash184, "hash184", 0) \ - K(Hash192, "hash192", 0) \ - K(Hash200, "hash200", 0) \ - K(Hash208, "hash208", 0) \ - K(Hash216, "hash216", 0) \ - K(Hash224, "hash224", 0) \ - K(Hash232, "hash232", 0) \ - K(Hash240, "hash240", 0) \ - K(Hash248, "hash248", 0) \ - K(Hash256, "hash256", 0) \ + K(Bytes, "bytes", 0) \ + K(Bytes8, "bytes8", 0) \ + K(Bytes16, "bytes16", 0) \ + K(Bytes24, "bytes24", 0) \ + K(Bytes32, "bytes32", 0) \ + K(Bytes40, "bytes40", 0) \ + K(Bytes48, "bytes48", 0) \ + K(Bytes56, "bytes56", 0) \ + K(Bytes64, "bytes64", 0) \ + K(Bytes72, "bytes72", 0) \ + K(Bytes80, "bytes80", 0) \ + K(Bytes88, "bytes88", 0) \ + K(Bytes96, "bytes96", 0) \ + K(Bytes104, "bytes104", 0) \ + K(Bytes112, "bytes112", 0) \ + K(Bytes120, "bytes120", 0) \ + K(Bytes128, "bytes128", 0) \ + K(Bytes136, "bytes136", 0) \ + K(Bytes144, "bytes144", 0) \ + K(Bytes152, "bytes152", 0) \ + K(Bytes160, "bytes160", 0) \ + K(Bytes168, "bytes168", 0) \ + K(Bytes176, "bytes178", 0) \ + K(Bytes184, "bytes184", 0) \ + K(Bytes192, "bytes192", 0) \ + K(Bytes200, "bytes200", 0) \ + K(Bytes208, "bytes208", 0) \ + K(Bytes216, "bytes216", 0) \ + K(Bytes224, "bytes224", 0) \ + K(Bytes232, "bytes232", 0) \ + K(Bytes240, "bytes240", 0) \ + K(Bytes248, "bytes248", 0) \ + K(Bytes256, "bytes256", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ - K(Bytes, "bytes", 0) \ K(StringType, "string", 0) \ - K(String0, "string0", 0) \ - K(String1, "string1", 0) \ - K(String2, "string2", 0) \ - K(String3, "string3", 0) \ - K(String4, "string4", 0) \ - K(String5, "string5", 0) \ - K(String6, "string6", 0) \ - K(String7, "string7", 0) \ - K(String8, "string8", 0) \ - K(String9, "string9", 0) \ - K(String10, "string10", 0) \ - K(String11, "string11", 0) \ - K(String12, "string12", 0) \ - K(String13, "string13", 0) \ - K(String14, "string14", 0) \ - K(String15, "string15", 0) \ - K(String16, "string16", 0) \ - K(String17, "string17", 0) \ - K(String18, "string18", 0) \ - K(String19, "string19", 0) \ - K(String20, "string20", 0) \ - K(String21, "string21", 0) \ - K(String22, "string22", 0) \ - K(String23, "string23", 0) \ - K(String24, "string24", 0) \ - K(String25, "string25", 0) \ - K(String26, "string26", 0) \ - K(String27, "string27", 0) \ - K(String28, "string28", 0) \ - K(String29, "string29", 0) \ - K(String30, "string30", 0) \ - K(String31, "string31", 0) \ - K(String32, "string32", 0) \ K(Text, "text", 0) \ K(Real, "real", 0) \ K(UReal, "ureal", 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 454d79d9b..73cd09d6f 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -39,7 +39,7 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) { solAssert(Token::isElementaryTypeName(_typeToken), "Elementary type name expected."); - if (Token::Int <= _typeToken && _typeToken <= Token::Hash256) + if (Token::Int <= _typeToken && _typeToken <= Token::Bytes256) { int offset = _typeToken - Token::Int; int bytes = offset % 33; From 4340d4867a914c78f24aff6ece0de7aff2e88068 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 4 Mar 2015 17:43:40 +0100 Subject: [PATCH 08/49] More changes towards getting rid of HashXX --- libsolidity/ExpressionCompiler.cpp | 4 ++-- libsolidity/Token.h | 4 +--- libsolidity/Types.cpp | 29 +++++++++++------------------ libsolidity/Types.h | 4 ++-- 4 files changed, 16 insertions(+), 25 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 129261120..91a59b2d0 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -131,7 +131,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con // conversion from string to hash. no need to clean the high bit // only to shift right because of opposite alignment IntegerType const& targetIntegerType = dynamic_cast(_targetType); - solAssert(targetIntegerType.isHash(), "Only conversion between String and Hash is allowed."); + solAssert(targetIntegerType.isBytes(), "Only conversion between String and Bytes is allowed."); solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV; } @@ -164,7 +164,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con // only to shift left because of opposite alignment StaticStringType const& targetStringType = dynamic_cast(_targetType); IntegerType const& typeOnStack = dynamic_cast(_typeOnStack); - solAssert(typeOnStack.isHash(), "Only conversion between String and Hash is allowed."); + solAssert(typeOnStack.isBytes(), "Only conversion between String and Bytes is allowed."); solAssert(typeOnStack.getNumBits() == targetStringType.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBits())) << eth::Instruction::MUL; } diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 7c1de60bb..d7f56aa42 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -252,8 +252,6 @@ namespace solidity K(UInt240, "uint240", 0) \ K(UInt248, "uint248", 0) \ K(UInt256, "uint256", 0) \ - K(Hash, "hash", 0) \ - K(Bytes, "bytes", 0) \ K(Bytes8, "bytes8", 0) \ K(Bytes16, "bytes16", 0) \ K(Bytes24, "bytes24", 0) \ @@ -286,10 +284,10 @@ namespace solidity K(Bytes240, "bytes240", 0) \ K(Bytes248, "bytes248", 0) \ K(Bytes256, "bytes256", 0) \ + K(Bytes, "bytes", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ K(StringType, "string", 0) \ - K(Text, "text", 0) \ K(Real, "real", 0) \ K(UReal, "ureal", 0) \ T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 73cd09d6f..daf7c03e1 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -49,14 +49,12 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) return make_shared(bytes * 8, modifier == 0 ? IntegerType::Modifier::Signed : modifier == 1 ? IntegerType::Modifier::Unsigned : - IntegerType::Modifier::Hash); + IntegerType::Modifier::Bytes); } else if (_typeToken == Token::Address) return make_shared(0, IntegerType::Modifier::Address); else if (_typeToken == Token::Bool) return make_shared(); - else if (Token::String0 <= _typeToken && _typeToken <= Token::String32) - return make_shared(int(_typeToken) - int(Token::String0)); else if (_typeToken == Token::Bytes) return make_shared(ArrayType::Location::Storage); else @@ -159,8 +157,8 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const return false; if (isAddress()) return convertTo.isAddress(); - else if (isHash()) - return convertTo.isHash(); + else if (isBytes()) + return convertTo.isBytes(); else if (isSigned()) return convertTo.isSigned(); else @@ -169,14 +167,9 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - if (_convertTo.getCategory() == Category::String) - { - StaticStringType const& convertTo = dynamic_cast(_convertTo); - return isHash() && (m_bits == convertTo.getNumBytes() * 8); - } return _convertTo.getCategory() == getCategory() || - _convertTo.getCategory() == Category::Contract || - _convertTo.getCategory() == Category::Enum; + _convertTo.getCategory() == Category::Contract || + _convertTo.getCategory() == Category::Enum; } TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const @@ -190,8 +183,8 @@ TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const // "~" is ok for all other types else if (_operator == Token::BitNot) return shared_from_this(); - // nothing else for hashes - else if (isHash()) + // nothing else for bytes + else if (isBytes()) return TypePointer(); // for non-hash integers, we allow +, -, ++ and -- else if (_operator == Token::Add || _operator == Token::Sub || @@ -214,7 +207,7 @@ string IntegerType::toString() const { if (isAddress()) return "address"; - string prefix = isHash() ? "hash" : (isSigned() ? "int" : "uint"); + string prefix = isBytes() ? "bytes" : (isSigned() ? "int" : "uint"); return prefix + dev::toString(m_bits); } @@ -231,10 +224,10 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe if (Token::isCompareOp(_operator)) return commonType; - // Nothing else can be done with addresses, but hashes can receive bit operators + // Nothing else can be done with addresses, but bytes can receive bit operators if (commonType->isAddress()) return TypePointer(); - else if (commonType->isHash() && !Token::isBitOp(_operator)) + else if (commonType->isBytes() && !Token::isBitOp(_operator)) return TypePointer(); else return commonType; @@ -461,7 +454,7 @@ bool StaticStringType::isExplicitlyConvertibleTo(Type const& _convertTo) const if (_convertTo.getCategory() == Category::Integer) { IntegerType const& convertTo = dynamic_cast(_convertTo); - if (convertTo.isHash() && (m_bytes * 8 == convertTo.getNumBits())) + if (convertTo.isBytes() && (m_bytes * 8 == convertTo.getNumBits())) return true; } diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 6cef8d64a..3d67720c7 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -165,7 +165,7 @@ class IntegerType: public Type public: enum class Modifier { - Unsigned, Signed, Hash, Address + Unsigned, Signed, Bytes, Address }; virtual Category getCategory() const override { return Category::Integer; } @@ -186,7 +186,7 @@ public: virtual std::string toString() const override; int getNumBits() const { return m_bits; } - bool isHash() const { return m_modifier == Modifier::Hash || m_modifier == Modifier::Address; } + bool isBytes() const { return m_modifier == Modifier::Bytes || m_modifier == Modifier::Address; } bool isAddress() const { return m_modifier == Modifier::Address; } bool isSigned() const { return m_modifier == Modifier::Signed; } From 72f2397ebe24336537ccdb24587ee8df3910e178 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 5 Mar 2015 16:54:55 +0100 Subject: [PATCH 09/49] Replacing StaticStringType with FixedBytesType --- libsolidity/CompilerUtils.cpp | 7 +-- libsolidity/ExpressionCompiler.cpp | 26 ++++----- libsolidity/Types.cpp | 84 +++++++++++++++++++----------- libsolidity/Types.h | 27 +++++----- 4 files changed, 84 insertions(+), 60 deletions(-) diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 8a26b5d17..e11b6b4f6 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -177,8 +177,9 @@ void CompilerUtils::computeHashStatic(Type const& _type, bool _padToWordBoundari unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries) { - unsigned numBytes = _type.getCalldataEncodedSize(_padToWordBoundaries); - bool leftAligned = _type.getCategory() == Type::Category::String; + unsigned _encodedSize = _type.getCalldataEncodedSize(); + unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; + bool leftAligned = _type.getCategory() == Type::Category::FixedBytes; if (numBytes == 0) m_context << eth::Instruction::POP << u256(0); else @@ -202,7 +203,7 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const { unsigned numBytes = _type.getCalldataEncodedSize(_padToWordBoundaries); - bool leftAligned = _type.getCategory() == Type::Category::String; + bool leftAligned = _type.getCategory() == Type::Category::FixedBytes; if (numBytes == 0) m_context << eth::Instruction::POP; else diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 91a59b2d0..51e1fd0a9 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -123,23 +123,23 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con Type::Category stackTypeCategory = _typeOnStack.getCategory(); Type::Category targetTypeCategory = _targetType.getCategory(); - if (stackTypeCategory == Type::Category::String) + if (stackTypeCategory == Type::Category::FixedBytes) { - StaticStringType const& typeOnStack = dynamic_cast(_typeOnStack); + FixedBytesType const& typeOnStack = dynamic_cast(_typeOnStack); if (targetTypeCategory == Type::Category::Integer) { - // conversion from string to hash. no need to clean the high bit + // conversion from string to bytes. no need to clean the high bit // only to shift right because of opposite alignment IntegerType const& targetIntegerType = dynamic_cast(_targetType); - solAssert(targetIntegerType.isBytes(), "Only conversion between String and Bytes is allowed."); + solAssert(targetIntegerType.isAddress(), "Only conversion between Address and FixedBytes is allowed."); solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV; } else { - // clear lower-order bytes for conversion to shorter strings - we always clean - solAssert(targetTypeCategory == Type::Category::String, "Invalid type conversion requested."); - StaticStringType const& targetType = dynamic_cast(_targetType); + // clear lower-order bytes for conversion to shorter bytes - we always clean + solAssert(targetTypeCategory == Type::Category::FixedBytes, "Invalid type conversion requested."); + FixedBytesType const& targetType = dynamic_cast(_targetType); if (targetType.getNumBytes() < typeOnStack.getNumBytes()) { if (targetType.getNumBytes() == 0) @@ -158,14 +158,14 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con stackTypeCategory == Type::Category::Contract || stackTypeCategory == Type::Category::IntegerConstant) { - if (targetTypeCategory == Type::Category::String && stackTypeCategory == Type::Category::Integer) + if (targetTypeCategory == Type::Category::FixedBytes && stackTypeCategory == Type::Category::Integer) { - // conversion from hash to string. no need to clean the high bit + // conversion from bytes to string. no need to clean the high bit // only to shift left because of opposite alignment - StaticStringType const& targetStringType = dynamic_cast(_targetType); + FixedBytesType const& targetBytesType = dynamic_cast(_targetType); IntegerType const& typeOnStack = dynamic_cast(_typeOnStack); - solAssert(typeOnStack.isBytes(), "Only conversion between String and Bytes is allowed."); - solAssert(typeOnStack.getNumBits() == targetStringType.getNumBytes() * 8, "The size should be the same."); + solAssert(typeOnStack.isAddress(), "Only conversion between Address and Bytes is allowed."); + solAssert(typeOnStack.getNumBits() == targetBytesType.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBits())) << eth::Instruction::MUL; } else if (targetTypeCategory == Type::Category::Enum) @@ -870,7 +870,7 @@ void ExpressionCompiler::endVisit(Literal const& _literal) { case Type::Category::IntegerConstant: case Type::Category::Bool: - case Type::Category::String: + case Type::Category::FixedBytes: m_context << _literal.getType()->literalValue(&_literal); break; default: diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index daf7c03e1..aadd884b5 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -46,10 +46,18 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) if (bytes == 0) bytes = 32; int modifier = offset / 33; - return make_shared(bytes * 8, - modifier == 0 ? IntegerType::Modifier::Signed : - modifier == 1 ? IntegerType::Modifier::Unsigned : - IntegerType::Modifier::Bytes); + switch(modifier) + { + case 0: + return make_shared(bytes * 8, IntegerType::Modifier::Signed); + case 1: + return make_shared(bytes * 8, IntegerType::Modifier::Unsigned); + case 2: + return make_shared(bytes); + default: + solAssert(false, "Unexpected modifier value. Should never happen"); + return TypePointer(); + } } else if (_typeToken == Token::Address) return make_shared(0, IntegerType::Modifier::Address); @@ -121,7 +129,7 @@ TypePointer Type::forLiteral(Literal const& _literal) return make_shared(_literal); case Token::StringLiteral: //@todo put larger strings into dynamic strings - return StaticStringType::smallestTypeForLiteral(_literal.getValue()); + return FixedBytesType::smallestTypeForLiteral(_literal.getValue()); default: return shared_ptr(); } @@ -157,8 +165,6 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const return false; if (isAddress()) return convertTo.isAddress(); - else if (isBytes()) - return convertTo.isBytes(); else if (isSigned()) return convertTo.isSigned(); else @@ -183,10 +189,7 @@ TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const // "~" is ok for all other types else if (_operator == Token::BitNot) return shared_from_this(); - // nothing else for bytes - else if (isBytes()) - return TypePointer(); - // for non-hash integers, we allow +, -, ++ and -- + // for non-address integers, we allow +, -, ++ and -- else if (_operator == Token::Add || _operator == Token::Sub || _operator == Token::Inc || _operator == Token::Dec || _operator == Token::After) @@ -207,7 +210,7 @@ string IntegerType::toString() const { if (isAddress()) return "address"; - string prefix = isBytes() ? "bytes" : (isSigned() ? "int" : "uint"); + string prefix = isSigned() ? "int" : "uint"; return prefix + dev::toString(m_bits); } @@ -224,13 +227,7 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe if (Token::isCompareOp(_operator)) return commonType; - // Nothing else can be done with addresses, but bytes can receive bit operators - if (commonType->isAddress()) - return TypePointer(); - else if (commonType->isBytes() && !Token::isBitOp(_operator)) - return TypePointer(); - else - return commonType; + return TypePointer(); } const MemberList IntegerType::AddressMemberList = @@ -426,50 +423,75 @@ shared_ptr IntegerConstantType::getIntegerType() const : IntegerType::Modifier::Unsigned); } -shared_ptr StaticStringType::smallestTypeForLiteral(string const& _literal) +shared_ptr FixedBytesType::smallestTypeForLiteral(string const& _literal) { if (_literal.length() <= 32) - return make_shared(_literal.length()); - return shared_ptr(); + return make_shared(_literal.length()); + return shared_ptr(); } -StaticStringType::StaticStringType(int _bytes): m_bytes(_bytes) +FixedBytesType::FixedBytesType(int _bytes): m_bytes(_bytes) { solAssert(m_bytes >= 0 && m_bytes <= 32, "Invalid byte number for static string type: " + dev::toString(m_bytes)); } -bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const +bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const { if (_convertTo.getCategory() != getCategory()) return false; - StaticStringType const& convertTo = dynamic_cast(_convertTo); + FixedBytesType const& convertTo = dynamic_cast(_convertTo); return convertTo.m_bytes >= m_bytes; } -bool StaticStringType::isExplicitlyConvertibleTo(Type const& _convertTo) const +bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const { if (_convertTo.getCategory() == getCategory()) return true; if (_convertTo.getCategory() == Category::Integer) { IntegerType const& convertTo = dynamic_cast(_convertTo); - if (convertTo.isBytes() && (m_bytes * 8 == convertTo.getNumBits())) + if (m_bytes * 8 == convertTo.getNumBits()) return true; } return false; } -bool StaticStringType::operator==(Type const& _other) const +TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const +{ + // "delete" and "~" is okay for FixedBytesType + if (_operator == Token::Delete) + return make_shared(); + else if (_operator == Token::BitNot) + return shared_from_this(); + + return TypePointer(); +} + +TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const +{ + auto commonType = dynamic_pointer_cast(Type::commonType(shared_from_this(), _other)); + + if (!commonType) + return TypePointer(); + + // FixedBytes can be compared and have bitwise operators applied to them + if (Token::isCompareOp(_operator) || Token::isBitOp(_operator)) + return commonType; + + return TypePointer(); +} + +bool FixedBytesType::operator==(Type const& _other) const { if (_other.getCategory() != getCategory()) return false; - StaticStringType const& other = dynamic_cast(_other); + FixedBytesType const& other = dynamic_cast(_other); return other.m_bytes == m_bytes; } -u256 StaticStringType::literalValue(const Literal* _literal) const +u256 FixedBytesType::literalValue(const Literal* _literal) const { solAssert(_literal, ""); u256 value = 0; @@ -1117,7 +1139,7 @@ MagicType::MagicType(MagicType::Kind _kind): case Kind::Block: m_members = MemberList({{"coinbase", make_shared(0, IntegerType::Modifier::Address)}, {"timestamp", make_shared(256)}, - {"blockhash", make_shared(strings{"uint"}, strings{"hash"}, FunctionType::Location::BlockHash)}, + {"blockhash", make_shared(strings{"uint"}, strings{"bytes"}, FunctionType::Location::BlockHash)}, {"difficulty", make_shared(256)}, {"number", make_shared(256)}, {"gaslimit", make_shared(256)}}); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 3d67720c7..6517cf070 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -77,12 +77,12 @@ public: enum class Category { Integer, IntegerConstant, Bool, Real, Array, - String, Contract, Struct, Function, Enum, + FixedBytes, Contract, Struct, Function, Enum, Mapping, Void, TypeType, Modifier, Magic }; - ///@{ - ///@name Factory functions + /// @{ + /// @name Factory functions /// Factory functions that convert an AST @ref TypeName to a Type. static TypePointer fromElementaryTypeName(Token::Value _typeToken); static TypePointer fromElementaryTypeName(std::string const& _name); @@ -158,14 +158,14 @@ protected: }; /** - * Any kind of integer type including hash and address. + * Any kind of integer type including address. */ class IntegerType: public Type { public: enum class Modifier { - Unsigned, Signed, Bytes, Address + Unsigned, Signed, Address }; virtual Category getCategory() const override { return Category::Integer; } @@ -186,7 +186,6 @@ public: virtual std::string toString() const override; int getNumBits() const { return m_bits; } - bool isBytes() const { return m_modifier == Modifier::Bytes || m_modifier == Modifier::Address; } bool isAddress() const { return m_modifier == Modifier::Address; } bool isSigned() const { return m_modifier == Modifier::Signed; } @@ -232,27 +231,29 @@ private: }; /** - * String type with fixed length, up to 32 bytes. + * Bytes type with fixed length of up to 32 bytes */ -class StaticStringType: public Type +class FixedBytesType: public Type { public: - virtual Category getCategory() const override { return Category::String; } + virtual Category getCategory() const override { return Category::FixedBytes; } - /// @returns the smallest string type for the given literal or an empty pointer + /// @returns the smallest bytes type for the given literal or an empty pointer /// if no type fits. - static std::shared_ptr smallestTypeForLiteral(std::string const& _literal); + static std::shared_ptr smallestTypeForLiteral(std::string const& _literal); - explicit StaticStringType(int _bytes); + explicit FixedBytesType(int _bytes); virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; virtual bool operator==(Type const& _other) const override; + virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; + virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override; virtual unsigned getCalldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; } virtual bool isValueType() const override { return true; } - virtual std::string toString() const override { return "string" + dev::toString(m_bytes); } + virtual std::string toString() const override { return "bytes" + dev::toString(m_bytes); } virtual u256 literalValue(Literal const* _literal) const override; int getNumBytes() const { return m_bytes; } From 4700b1b2c884715f5ddb80268ff52bf81d0f58ee Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Fri, 6 Mar 2015 17:20:00 +0100 Subject: [PATCH 10/49] Fixes after rebasing on top of develop --- libsolidity/AST.cpp | 2 +- libsolidity/CompilerUtils.cpp | 3 +-- libsolidity/LValue.cpp | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 79b755e97..46c44995b 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -671,7 +671,7 @@ void IndexAccess::checkTypeRequirements() BOOST_THROW_EXCEPTION(createTypeError("Index expression cannot be omitted.")); m_index->expectType(IntegerType(256)); if (type.isByteArray()) - m_type = make_shared(8, IntegerType::Modifier::Hash); + m_type = make_shared(1); else m_type = type.getBaseType(); m_isLValue = type.getLocation() != ArrayType::Location::CallData; diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index e11b6b4f6..7b078e03e 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -177,8 +177,7 @@ void CompilerUtils::computeHashStatic(Type const& _type, bool _padToWordBoundari unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries) { - unsigned _encodedSize = _type.getCalldataEncodedSize(); - unsigned numBytes = _padToWordBoundaries ? getPaddedSize(_encodedSize) : _encodedSize; + unsigned numBytes = _type.getCalldataEncodedSize(_padToWordBoundaries); bool leftAligned = _type.getCategory() == Type::Category::FixedBytes; if (numBytes == 0) m_context << eth::Instruction::POP << u256(0); diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index a036be80b..db3cd56be 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -234,7 +234,7 @@ void StorageItem::setToZero(SourceLocation const&, bool _removeReference) const } /// Used in StorageByteArrayElement -static IntegerType byteType(8, IntegerType::Modifier::Hash); +static FixedBytesType byteType(1); StorageByteArrayElement::StorageByteArrayElement(CompilerContext& _compilerContext): LValue(_compilerContext, byteType) From 9d7ebacabc43a580905682c6e46df490a7b55201 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 9 Mar 2015 13:49:53 +0100 Subject: [PATCH 11/49] Bytes Tokens properly named and NameAndTypeResolution tests work --- libsolidity/Token.h | 64 +++++++++++++------------- libsolidity/Types.cpp | 7 ++- test/SolidityNameAndTypeResolution.cpp | 31 +++++++------ 3 files changed, 53 insertions(+), 49 deletions(-) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index d7f56aa42..2a4d22495 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -252,39 +252,39 @@ namespace solidity K(UInt240, "uint240", 0) \ K(UInt248, "uint248", 0) \ K(UInt256, "uint256", 0) \ - K(Bytes8, "bytes8", 0) \ - K(Bytes16, "bytes16", 0) \ - K(Bytes24, "bytes24", 0) \ - K(Bytes32, "bytes32", 0) \ - K(Bytes40, "bytes40", 0) \ - K(Bytes48, "bytes48", 0) \ - K(Bytes56, "bytes56", 0) \ - K(Bytes64, "bytes64", 0) \ - K(Bytes72, "bytes72", 0) \ - K(Bytes80, "bytes80", 0) \ - K(Bytes88, "bytes88", 0) \ - K(Bytes96, "bytes96", 0) \ - K(Bytes104, "bytes104", 0) \ - K(Bytes112, "bytes112", 0) \ - K(Bytes120, "bytes120", 0) \ - K(Bytes128, "bytes128", 0) \ - K(Bytes136, "bytes136", 0) \ - K(Bytes144, "bytes144", 0) \ - K(Bytes152, "bytes152", 0) \ - K(Bytes160, "bytes160", 0) \ - K(Bytes168, "bytes168", 0) \ - K(Bytes176, "bytes178", 0) \ - K(Bytes184, "bytes184", 0) \ - K(Bytes192, "bytes192", 0) \ - K(Bytes200, "bytes200", 0) \ - K(Bytes208, "bytes208", 0) \ - K(Bytes216, "bytes216", 0) \ - K(Bytes224, "bytes224", 0) \ - K(Bytes232, "bytes232", 0) \ - K(Bytes240, "bytes240", 0) \ - K(Bytes248, "bytes248", 0) \ - K(Bytes256, "bytes256", 0) \ K(Bytes, "bytes", 0) \ + K(Bytes1, "bytes1", 0) \ + K(Bytes2, "bytes2", 0) \ + K(Bytes3, "bytes3", 0) \ + K(Bytes4, "bytes4", 0) \ + K(Bytes5, "bytes5", 0) \ + K(Bytes6, "bytes6", 0) \ + K(Bytes7, "bytes7", 0) \ + K(Bytes8, "bytes8", 0) \ + K(Bytes9, "bytes9", 0) \ + K(Bytes10, "bytes10", 0) \ + K(Bytes11, "bytes11", 0) \ + K(Bytes12, "bytes12", 0) \ + K(Bytes13, "bytes13", 0) \ + K(Bytes14, "bytes14", 0) \ + K(Bytes15, "bytes15", 0) \ + K(Bytes16, "bytes16", 0) \ + K(Bytes17, "bytes17", 0) \ + K(Bytes18, "bytes18", 0) \ + K(Bytes19, "bytes19", 0) \ + K(Bytes20, "bytes20", 0) \ + K(Bytes21, "bytes21", 0) \ + K(Bytes22, "bytes22", 0) \ + K(Bytes23, "bytes23", 0) \ + K(Bytes24, "bytes24", 0) \ + K(Bytes25, "bytes25", 0) \ + K(Bytes26, "bytes26", 0) \ + K(Bytes27, "bytes27", 0) \ + K(Bytes28, "bytes28", 0) \ + K(Bytes29, "bytes29", 0) \ + K(Bytes30, "bytes30", 0) \ + K(Bytes31, "bytes31", 0) \ + K(Bytes32, "bytes32", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ K(StringType, "string", 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index aadd884b5..9f307cbc6 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -39,7 +39,7 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) { solAssert(Token::isElementaryTypeName(_typeToken), "Elementary type name expected."); - if (Token::Int <= _typeToken && _typeToken <= Token::Bytes256) + if (Token::Int <= _typeToken && _typeToken <= Token::Bytes32) { int offset = _typeToken - Token::Int; int bytes = offset % 33; @@ -226,8 +226,11 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe // All integer types can be compared if (Token::isCompareOp(_operator)) return commonType; + // Nothing else can be done with addresses, but hashes can receive bit operators + if (commonType->isAddress()) + return TypePointer(); - return TypePointer(); + return commonType; } const MemberList IntegerType::AddressMemberList = diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index c3a4a3377..3dfac0a3e 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -75,6 +75,7 @@ static FunctionTypePointer const& retrieveFunctionBySignature(ContractDefinition FixedHash<4> hash(dev::sha3(_signature)); return _contract->getInterfaceFunctions()[hash]; } + } BOOST_AUTO_TEST_SUITE(SolidityNameAndTypeResolution) @@ -353,7 +354,7 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature) " ret = arg1 + arg2;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(sourceUnit = parseTextAndResolveNames(text)); + ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed"); for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { @@ -366,16 +367,16 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases) { ASTPointer sourceUnit; char const* text = "contract Test {\n" - " function boo(uint arg1, hash arg2, address arg3) returns (uint ret) {\n" + " function boo(uint arg1, bytes32 arg2, address arg3) returns (uint ret) {\n" " ret = 5;\n" " }\n" "}\n"; - BOOST_CHECK_NO_THROW(sourceUnit = parseTextAndResolveNames(text)); + ETH_TEST_REQUIRE_NO_THROW(sourceUnit = parseTextAndResolveNames(text), "Parsing and name Resolving failed"); for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { auto functions = contract->getDefinedFunctions(); - BOOST_CHECK_EQUAL("boo(uint256,hash256,address)", functions[0]->getCanonicalSignature()); + BOOST_CHECK_EQUAL("boo(uint256,bytes32,address)", functions[0]->getCanonicalSignature()); } } @@ -537,7 +538,7 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation) contract B { function f() mod1(2, true) mod2("0123456") { } modifier mod1(uint a, bool b) { if (b) _ } - modifier mod2(string7 a) { while (a == "1234567") _ } + modifier mod2(bytes7 a) { while (a == "1234567") _ } } )"; ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); @@ -558,9 +559,9 @@ BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters) { char const* text = R"( contract B { - function f(uint8 a) mod1(a, true) mod2(r) returns (string7 r) { } + function f(uint8 a) mod1(a, true) mod2(r) returns (bytes7 r) { } modifier mod1(uint a, bool b) { if (b) _ } - modifier mod2(string7 a) { while (a == "1234567") _ } + modifier mod2(bytes7 a) { while (a == "1234567") _ } } )"; ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); @@ -631,8 +632,8 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) " uint64(2);\n" " }\n" "uint256 public foo;\n" - "mapping(uint=>string4) public map;\n" - "mapping(uint=>mapping(uint=>string4)) public multiple_map;\n" + "mapping(uint=>bytes4) public map;\n" + "mapping(uint=>mapping(uint=>bytes4)) public multiple_map;\n" "}\n"; ASTPointer source; @@ -650,7 +651,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) auto params = function->getParameterTypeNames(); BOOST_CHECK_EQUAL(params.at(0), "uint256"); returnParams = function->getReturnParameterTypeNames(); - BOOST_CHECK_EQUAL(returnParams.at(0), "string4"); + BOOST_CHECK_EQUAL(returnParams.at(0), "bytes4"); BOOST_CHECK(function->isConstant()); function = retrieveFunctionBySignature(contract, "multiple_map(uint256,uint256)"); @@ -659,7 +660,7 @@ BOOST_AUTO_TEST_CASE(state_variable_accessors) BOOST_CHECK_EQUAL(params.at(0), "uint256"); BOOST_CHECK_EQUAL(params.at(1), "uint256"); returnParams = function->getReturnParameterTypeNames(); - BOOST_CHECK_EQUAL(returnParams.at(0), "string4"); + BOOST_CHECK_EQUAL(returnParams.at(0), "bytes4"); BOOST_CHECK(function->isConstant()); } @@ -800,7 +801,7 @@ BOOST_AUTO_TEST_CASE(event) { char const* text = R"( contract c { - event e(uint indexed a, string3 indexed s, bool indexed b); + event e(uint indexed a, bytes3 indexed s, bool indexed b); function f() { e(2, "abc", true); } })"; ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); @@ -810,7 +811,7 @@ BOOST_AUTO_TEST_CASE(event_too_many_indexed) { char const* text = R"( contract c { - event e(uint indexed a, string3 indexed b, bool indexed c, uint indexed d); + event e(uint indexed a, bytes3 indexed b, bool indexed c, uint indexed d); function f() { e(2, "abc", true); } })"; BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); @@ -820,7 +821,7 @@ BOOST_AUTO_TEST_CASE(event_call) { char const* text = R"( contract c { - event e(uint a, string3 indexed s, bool indexed b); + event e(uint a, bytes3 indexed s, bool indexed b); function f() { e(2, "abc", true); } })"; ETH_TEST_CHECK_NO_THROW(parseTextAndResolveNames(text), "Parsing and Name Resolving Failed"); @@ -830,7 +831,7 @@ BOOST_AUTO_TEST_CASE(event_inheritance) { char const* text = R"( contract base { - event e(uint a, string3 indexed s, bool indexed b); + event e(uint a, bytes3 indexed s, bool indexed b); } contract c is base { function f() { e(2, "abc", true); } From bb205103c459208df0c4cd9952154afbe8236dc9 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 9 Mar 2015 17:48:33 +0100 Subject: [PATCH 12/49] Most EndToEndTests are now compliant with the Bytes renaming --- libsolidity/CompilerStack.cpp | 8 +- libsolidity/ExpressionCompiler.cpp | 2 - libsolidity/GlobalContext.cpp | 18 ++-- libsolidity/Token.h | 3 +- libsolidity/Types.cpp | 13 ++- test/SolidityEndToEndTest.cpp | 140 +++++++++++++------------ test/SolidityNameAndTypeResolution.cpp | 105 +++++++++++++++++++ test/SolidityParser.cpp | 4 +- 8 files changed, 203 insertions(+), 90 deletions(-) diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index a878bb61a..55ec0cb59 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -41,14 +41,14 @@ namespace solidity { const map StandardSources = map{ - {"coin", R"(import "CoinReg";import "Config";import "configUser";contract coin is configUser{function coin(string3 name, uint denom) {CoinReg(Config(configAddr()).lookup(3)).register(name, denom);}})"}, + {"coin", R"(import "CoinReg";import "Config";import "configUser";contract coin is configUser{function coin(bytes3 name, uint denom) {CoinReg(Config(configAddr()).lookup(3)).register(name, denom);}})"}, {"Coin", R"(contract Coin{function isApprovedFor(address _target,address _proxy)constant returns(bool _r){}function isApproved(address _proxy)constant returns(bool _r){}function sendCoinFrom(address _from,uint256 _val,address _to){}function coinBalanceOf(address _a)constant returns(uint256 _r){}function sendCoin(uint256 _val,address _to){}function coinBalance()constant returns(uint256 _r){}function approve(address _a){}})"}, - {"CoinReg", R"(contract CoinReg{function count()constant returns(uint256 r){}function info(uint256 i)constant returns(address addr,string3 name,uint256 denom){}function register(string3 name,uint256 denom){}function unregister(){}})"}, + {"CoinReg", R"(contract CoinReg{function count()constant returns(uint256 r){}function info(uint256 i)constant returns(address addr,bytes3 name,uint256 denom){}function register(bytes3 name,uint256 denom){}function unregister(){}})"}, {"configUser", R"(contract configUser{function configAddr()constant returns(address a){ return 0xc6d9d2cd449a754c494264e1809c50e34d64562b;}})"}, {"Config", R"(contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}})"}, {"mortal", R"(import "owned";contract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }})"}, - {"named", R"(import "Config";import "NameReg";import "configUser";contract named is configUser {function named(string32 name) {NameReg(Config(configAddr()).lookup(1)).register(name);}})"}, - {"NameReg", R"(contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}})"}, + {"named", R"(import "Config";import "NameReg";import "configUser";contract named is configUser {function named(bytes32 name) {NameReg(Config(configAddr()).lookup(1)).register(name);}})"}, + {"NameReg", R"(contract NameReg{function register(bytes32 name){}function addressOf(bytes32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(bytes32 name){}})"}, {"owned", R"(contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;})"}, {"service", R"(import "Config";import "configUser";contract service is configUser{function service(uint _n){Config(configAddr()).register(_n, this);}})"}, {"std", R"(import "owned";import "mortal";import "Config";import "configUser";import "NameReg";import "named";)"} diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 51e1fd0a9..089ebc32d 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -131,7 +131,6 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con // conversion from string to bytes. no need to clean the high bit // only to shift right because of opposite alignment IntegerType const& targetIntegerType = dynamic_cast(_targetType); - solAssert(targetIntegerType.isAddress(), "Only conversion between Address and FixedBytes is allowed."); solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV; } @@ -164,7 +163,6 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con // only to shift left because of opposite alignment FixedBytesType const& targetBytesType = dynamic_cast(_targetType); IntegerType const& typeOnStack = dynamic_cast(_typeOnStack); - solAssert(typeOnStack.isAddress(), "Only conversion between Address and Bytes is allowed."); solAssert(typeOnStack.getNumBits() == targetBytesType.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBits())) << eth::Instruction::MUL; } diff --git a/libsolidity/GlobalContext.cpp b/libsolidity/GlobalContext.cpp index 411e99abb..7bd9c8dfa 100644 --- a/libsolidity/GlobalContext.cpp +++ b/libsolidity/GlobalContext.cpp @@ -41,23 +41,23 @@ m_magicVariables(vector>{make_shared< make_shared("suicide", make_shared(strings{"address"}, strings{}, FunctionType::Location::Suicide)), make_shared("sha3", - make_shared(strings(), strings{"hash"}, FunctionType::Location::SHA3, true)), + make_shared(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)), make_shared("log0", - make_shared(strings{"hash"},strings{}, FunctionType::Location::Log0)), + make_shared(strings{"bytes32"}, strings{}, FunctionType::Location::Log0)), make_shared("log1", - make_shared(strings{"hash", "hash"},strings{}, FunctionType::Location::Log1)), + make_shared(strings{"bytes32", "bytes32"}, strings{}, FunctionType::Location::Log1)), make_shared("log2", - make_shared(strings{"hash", "hash", "hash"},strings{}, FunctionType::Location::Log2)), + make_shared(strings{"bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Location::Log2)), make_shared("log3", - make_shared(strings{"hash", "hash", "hash", "hash"},strings{}, FunctionType::Location::Log3)), + make_shared(strings{"bytes32", "bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Location::Log3)), make_shared("log4", - make_shared(strings{"hash", "hash", "hash", "hash", "hash"},strings{}, FunctionType::Location::Log4)), + make_shared(strings{"bytes32", "bytes32", "bytes32", "bytes32", "bytes32"}, strings{}, FunctionType::Location::Log4)), make_shared("sha256", - make_shared(strings(), strings{"hash"}, FunctionType::Location::SHA256, true)), + make_shared(strings(), strings{"bytes32"}, FunctionType::Location::SHA256, true)), make_shared("ecrecover", - make_shared(strings{"hash", "hash8", "hash", "hash"}, strings{"address"}, FunctionType::Location::ECRecover)), + make_shared(strings{"bytes32", "bytes1", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Location::ECRecover)), make_shared("ripemd160", - make_shared(strings(), strings{"hash160"}, FunctionType::Location::RIPEMD160, true))}) + make_shared(strings(), strings{"bytes20"}, FunctionType::Location::RIPEMD160, true))}) { } diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 2a4d22495..c439c79ee 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -252,7 +252,7 @@ namespace solidity K(UInt240, "uint240", 0) \ K(UInt248, "uint248", 0) \ K(UInt256, "uint256", 0) \ - K(Bytes, "bytes", 0) \ + K(Bytes0, "bytes0", 0) \ K(Bytes1, "bytes1", 0) \ K(Bytes2, "bytes2", 0) \ K(Bytes3, "bytes3", 0) \ @@ -285,6 +285,7 @@ namespace solidity K(Bytes30, "bytes30", 0) \ K(Bytes31, "bytes31", 0) \ K(Bytes32, "bytes32", 0) \ + K(Bytes, "bytes", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ K(StringType, "string", 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 9f307cbc6..6039895af 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -37,13 +37,15 @@ namespace solidity TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) { - solAssert(Token::isElementaryTypeName(_typeToken), "Elementary type name expected."); + char const* tokenCstr = Token::toString(_typeToken); + solAssert(Token::isElementaryTypeName(_typeToken), + "Expected an elementary type name but got " + ((tokenCstr) ? std::string(Token::toString(_typeToken)) : "")); if (Token::Int <= _typeToken && _typeToken <= Token::Bytes32) { int offset = _typeToken - Token::Int; int bytes = offset % 33; - if (bytes == 0) + if (bytes == 0 && _typeToken != Token::Bytes0) bytes = 32; int modifier = offset / 33; switch(modifier) @@ -173,6 +175,11 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const { + if (_convertTo.getCategory() == Category::FixedBytes) + { + FixedBytesType const& convertTo = dynamic_cast(_convertTo); + return (m_bits == convertTo.getNumBytes() * 8); + } return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::Contract || _convertTo.getCategory() == Category::Enum; @@ -436,7 +443,7 @@ shared_ptr FixedBytesType::smallestTypeForLiteral(string const& FixedBytesType::FixedBytesType(int _bytes): m_bytes(_bytes) { solAssert(m_bytes >= 0 && m_bytes <= 32, - "Invalid byte number for static string type: " + dev::toString(m_bytes)); + "Invalid byte number for fixed bytes type: " + dev::toString(m_bytes)); } bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 3205c038a..d9ea6ed98 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -507,23 +507,23 @@ BOOST_AUTO_TEST_CASE(small_signed_types) BOOST_AUTO_TEST_CASE(strings) { char const* sourceCode = "contract test {\n" - " function fixed() returns(string32 ret) {\n" + " function fixed() returns(bytes32 ret) {\n" " return \"abc\\x00\\xff__\";\n" " }\n" - " function pipeThrough(string2 small, bool one) returns(string16 large, bool oneRet) {\n" + " function pipeThrough(bytes2 small, bool one) returns(bytes16 large, bool oneRet) {\n" " oneRet = one;\n" " large = small;\n" " }\n" "}\n"; compileAndRun(sourceCode); BOOST_CHECK(callContractFunction("fixed()") == encodeArgs(string("abc\0\xff__", 7))); - BOOST_CHECK(callContractFunction("pipeThrough(string2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true)); + BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true)); } - +# BOOST_AUTO_TEST_CASE(empty_string_on_stack) { char const* sourceCode = "contract test {\n" - " function run(string0 empty, uint8 inp) returns(uint16 a, string0 b, string4 c) {\n" + " function run(bytes0 empty, uint8 inp) returns(uint16 a, bytes0 b, bytes4 c) {\n" " var x = \"abc\";\n" " var y = \"\";\n" " var z = inp;\n" @@ -531,7 +531,7 @@ BOOST_AUTO_TEST_CASE(empty_string_on_stack) " }\n" "}\n"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("run(string0,uint8)", string(), byte(0x02)) == encodeArgs(0x2, string(""), string("abc\0"))); + BOOST_CHECK(callContractFunction("run(bytes0,uint8)", string(), byte(0x02)) == encodeArgs(0x2, string(""), string("abc\0"))); } BOOST_AUTO_TEST_CASE(state_smoke_test) @@ -948,8 +948,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" + " bytes6 public name;\n" + " bytes32 public a_hash;\n" " address public an_address;\n" " function test() {\n" " data = 8;\n" @@ -971,7 +971,7 @@ BOOST_AUTO_TEST_CASE(multiple_elementary_accessors) BOOST_AUTO_TEST_CASE(complex_accessors) { char const* sourceCode = "contract test {\n" - " mapping(uint256 => string4) public to_string_map;\n" + " mapping(uint256 => bytes4) 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" @@ -1076,96 +1076,96 @@ 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) +BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_fixed_bytes_smaller_size) { char const* sourceCode = R"( contract Test { - function pipeTrough(string3 input) returns (string3 ret) { - return string3(input); + function pipeTrough(bytes3 input) returns (bytes2 ret) { + return bytes2(input); } })"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("pipeTrough(string3)", "abc") == encodeArgs("abc")); + BOOST_CHECK(callContractFunction("pipeTrough(bytes3)", "abc") == encodeArgs("ab")); } -BOOST_AUTO_TEST_CASE(convert_hash_to_string_same_size) +BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_same_size) { char const* sourceCode = R"( contract Test { - function hashToString(hash h) returns (string32 s) { - return string32(h); + function uintToBytes(uint256 h) returns (bytes32 s) { + return bytes32(h); } })"; compileAndRun(sourceCode); u256 a("0x6162630000000000000000000000000000000000000000000000000000000000"); - BOOST_CHECK(callContractFunction("hashToString(hash256)", a) == encodeArgs(a)); + BOOST_CHECK(callContractFunction("uintToBytes(uint256)", a) == encodeArgs(a)); } -BOOST_AUTO_TEST_CASE(convert_hash_to_string_different_size) +BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_different_size) { char const* sourceCode = R"( contract Test { - function hashToString(hash160 h) returns (string20 s) { - return string20(h); + function uintToBytes(uint160 h) returns (bytes20 s) { + return bytes20(h); } })"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("hashToString(hash160)", u160("0x6161626361626361626361616263616263616263")) == - encodeArgs(string("aabcabcabcaabcabcabc"))); + BOOST_CHECK(callContractFunction("uintToBytes(uint160)", + u160("0x6161626361626361626361616263616263616263")) == encodeArgs(string("aabcabcabcaabcabcabc"))); } -BOOST_AUTO_TEST_CASE(convert_string_to_hash_same_size) +BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_same_size) { char const* sourceCode = R"( contract Test { - function stringToHash(string32 s) returns (hash h) { - return hash(s); + function bytesToUint(bytes32 s) returns (uint256 h) { + return uint(s); } })"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("stringToHash(string32)", string("abc2")) == - encodeArgs(u256("0x6162633200000000000000000000000000000000000000000000000000000000"))); + BOOST_CHECK(callContractFunction("bytesToUint(bytes32)", string("abc2")) == + encodeArgs(u256("0x6162633200000000000000000000000000000000000000000000000000000000"))); } -BOOST_AUTO_TEST_CASE(convert_string_to_hash_different_size) +BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_different_size) { char const* sourceCode = R"( contract Test { - function stringToHash(string20 s) returns (hash160 h) { - return hash160(s); + function bytesToUint(bytes20 s) returns (uint160 h) { + return uint160(s); } })"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("stringToHash(string20)", string("aabcabcabcaabcabcabc")) == - encodeArgs(u160("0x6161626361626361626361616263616263616263"))); + BOOST_CHECK(callContractFunction("bytesToUint(bytes20)", string("aabcabcabcaabcabcabc")) == + encodeArgs(u160("0x6161626361626361626361616263616263616263"))); } -BOOST_AUTO_TEST_CASE(convert_string_to_hash_different_min_size) +BOOST_AUTO_TEST_CASE(convert_fixed_bytes_to_uint_different_min_size) { char const* sourceCode = R"( contract Test { - function stringToHash(string1 s) returns (hash8 h) { - return hash8(s); + function bytesToUint(bytes1 s) returns (uint8 h) { + return uint8(s); } })"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("stringToHash(string1)", string("a")) == - encodeArgs(u256("0x61"))); + BOOST_CHECK(callContractFunction("bytesToUint(bytes1)", string("a")) == + encodeArgs(u256("0x61"))); } -BOOST_AUTO_TEST_CASE(convert_hash_to_string_different_min_size) +BOOST_AUTO_TEST_CASE(convert_uint_to_fixed_bytes_different_min_size) { char const* sourceCode = R"( contract Test { - function HashToString(hash8 h) returns (string1 s) { - return string1(h); + function UintToBytes(uint8 h) returns (bytes1 s) { + return bytes1(h); } })"; compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("HashToString(hash8)", u256("0x61")) == - encodeArgs(string("a"))); + BOOST_CHECK(callContractFunction("UintToBytes(uint8)", u256("0x61")) == + encodeArgs(string("a"))); } BOOST_AUTO_TEST_CASE(send_ether) @@ -1182,12 +1182,14 @@ BOOST_AUTO_TEST_CASE(send_ether) BOOST_CHECK(callContractFunction("a(address,uint256)", address, amount) == encodeArgs(1)); BOOST_CHECK_EQUAL(m_state.balance(address), amount); } - +// TODO: Note that these tests should actually be +// simply converting integer constant to bytes32. This conversion is not there +// yet. When it's implemented DO change the tests too BOOST_AUTO_TEST_CASE(log0) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log0(1);\n" + " log0(bytes32(int(1)));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1202,7 +1204,7 @@ BOOST_AUTO_TEST_CASE(log1) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log1(1, 2);\n" + " log1(bytes32(int(1)), bytes32(int(2)));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1218,7 +1220,7 @@ BOOST_AUTO_TEST_CASE(log2) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log2(1, 2, 3);\n" + " log2(bytes32(int(1)), bytes32(int(2)), bytes32(int(3)));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1235,7 +1237,7 @@ BOOST_AUTO_TEST_CASE(log3) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log3(1, 2, 3, 4);\n" + " log3(bytes32(int(1)), bytes32(int(2)), bytes32(int(3)), bytes32(int(4)));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1252,7 +1254,7 @@ BOOST_AUTO_TEST_CASE(log4) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log4(1, 2, 3, 4, 5);\n" + " log4(bytes32(int(1)), bytes32(int(2)), bytes32(int(3)), bytes32(int(4)), bytes32(int(5)));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1269,7 +1271,7 @@ BOOST_AUTO_TEST_CASE(log_in_constructor) { char const* sourceCode = "contract test {\n" " function test() {\n" - " log1(1, 2);\n" + " log1(bytes32(int(1)), bytes32(int(2)));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1299,7 +1301,7 @@ BOOST_AUTO_TEST_CASE(suicide) BOOST_AUTO_TEST_CASE(sha3) { char const* sourceCode = "contract test {\n" - " function a(hash input) returns (hash sha3hash) {\n" + " function a(bytes32 input) returns (bytes32 sha3hash) {\n" " return sha3(input);\n" " }\n" "}\n"; @@ -1308,15 +1310,15 @@ BOOST_AUTO_TEST_CASE(sha3) { return dev::sha3(toBigEndian(_x)); }; - testSolidityAgainstCpp("a(hash256)", f, u256(4)); - testSolidityAgainstCpp("a(hash256)", f, u256(5)); - testSolidityAgainstCpp("a(hash256)", f, u256(-1)); + testSolidityAgainstCpp("a(bytes32)", f, u256(4)); + testSolidityAgainstCpp("a(bytes32)", f, u256(5)); + testSolidityAgainstCpp("a(bytes32)", f, u256(-1)); } BOOST_AUTO_TEST_CASE(sha256) { char const* sourceCode = "contract test {\n" - " function a(hash input) returns (hash sha256hash) {\n" + " function a(bytes32 input) returns (bytes32 sha256hash) {\n" " return sha256(input);\n" " }\n" "}\n"; @@ -1327,15 +1329,15 @@ BOOST_AUTO_TEST_CASE(sha256) dev::sha256(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32)); return ret; }; - testSolidityAgainstCpp("a(hash256)", f, u256(4)); - testSolidityAgainstCpp("a(hash256)", f, u256(5)); - testSolidityAgainstCpp("a(hash256)", f, u256(-1)); + testSolidityAgainstCpp("a(bytes32)", f, u256(4)); + testSolidityAgainstCpp("a(bytes32)", f, u256(5)); + testSolidityAgainstCpp("a(bytes32)", f, u256(-1)); } BOOST_AUTO_TEST_CASE(ripemd) { char const* sourceCode = "contract test {\n" - " function a(hash input) returns (hash sha256hash) {\n" + " function a(bytes32 input) returns (bytes32 sha256hash) {\n" " return ripemd160(input);\n" " }\n" "}\n"; @@ -1346,16 +1348,16 @@ BOOST_AUTO_TEST_CASE(ripemd) dev::ripemd160(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32)); return u256(ret) >> (256 - 160); }; - testSolidityAgainstCpp("a(hash256)", f, u256(4)); - testSolidityAgainstCpp("a(hash256)", f, u256(5)); - testSolidityAgainstCpp("a(hash256)", f, u256(-1)); + testSolidityAgainstCpp("a(bytes32)", f, u256(4)); + testSolidityAgainstCpp("a(bytes32)", f, u256(5)); + testSolidityAgainstCpp("a(bytes32)", f, u256(-1)); } BOOST_AUTO_TEST_CASE(ecrecover) { char const* sourceCode = "contract test {\n" - " function a(hash h, uint8 v, hash r, hash s) returns (address addr) {\n" - " return ecrecover(h, v, r, s);\n" + " function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) returns (address addr) {\n" + " return ecrecover(h, bytes1(v), r, s);\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1364,7 +1366,7 @@ BOOST_AUTO_TEST_CASE(ecrecover) u256 r("0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f"); u256 s("0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549"); u160 addr("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"); - BOOST_CHECK(callContractFunction("a(hash256,uint8,hash256,hash256)", h, v, r, s) == encodeArgs(addr)); + BOOST_CHECK(callContractFunction("a(bytes32,uint8,bytes32,bytes32)", h, v, r, s) == encodeArgs(addr)); } BOOST_AUTO_TEST_CASE(inter_contract_calls) @@ -2090,13 +2092,13 @@ 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) { + event Deposit(address indexed _from, bytes32 indexed _id, uint _value); + function deposit(bytes32 _id, bool _manually) { if (_manually) { - hash s = 0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20; - log3(msg.value, s, hash32(msg.sender), _id); + bytes32 s = uint(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20); + log3(msg.value, s, bytes4(msg.sender), _id); } else - Deposit(hash32(msg.sender), _id, msg.value); + Deposit(bytes4(msg.sender), _id, msg.value); } } )"; diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 3dfac0a3e..a73c937f9 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1288,6 +1288,111 @@ BOOST_AUTO_TEST_CASE(storage_variable_initialization_with_incorrect_type_string) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) +{ + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int) == *make_shared(256, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int8) == *make_shared(8, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int16) == *make_shared(16, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int24) == *make_shared(24, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int32) == *make_shared(32, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int40) == *make_shared(40, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int48) == *make_shared(48, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int56) == *make_shared(56, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int64) == *make_shared(64, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int72) == *make_shared(72, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int80) == *make_shared(80, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int88) == *make_shared(88, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int96) == *make_shared(96, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int104) == *make_shared(104, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int112) == *make_shared(112, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int120) == *make_shared(120, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int128) == *make_shared(128, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int136) == *make_shared(136, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int144) == *make_shared(144, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int152) == *make_shared(152, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int160) == *make_shared(160, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int168) == *make_shared(168, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int176) == *make_shared(176, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int184) == *make_shared(184, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int192) == *make_shared(192, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int200) == *make_shared(200, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int208) == *make_shared(208, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int216) == *make_shared(216, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int224) == *make_shared(224, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int232) == *make_shared(232, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int240) == *make_shared(240, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int248) == *make_shared(248, IntegerType::Modifier::Signed)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Int256) == *make_shared(256, IntegerType::Modifier::Signed)); + + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt8) == *make_shared(8, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt16) == *make_shared(16, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt24) == *make_shared(24, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt32) == *make_shared(32, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt40) == *make_shared(40, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt48) == *make_shared(48, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt56) == *make_shared(56, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt64) == *make_shared(64, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt72) == *make_shared(72, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt80) == *make_shared(80, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt88) == *make_shared(88, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt96) == *make_shared(96, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt104) == *make_shared(104, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt112) == *make_shared(112, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt120) == *make_shared(120, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt128) == *make_shared(128, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt136) == *make_shared(136, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt144) == *make_shared(144, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt152) == *make_shared(152, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt160) == *make_shared(160, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt168) == *make_shared(168, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt176) == *make_shared(176, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt184) == *make_shared(184, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt192) == *make_shared(192, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt200) == *make_shared(200, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt208) == *make_shared(208, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt216) == *make_shared(216, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt224) == *make_shared(224, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt232) == *make_shared(232, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt240) == *make_shared(240, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt248) == *make_shared(248, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt256) == *make_shared(256, IntegerType::Modifier::Unsigned)); + + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes0) == *make_shared(0)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes1) == *make_shared(1)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes2) == *make_shared(2)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes3) == *make_shared(3)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes4) == *make_shared(4)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes5) == *make_shared(5)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes6) == *make_shared(6)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes7) == *make_shared(7)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes8) == *make_shared(8)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes9) == *make_shared(9)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes10) == *make_shared(10)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes11) == *make_shared(11)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes12) == *make_shared(12)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes13) == *make_shared(13)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes14) == *make_shared(14)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes15) == *make_shared(15)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes16) == *make_shared(16)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes17) == *make_shared(17)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes18) == *make_shared(18)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes19) == *make_shared(19)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes20) == *make_shared(20)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes21) == *make_shared(21)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes22) == *make_shared(22)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes23) == *make_shared(23)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes24) == *make_shared(24)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes25) == *make_shared(25)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes26) == *make_shared(26)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes27) == *make_shared(27)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes28) == *make_shared(28)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes29) == *make_shared(29)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes30) == *make_shared(30)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes31) == *make_shared(31)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes32) == *make_shared(32)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 88b86e638..608e1707e 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -307,7 +307,7 @@ BOOST_AUTO_TEST_CASE(mapping_in_struct) " struct test_struct {\n" " address addr;\n" " uint256 count;\n" - " mapping(hash => test_struct) self_reference;\n" + " mapping(bytes32 => test_struct) self_reference;\n" " }\n" "}\n"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(mapping_to_mapping_in_struct) char const* text = "contract test {\n" " struct test_struct {\n" " address addr;\n" - " mapping (uint64 => mapping (hash => uint)) complex_mapping;\n" + " mapping (uint64 => mapping (bytes32 => uint)) complex_mapping;\n" " }\n" "}\n"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); From d9d792a05522adb585e3ab53f9027ef6aec6ed8c Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 10 Mar 2015 18:22:19 +0100 Subject: [PATCH 13/49] Conversion changes after renaming Hash/String to Bytes. - Almost all end to end tests pass. Still needs a little bit of work --- libsolidity/ExpressionCompiler.cpp | 49 +++++++++++++--------- libsolidity/GlobalContext.cpp | 2 +- libsolidity/LValue.cpp | 8 ++-- libsolidity/Types.cpp | 20 +++++---- test/SolidityEndToEndTest.cpp | 66 +++++++++++++++--------------- 5 files changed, 80 insertions(+), 65 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 089ebc32d..f00b2d40c 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -123,16 +123,20 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con Type::Category stackTypeCategory = _typeOnStack.getCategory(); Type::Category targetTypeCategory = _targetType.getCategory(); - if (stackTypeCategory == Type::Category::FixedBytes) + switch (stackTypeCategory) + { + case Type::Category::FixedBytes: { FixedBytesType const& typeOnStack = dynamic_cast(_typeOnStack); if (targetTypeCategory == Type::Category::Integer) { - // conversion from string to bytes. no need to clean the high bit + // conversion from bytes to integer. no need to clean the high bit // only to shift right because of opposite alignment IntegerType const& targetIntegerType = dynamic_cast(_targetType); - solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same."); + // solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV; + if (targetIntegerType.getNumBits() < typeOnStack.getNumBytes() * 8) + appendTypeConversion(IntegerType(typeOnStack.getNumBytes() * 8), _targetType, _cleanupNeeded); } else { @@ -150,21 +154,24 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con } } } - else if (stackTypeCategory == Type::Category::Enum) - solAssert(targetTypeCategory == Type::Category::Integer || - targetTypeCategory == Type::Category::Enum, ""); - else if (stackTypeCategory == Type::Category::Integer || - stackTypeCategory == Type::Category::Contract || - stackTypeCategory == Type::Category::IntegerConstant) - { - if (targetTypeCategory == Type::Category::FixedBytes && stackTypeCategory == Type::Category::Integer) + break; + case Type::Category::Enum: + solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Enum, ""); + break; + case Type::Category::Integer: + case Type::Category::Contract: + case Type::Category::IntegerConstant: + if (targetTypeCategory == Type::Category::FixedBytes) { + solAssert(stackTypeCategory == Type::Category::Integer || stackTypeCategory == Type::Category::IntegerConstant, + "Invalid conversion to FixedBytesType requested."); // conversion from bytes to string. no need to clean the high bit // only to shift left because of opposite alignment FixedBytesType const& targetBytesType = dynamic_cast(_targetType); - IntegerType const& typeOnStack = dynamic_cast(_typeOnStack); - solAssert(typeOnStack.getNumBits() == targetBytesType.getNumBytes() * 8, "The size should be the same."); - m_context << (u256(1) << (256 - typeOnStack.getNumBits())) << eth::Instruction::MUL; + if (auto typeOnStack = dynamic_cast(&_typeOnStack)) + if (targetBytesType.getNumBytes() * 8 > typeOnStack->getNumBits()) + appendHighBitsCleanup(*typeOnStack); + m_context << (u256(1) << (256 - targetBytesType.getNumBytes() * 8)) << eth::Instruction::MUL; } else if (targetTypeCategory == Type::Category::Enum) // just clean @@ -174,7 +181,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con solAssert(targetTypeCategory == Type::Category::Integer || targetTypeCategory == Type::Category::Contract, ""); IntegerType addressType(0, IntegerType::Modifier::Address); IntegerType const& targetType = targetTypeCategory == Type::Category::Integer - ? dynamic_cast(_targetType) : addressType; + ? dynamic_cast(_targetType) : addressType; if (stackTypeCategory == Type::Category::IntegerConstant) { IntegerConstantType const& constType = dynamic_cast(_typeOnStack); @@ -186,7 +193,7 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con else { IntegerType const& typeOnStack = stackTypeCategory == Type::Category::Integer - ? dynamic_cast(_typeOnStack) : addressType; + ? dynamic_cast(_typeOnStack) : addressType; // Widening: clean up according to source type width // Non-widening and force: clean up according to target type bits if (targetType.getNumBits() > typeOnStack.getNumBits()) @@ -195,10 +202,12 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con appendHighBitsCleanup(targetType); } } - } - else if (_typeOnStack != _targetType) + break; + default: // All other types should not be convertible to non-equal types. - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Invalid type conversion requested.")); + solAssert(_typeOnStack == _targetType, "Invalid type conversion requested."); + break; + } } bool ExpressionCompiler::visit(Assignment const& _assignment) @@ -773,7 +782,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) // no lvalue, just retrieve the value m_context << eth::Instruction::ADD << eth::Instruction::CALLDATALOAD - << u256(0) << eth::Instruction::BYTE; + << ((u256(1) << (256 - 8)) - 1) << eth::Instruction::AND; break; case ArrayType::Location::Memory: solAssert(false, "Memory lvalues not yet implemented."); diff --git a/libsolidity/GlobalContext.cpp b/libsolidity/GlobalContext.cpp index 7bd9c8dfa..80cebd760 100644 --- a/libsolidity/GlobalContext.cpp +++ b/libsolidity/GlobalContext.cpp @@ -55,7 +55,7 @@ m_magicVariables(vector>{make_shared< make_shared("sha256", make_shared(strings(), strings{"bytes32"}, FunctionType::Location::SHA256, true)), make_shared("ecrecover", - make_shared(strings{"bytes32", "bytes1", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Location::ECRecover)), + make_shared(strings{"bytes32", "uint8", "bytes32", "bytes32"}, strings{"address"}, FunctionType::Location::ECRecover)), make_shared("ripemd160", make_shared(strings(), strings{"bytes20"}, FunctionType::Location::RIPEMD160, true))}) { diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index db3cd56be..7b8374b81 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -246,10 +246,11 @@ void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove) // stack: ref byte_number if (_remove) m_context << eth::Instruction::SWAP1 << eth::Instruction::SLOAD - << eth::Instruction::SWAP1 << eth::Instruction::BYTE; + << eth::Instruction::SWAP1 << eth::Instruction::BYTE ; else m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD << eth::Instruction::DUP2 << eth::Instruction::BYTE; + m_context << (u256(1) << (256 - 8)) << eth::Instruction::MUL; } void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, bool _move) const @@ -265,8 +266,9 @@ void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, boo m_context << eth::Instruction::DUP2 << u256(0xff) << eth::Instruction::MUL << eth::Instruction::NOT << eth::Instruction::AND; // stack: value ref (1<<(32-byte_number)) old_full_value_with_cleared_byte - m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP4 << eth::Instruction::MUL - << eth::Instruction::OR; + m_context << eth::Instruction::SWAP1; + m_context << (u256(1) << (256 - 8)) << eth::Instruction::DUP5 << eth::Instruction::DIV + << eth::Instruction::MUL << eth::Instruction::OR; // stack: value ref new_full_value m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE; if (_move) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 6039895af..8524cb8b0 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -175,14 +175,10 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - if (_convertTo.getCategory() == Category::FixedBytes) - { - FixedBytesType const& convertTo = dynamic_cast(_convertTo); - return (m_bits == convertTo.getNumBytes() * 8); - } return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::Contract || - _convertTo.getCategory() == Category::Enum; + _convertTo.getCategory() == Category::Enum || + _convertTo.getCategory() == Category::FixedBytes; } TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const @@ -284,7 +280,15 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal) bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const { - TypePointer integerType = getIntegerType(); + auto integerType = getIntegerType(); + if (_convertTo.getCategory() == Category::FixedBytes) + { + FixedBytesType const& convertTo = dynamic_cast(_convertTo); + if (convertTo.getNumBytes() * 8 >= integerType->getNumBits()) + return true; + return false; + } + return integerType && integerType->isImplicitlyConvertibleTo(_convertTo); } @@ -461,7 +465,7 @@ bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const if (_convertTo.getCategory() == Category::Integer) { IntegerType const& convertTo = dynamic_cast(_convertTo); - if (m_bytes * 8 == convertTo.getNumBits()) + if (m_bytes * 8 <= convertTo.getNumBits()) return true; } diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index d9ea6ed98..b47048272 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -1357,7 +1357,7 @@ BOOST_AUTO_TEST_CASE(ecrecover) { char const* sourceCode = "contract test {\n" " function a(bytes32 h, uint8 v, bytes32 r, bytes32 s) returns (address addr) {\n" - " return ecrecover(h, bytes1(v), r, s);\n" + " return ecrecover(h, v, r, s);\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1526,17 +1526,17 @@ BOOST_AUTO_TEST_CASE(inter_contract_calls_with_local_vars) BOOST_REQUIRE(callContractFunction("callHelper(uint256,uint256)", a, b) == encodeArgs(a * b + 9)); } -BOOST_AUTO_TEST_CASE(strings_in_calls) +BOOST_AUTO_TEST_CASE(fixed_bytes_in_calls) { char const* sourceCode = R"( contract Helper { - function invoke(string3 x, bool stop) returns (string4 ret) { + function invoke(bytes3 x, bool stop) returns (bytes4 ret) { return x; } } contract Main { Helper h; - function callHelper(string2 x, bool stop) returns (string5 ret) { + function callHelper(bytes2 x, bool stop) returns (bytes5 ret) { return h.invoke(x, stop); } function getHelper() returns (address addr) { @@ -1551,21 +1551,21 @@ BOOST_AUTO_TEST_CASE(strings_in_calls) compileAndRun(sourceCode, 0, "Main"); BOOST_REQUIRE(callContractFunction("setHelper(address)", c_helperAddress) == bytes()); BOOST_REQUIRE(callContractFunction("getHelper()", c_helperAddress) == encodeArgs(c_helperAddress)); - BOOST_CHECK(callContractFunction("callHelper(string2,bool)", string("\0a", 2), true) == encodeArgs(string("\0a\0\0\0", 5))); + BOOST_CHECK(callContractFunction("callHelper(bytes2,bool)", string("\0a", 2), true) == encodeArgs(string("\0a\0\0\0", 5))); } BOOST_AUTO_TEST_CASE(constructor_arguments) { char const* sourceCode = R"( contract Helper { - string3 name; + bytes3 name; bool flag; - function Helper(string3 x, bool f) { + function Helper(bytes3 x, bool f) { name = x; flag = f; } - function getName() returns (string3 ret) { return name; } + function getName() returns (bytes3 ret) { return name; } function getFlag() returns (bool ret) { return flag; } } contract Main { @@ -1574,7 +1574,7 @@ BOOST_AUTO_TEST_CASE(constructor_arguments) h = new Helper("abc", true); } function getFlag() returns (bool ret) { return h.getFlag(); } - function getName() returns (string3 ret) { return h.getName(); } + function getName() returns (bytes3 ret) { return h.getName(); } })"; compileAndRun(sourceCode, 0, "Main"); BOOST_REQUIRE(callContractFunction("getFlag()") == encodeArgs(true)); @@ -1585,13 +1585,13 @@ BOOST_AUTO_TEST_CASE(functions_called_by_constructor) { char const* sourceCode = R"( contract Test { - string3 name; + bytes3 name; bool flag; function Test() { setName("abc"); } - function getName() returns (string3 ret) { return name; } - function setName(string3 _name) private { name = _name; } + function getName() returns (bytes3 ret) { return name; } + function setName(bytes3 _name) private { name = _name; } })"; compileAndRun(sourceCode); BOOST_REQUIRE(callContractFunction("getName()") == encodeArgs("abc")); @@ -1699,13 +1699,13 @@ BOOST_AUTO_TEST_CASE(value_for_constructor) { char const* sourceCode = R"( contract Helper { - string3 name; + bytes3 name; bool flag; - function Helper(string3 x, bool f) { + function Helper(bytes3 x, bool f) { name = x; flag = f; } - function getName() returns (string3 ret) { return name; } + function getName() returns (bytes3 ret) { return name; } function getFlag() returns (bool ret) { return flag; } } contract Main { @@ -1714,7 +1714,7 @@ BOOST_AUTO_TEST_CASE(value_for_constructor) h = new Helper.value(10)("abc", true); } function getFlag() returns (bool ret) { return h.getFlag(); } - function getName() returns (string3 ret) { return h.getName(); } + function getName() returns (bytes3 ret) { return h.getName(); } function getBalances() returns (uint me, uint them) { me = this.balance; them = h.balance;} })"; compileAndRun(sourceCode, 22, "Main"); @@ -2095,10 +2095,10 @@ BOOST_AUTO_TEST_CASE(event) event Deposit(address indexed _from, bytes32 indexed _id, uint _value); function deposit(bytes32 _id, bool _manually) { if (_manually) { - bytes32 s = uint(0x50cb9fe53daa9737b786ab3646f04d0150dc50ef4e75f59509d83667ad5adb20); - log3(msg.value, s, bytes4(msg.sender), _id); + bytes32 s = 0x19dacbf83c5de6658e14cbf7bcae5c15eca2eedecf1c66fbca928e4d351bea0f; + log3(bytes32(msg.value), s, bytes32(msg.sender), _id); } else - Deposit(bytes4(msg.sender), _id, msg.value); + Deposit(msg.sender, _id, msg.value); } } )"; @@ -2107,12 +2107,12 @@ BOOST_AUTO_TEST_CASE(event) u256 id(0x1234); for (bool manually: {true, false}) { - callContractFunctionWithValue("deposit(hash256,bool)", value, id, manually); + callContractFunctionWithValue("deposit(bytes32,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[0], dev::sha3(string("Deposit(address,bytes32,uint256)"))); BOOST_CHECK_EQUAL(m_logs[0].topics[1], h256(m_sender)); BOOST_CHECK_EQUAL(m_logs[0].topics[2], h256(id)); } @@ -2141,21 +2141,21 @@ 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); + event Deposit(address _from, bytes32 _id, uint _value, bool _flag); + function deposit(bytes32 _id) { + Deposit(msg.sender, _id, msg.value, true); } } )"; compileAndRun(sourceCode); u256 value(18); u256 id(0x1234); - callContractFunctionWithValue("deposit(hash256)", value, id); + callContractFunctionWithValue("deposit(bytes32)", 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((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)"))); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::sha3(string("Deposit(address,bytes32,uint256,bool)"))); } BOOST_AUTO_TEST_CASE(empty_name_input_parameter_with_named_one) @@ -2189,7 +2189,7 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments) { char const* sourceCode = R"( contract c { - function foo(uint a, uint b, uint c) returns (hash d) + function foo(uint a, uint b, uint c) returns (bytes32 d) { d = sha3(a, b, c); } @@ -2207,7 +2207,7 @@ 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) + function foo(uint a, uint16 b) returns (bytes32 d) { d = sha3(a, b, 145); } @@ -2225,11 +2225,11 @@ BOOST_AUTO_TEST_CASE(sha3_multiple_arguments_with_string_literals) { char const* sourceCode = R"( contract c { - function foo() returns (hash d) + function foo() returns (bytes32 d) { d = sha3("foo"); } - function bar(uint a, uint16 b) returns (hash d) + function bar(uint a, uint16 b) returns (bytes32 d) { d = sha3(a, b, 145, "foo"); } @@ -2256,7 +2256,7 @@ BOOST_AUTO_TEST_CASE(generic_call) contract sender { function doSend(address rec) returns (uint d) { - string4 signature = string4(string32(sha3("receive(uint256)"))); + bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); rec.call.value(2)(signature, 23); return receiver(rec).received(); } @@ -2292,7 +2292,7 @@ BOOST_AUTO_TEST_CASE(bytes_from_calldata_to_memory) { char const* sourceCode = R"( contract C { - function() returns (hash) { + function() returns (bytes32) { return sha3("abc", msg.data); } } @@ -3016,6 +3016,7 @@ BOOST_AUTO_TEST_CASE(bytes_index_access) 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}; + cout << toHex(callContractFunction("direct(bytes,uint256)", u256(array.length()), 32, array)) << endl; BOOST_CHECK(callContractFunction("direct(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193)); @@ -3183,7 +3184,6 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base_base_with_gap) BOOST_CHECK(callContractFunction("m_i()") == encodeArgs(4)); } - BOOST_AUTO_TEST_SUITE_END() } From 912b8569a45212b6fa03462566c92cd92394ba8a Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Mar 2015 11:31:49 +0100 Subject: [PATCH 14/49] Mix changes after rebase - @arkpar should take a look --- mix/CodeModel.cpp | 8 ++++---- mix/CodeModel.h | 3 +-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index bb258334c..28934160a 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -77,15 +77,15 @@ namespace { IntegerType const* it = dynamic_cast(_type); unsigned size = it->getNumBits() / 8; - SolidityType::Type typeCode = it->isAddress() ? SolidityType::Type::Address : it->isHash() ? SolidityType::Type::Hash : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger; + SolidityType::Type typeCode = it->isAddress() ? SolidityType::Type::Address : it->isSigned() ? SolidityType::Type::SignedInteger : SolidityType::Type::UnsignedInteger; return SolidityType { typeCode, size }; } case Type::Category::Bool: return SolidityType { SolidityType::Type::Bool, _type->getSizeOnStack() * 32 }; - case Type::Category::String: + case Type::Category::FixedBytes: { - StaticStringType const* s = dynamic_cast(_type); - return SolidityType { SolidityType::Type::String, static_cast(s->getNumBytes()) }; + FixedBytesType const* s = dynamic_cast(_type); + return SolidityType { SolidityType::Type::FixedBytes, static_cast(s->getNumBytes()) }; } case Type::Category::Contract: return SolidityType { SolidityType::Type::Address, _type->getSizeOnStack() * 32 }; diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 92111996c..0294ca7c3 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -72,10 +72,9 @@ struct SolidityType { SignedInteger, UnsignedInteger, - Hash, Bool, Address, - String, + FixedBytes, }; Type type; unsigned size; //bytes From 81beec48bf21299a9086e6668c660990f7fbb8ef Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Mar 2015 11:38:11 +0100 Subject: [PATCH 15/49] Changes in Solidity Tests to use the new bytesXX type --- test/SolidityABIJSON.cpp | 10 +++++----- test/SolidityInterface.cpp | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/SolidityABIJSON.cpp b/test/SolidityABIJSON.cpp index 5f67a5667..195270138 100644 --- a/test/SolidityABIJSON.cpp +++ b/test/SolidityABIJSON.cpp @@ -339,10 +339,10 @@ BOOST_AUTO_TEST_CASE(inherited) char const* sourceCode = " contract Base { \n" " function baseFunction(uint p) returns (uint i) { return p; } \n" - " event baseEvent(string32 indexed evtArgBase); \n" + " event baseEvent(bytes32 indexed evtArgBase); \n" " } \n" " contract Derived is Base { \n" - " function derivedFunction(string32 p) returns (string32 i) { return p; } \n" + " function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } \n" " event derivedEvent(uint indexed evtArgDerived); \n" " }"; @@ -369,12 +369,12 @@ BOOST_AUTO_TEST_CASE(inherited) "inputs": [{ "name": "p", - "type": "string32" + "type": "bytes32" }], "outputs": [{ "name": "i", - "type": "string32" + "type": "bytes32" }] }, { @@ -394,7 +394,7 @@ BOOST_AUTO_TEST_CASE(inherited) [{ "indexed": true, "name": "evtArgBase", - "type": "string32" + "type": "bytes32" }] }])"; diff --git a/test/SolidityInterface.cpp b/test/SolidityInterface.cpp index ecab64c8c..48e2fd7aa 100644 --- a/test/SolidityInterface.cpp +++ b/test/SolidityInterface.cpp @@ -84,10 +84,10 @@ BOOST_AUTO_TEST_CASE(single_function) BOOST_AUTO_TEST_CASE(single_constant_function) { ContractDefinition const& contract = checkInterface( - "contract test { function f(uint a) constant returns(hash8 x) { 1==2; } }"); + "contract test { function f(uint a) constant returns(bytes1 x) { 1==2; } }"); BOOST_REQUIRE_EQUAL(1, contract.getDefinedFunctions().size()); BOOST_CHECK_EQUAL(getSourcePart(*contract.getDefinedFunctions().front()), - "function f(uint256 a)constant returns(hash8 x){}"); + "function f(uint256 a)constant returns(bytes1 x){}"); } BOOST_AUTO_TEST_CASE(multiple_functions) @@ -128,15 +128,15 @@ BOOST_AUTO_TEST_CASE(inheritance) char const* sourceCode = " contract Base { \n" " function baseFunction(uint p) returns (uint i) { return p; } \n" - " event baseEvent(string32 indexed evtArgBase); \n" + " event baseEvent(bytes32 indexed evtArgBase); \n" " } \n" " contract Derived is Base { \n" - " function derivedFunction(string32 p) returns (string32 i) { return p; } \n" + " function derivedFunction(bytes32 p) returns (bytes32 i) { return p; } \n" " event derivedEvent(uint indexed evtArgDerived); \n" " }"; ContractDefinition const& contract = checkInterface(sourceCode); set expectedFunctions({"function baseFunction(uint256 p)returns(uint256 i){}", - "function derivedFunction(string32 p)returns(string32 i){}"}); + "function derivedFunction(bytes32 p)returns(bytes32 i){}"}); BOOST_REQUIRE_EQUAL(2, contract.getDefinedFunctions().size()); BOOST_CHECK(expectedFunctions == set({getSourcePart(*contract.getDefinedFunctions().at(0)), getSourcePart(*contract.getDefinedFunctions().at(1))})); From 9fa08d179b6b64f75dd87ccef3706c809da63197 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Mar 2015 16:58:25 +0100 Subject: [PATCH 16/49] Fixing byte array index access code generation --- libsolidity/ExpressionCompiler.cpp | 3 +-- libsolidity/LValue.cpp | 2 +- test/SolidityEndToEndTest.cpp | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index f00b2d40c..3cee40df1 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -133,7 +133,6 @@ void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type con // conversion from bytes to integer. no need to clean the high bit // only to shift right because of opposite alignment IntegerType const& targetIntegerType = dynamic_cast(_targetType); - // solAssert(targetIntegerType.getNumBits() == typeOnStack.getNumBytes() * 8, "The size should be the same."); m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV; if (targetIntegerType.getNumBits() < typeOnStack.getNumBytes() * 8) appendTypeConversion(IntegerType(typeOnStack.getNumBytes() * 8), _targetType, _cleanupNeeded); @@ -782,7 +781,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) // no lvalue, just retrieve the value m_context << eth::Instruction::ADD << eth::Instruction::CALLDATALOAD - << ((u256(1) << (256 - 8)) - 1) << eth::Instruction::AND; + << ((u256(0xff) << (256 - 8))) << eth::Instruction::AND; break; case ArrayType::Location::Memory: solAssert(false, "Memory lvalues not yet implemented."); diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index 7b8374b81..dc07ec311 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -246,7 +246,7 @@ void StorageByteArrayElement::retrieveValue(SourceLocation const&, bool _remove) // stack: ref byte_number if (_remove) m_context << eth::Instruction::SWAP1 << eth::Instruction::SLOAD - << eth::Instruction::SWAP1 << eth::Instruction::BYTE ; + << eth::Instruction::SWAP1 << eth::Instruction::BYTE; else m_context << eth::Instruction::DUP2 << eth::Instruction::SLOAD << eth::Instruction::DUP2 << eth::Instruction::BYTE; diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index b47048272..c3116a994 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -3016,7 +3016,6 @@ BOOST_AUTO_TEST_CASE(bytes_index_access) 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33}; - cout << toHex(callContractFunction("direct(bytes,uint256)", u256(array.length()), 32, array)) << endl; BOOST_CHECK(callContractFunction("direct(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); BOOST_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", u256(array.length()), 32, array) == encodeArgs(32)); BOOST_CHECK(callContractFunction("storageWrite()") == encodeArgs(0x193)); From 0cd3b1537395c50660843595146f8689a316857c Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Mar 2015 17:41:12 +0100 Subject: [PATCH 17/49] byte is now an alias for byte1 --- libsolidity/Token.h | 7 ++++--- libsolidity/Types.cpp | 2 ++ test/SolidityNameAndTypeResolution.cpp | 10 ++++++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index c439c79ee..7b3467908 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -252,8 +252,8 @@ namespace solidity K(UInt240, "uint240", 0) \ K(UInt248, "uint248", 0) \ K(UInt256, "uint256", 0) \ - K(Bytes0, "bytes0", 0) \ - K(Bytes1, "bytes1", 0) \ + K(Bytes0, "bytes0", 0) \ + K(Bytes1, "bytes1", 0) \ K(Bytes2, "bytes2", 0) \ K(Bytes3, "bytes3", 0) \ K(Bytes4, "bytes4", 0) \ @@ -285,7 +285,8 @@ namespace solidity K(Bytes30, "bytes30", 0) \ K(Bytes31, "bytes31", 0) \ K(Bytes32, "bytes32", 0) \ - K(Bytes, "bytes", 0) \ + K(Bytes, "bytes", 0) \ + K(Byte, "byte", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ K(StringType, "string", 0) \ diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 8524cb8b0..aacf56fa3 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -61,6 +61,8 @@ TypePointer Type::fromElementaryTypeName(Token::Value _typeToken) return TypePointer(); } } + else if (_typeToken == Token::Byte) + return make_shared(1); else if (_typeToken == Token::Address) return make_shared(0, IntegerType::Modifier::Address); else if (_typeToken == Token::Bool) diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index a73c937f9..99a1a8bcb 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1393,6 +1393,16 @@ BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes32) == *make_shared(32)); } +BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1) +{ + char const* text = R"( + contract c { + bytes arr; + function f() { byte a = arr[0];} + })"; + ETH_TEST_REQUIRE_NO_THROW(parseTextAndResolveNames(text), "Type resolving failed"); +} + BOOST_AUTO_TEST_SUITE_END() } From afc20d251799737dfb9d7d16bda6709746d188b1 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Mar 2015 17:52:18 +0100 Subject: [PATCH 18/49] Style fixes in Types[cpp/h] --- libsolidity/Types.cpp | 5 ++--- libsolidity/Types.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index aacf56fa3..6f8d4b6b1 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -178,8 +178,8 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const { return _convertTo.getCategory() == getCategory() || - _convertTo.getCategory() == Category::Contract || - _convertTo.getCategory() == Category::Enum || + _convertTo.getCategory() == Category::Contract || + _convertTo.getCategory() == Category::Enum || _convertTo.getCategory() == Category::FixedBytes; } @@ -488,7 +488,6 @@ TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const { auto commonType = dynamic_pointer_cast(Type::commonType(shared_from_this(), _other)); - if (!commonType) return TypePointer(); diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 6517cf070..fd59a37ad 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -158,7 +158,7 @@ protected: }; /** - * Any kind of integer type including address. + * Any kind of integer type (signed, unsigned, address). */ class IntegerType: public Type { @@ -231,7 +231,7 @@ private: }; /** - * Bytes type with fixed length of up to 32 bytes + * Bytes type with fixed length of up to 32 bytes. */ class FixedBytesType: public Type { From 1c3ed8dd977653915986a5bc3f32aac4aeea93fe Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Wed, 11 Mar 2015 18:06:33 +0100 Subject: [PATCH 19/49] Removing uncecessary intermediate int conversion in log tests --- test/SolidityEndToEndTest.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index c3116a994..1492f03c1 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -1189,7 +1189,7 @@ BOOST_AUTO_TEST_CASE(log0) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log0(bytes32(int(1)));\n" + " log0(bytes32(1));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1204,7 +1204,7 @@ BOOST_AUTO_TEST_CASE(log1) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log1(bytes32(int(1)), bytes32(int(2)));\n" + " log1(bytes32(1), bytes32(2));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1220,7 +1220,7 @@ BOOST_AUTO_TEST_CASE(log2) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log2(bytes32(int(1)), bytes32(int(2)), bytes32(int(3)));\n" + " log2(bytes32(1), bytes32(2), bytes32(3));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1237,7 +1237,7 @@ BOOST_AUTO_TEST_CASE(log3) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log3(bytes32(int(1)), bytes32(int(2)), bytes32(int(3)), bytes32(int(4)));\n" + " log3(bytes32(1), bytes32(2), bytes32(3), bytes32(4));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1254,7 +1254,7 @@ BOOST_AUTO_TEST_CASE(log4) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log4(bytes32(int(1)), bytes32(int(2)), bytes32(int(3)), bytes32(int(4)), bytes32(int(5)));\n" + " log4(bytes32(1), bytes32(2), bytes32(3), bytes32(4), bytes32(5));\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1271,7 +1271,7 @@ BOOST_AUTO_TEST_CASE(log_in_constructor) { char const* sourceCode = "contract test {\n" " function test() {\n" - " log1(bytes32(int(1)), bytes32(int(2)));\n" + " log1(bytes32(1), bytes32(2));\n" " }\n" "}\n"; compileAndRun(sourceCode); From 98f0d04a94693468e0bb2ea871608c07f4e6cb81 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 12 Mar 2015 12:25:07 +0100 Subject: [PATCH 20/49] Style fixes and some additional hash to bytes32 renaming --- libsolidity/LValue.cpp | 2 +- libsolidity/Token.h | 6 +++--- test/SolidityEndToEndTest.cpp | 2 +- test/SolidityParser.cpp | 32 ++++++++++++++++---------------- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index dc07ec311..a56ed54c7 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -268,7 +268,7 @@ void StorageByteArrayElement::storeValue(Type const&, SourceLocation const&, boo // stack: value ref (1<<(32-byte_number)) old_full_value_with_cleared_byte m_context << eth::Instruction::SWAP1; m_context << (u256(1) << (256 - 8)) << eth::Instruction::DUP5 << eth::Instruction::DIV - << eth::Instruction::MUL << eth::Instruction::OR; + << eth::Instruction::MUL << eth::Instruction::OR; // stack: value ref new_full_value m_context << eth::Instruction::SWAP1 << eth::Instruction::SSTORE; if (_move) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 7b3467908..2d8a49fcd 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -262,9 +262,9 @@ namespace solidity K(Bytes7, "bytes7", 0) \ K(Bytes8, "bytes8", 0) \ K(Bytes9, "bytes9", 0) \ - K(Bytes10, "bytes10", 0) \ - K(Bytes11, "bytes11", 0) \ - K(Bytes12, "bytes12", 0) \ + K(Bytes10, "bytes10", 0) \ + K(Bytes11, "bytes11", 0) \ + K(Bytes12, "bytes12", 0) \ K(Bytes13, "bytes13", 0) \ K(Bytes14, "bytes14", 0) \ K(Bytes15, "bytes15", 0) \ diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 1492f03c1..5f95709c5 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -519,7 +519,7 @@ BOOST_AUTO_TEST_CASE(strings) BOOST_CHECK(callContractFunction("fixed()") == encodeArgs(string("abc\0\xff__", 7))); BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true)); } -# + BOOST_AUTO_TEST_CASE(empty_string_on_stack) { char const* sourceCode = "contract test {\n" diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 608e1707e..cfdb3f95f 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(empty_function) { char const* text = "contract test {\n" " uint256 stateVar;\n" - " function functionName(hash160 arg1, address addr) constant\n" + " function functionName(bytes20 arg1, address addr) constant\n" " returns (int id)\n" " { }\n" "}\n"; @@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(single_function_param) { char const* text = "contract test {\n" " uint256 stateVar;\n" - " function functionName(hash hashin) returns (hash hashout) {}\n" + " function functionName(bytes32 in) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); } @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) char const* text = "contract test {\n" " uint256 stateVar;\n" " /// This is a test function\n" - " function functionName(hash hashin) returns (hash hashout) {}\n" + " function functionName(bytes32 in) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(function_normal_comments) char const* text = "contract test {\n" " uint256 stateVar;\n" " // We won't see this comment\n" - " function functionName(hash hashin) returns (hash hashout) {}\n" + " function functionName(bytes32 in) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -164,13 +164,13 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) char const* text = "contract test {\n" " uint256 stateVar;\n" " /// This is test function 1\n" - " function functionName1(hash hashin) returns (hash hashout) {}\n" + " function functionName1(bytes32 in) returns (bytes32 out) {}\n" " /// This is test function 2\n" - " function functionName2(hash hashin) returns (hash hashout) {}\n" + " function functionName2(bytes32 in) returns (bytes32 out) {}\n" " // nothing to see here\n" - " function functionName3(hash hashin) returns (hash hashout) {}\n" + " function functionName3(bytes32 in) returns (bytes32 out) {}\n" " /// This is test function 4\n" - " function functionName4(hash hashin) returns (hash hashout) {}\n" + " function functionName4(bytes32 in) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) " uint256 stateVar;\n" " /// This is a test function\n" " /// and it has 2 lines\n" - " function functionName1(hash hashin) returns (hash hashout) {}\n" + " function functionName1(bytes32 in) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -217,12 +217,12 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) " var b;\n" " /// I should not interfere with actual natspec comments\n" " uint256 c;\n" - " mapping(address=>hash) d;\n" + " mapping(address=>bytes32) d;\n" " string name = \"Solidity\";" " }\n" " /// This is a test function\n" " /// and it has 2 lines\n" - " function fun(hash hashin) returns (hash hashout) {}\n" + " function fun(bytes32 in) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) " var b;\n" " /// I should not interfere with actual natspec comments\n" " uint256 c;\n" - " mapping(address=>hash) d;\n" + " mapping(address=>bytes32) d;\n" " string name = \"Solidity\";" " }\n" "}\n"; @@ -269,7 +269,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature) " var b;\n" " /// I should not interfere with actual natspec comments\n" " uint256 c;\n" - " mapping(address=>hash) d;\n" + " mapping(address=>bytes32) d;\n" " string name = \"Solidity\";" " }\n" "}\n"; @@ -330,7 +330,7 @@ BOOST_AUTO_TEST_CASE(variable_definition) " function fun(uint256 a) {\n" " var b;\n" " uint256 c;\n" - " mapping(address=>hash) d;\n" + " mapping(address=>bytes32) d;\n" " customtype varname;\n" " }\n" "}\n"; @@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) " function fun(uint256 a) {\n" " var b = 2;\n" " uint256 c = 0x87;\n" - " mapping(address=>hash) d;\n" + " mapping(address=>bytes32) d;\n" " string name = \"Solidity\";" " customtype varname;\n" " }\n" @@ -366,7 +366,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_mapping) char const* text = R"( contract test { function fun() { - mapping(var=>hash) d; + mapping(var=>bytes32) d; } } )"; From f488fc475350518f51a79a02f4706f6872a543bc Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 12 Mar 2015 13:39:12 +0100 Subject: [PATCH 21/49] Some fixes on Types.cpp for FixedBytesType --- libsolidity/Types.cpp | 20 ++++++++++---------- test/SolidityParser.cpp | 34 +++++++++++++++++----------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 6f8d4b6b1..22e9dfb81 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -231,7 +231,7 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe // All integer types can be compared if (Token::isCompareOp(_operator)) return commonType; - // Nothing else can be done with addresses, but hashes can receive bit operators + // Nothing else can be done with addresses if (commonType->isAddress()) return TypePointer(); @@ -282,16 +282,17 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal) bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const { - auto integerType = getIntegerType(); + shared_ptr integerType = getIntegerType(); + if (!integerType) + return false; + if (_convertTo.getCategory() == Category::FixedBytes) { FixedBytesType const& convertTo = dynamic_cast(_convertTo); - if (convertTo.getNumBytes() * 8 >= integerType->getNumBits()) - return true; - return false; + return convertTo.getNumBytes() * 8 >= integerType->getNumBits(); } - - return integerType && integerType->isImplicitlyConvertibleTo(_convertTo); + + return integerType->isImplicitlyConvertibleTo(_convertTo); } bool IntegerConstantType::isExplicitlyConvertibleTo(Type const& _convertTo) const @@ -462,8 +463,6 @@ bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - if (_convertTo.getCategory() == getCategory()) - return true; if (_convertTo.getCategory() == Category::Integer) { IntegerType const& convertTo = dynamic_cast(_convertTo); @@ -471,7 +470,8 @@ bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const return true; } - return false; + return _convertTo.getCategory() == Category::Contract || + _convertTo.getCategory() == getCategory(); } TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index cfdb3f95f..2f5d06ef6 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -103,7 +103,7 @@ BOOST_AUTO_TEST_CASE(single_function_param) { char const* text = "contract test {\n" " uint256 stateVar;\n" - " function functionName(bytes32 in) returns (bytes32 out) {}\n" + " function functionName(bytes32 input) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed."); } @@ -133,7 +133,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) char const* text = "contract test {\n" " uint256 stateVar;\n" " /// This is a test function\n" - " function functionName(bytes32 in) returns (bytes32 out) {}\n" + " function functionName(bytes32 input) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -148,7 +148,7 @@ BOOST_AUTO_TEST_CASE(function_normal_comments) char const* text = "contract test {\n" " uint256 stateVar;\n" " // We won't see this comment\n" - " function functionName(bytes32 in) returns (bytes32 out) {}\n" + " function functionName(bytes32 input) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -164,13 +164,13 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) char const* text = "contract test {\n" " uint256 stateVar;\n" " /// This is test function 1\n" - " function functionName1(bytes32 in) returns (bytes32 out) {}\n" + " function functionName1(bytes32 input) returns (bytes32 out) {}\n" " /// This is test function 2\n" - " function functionName2(bytes32 in) returns (bytes32 out) {}\n" + " function functionName2(bytes32 input) returns (bytes32 out) {}\n" " // nothing to see here\n" - " function functionName3(bytes32 in) returns (bytes32 out) {}\n" + " function functionName3(bytes32 input) returns (bytes32 out) {}\n" " /// This is test function 4\n" - " function functionName4(bytes32 in) returns (bytes32 out) {}\n" + " function functionName4(bytes32 input) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) " uint256 stateVar;\n" " /// This is a test function\n" " /// and it has 2 lines\n" - " function functionName1(bytes32 in) returns (bytes32 out) {}\n" + " function functionName1(bytes32 input) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -218,11 +218,11 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) " /// I should not interfere with actual natspec comments\n" " uint256 c;\n" " mapping(address=>bytes32) d;\n" - " string name = \"Solidity\";" + " bytes7 name = \"Solidity\";" " }\n" " /// This is a test function\n" " /// and it has 2 lines\n" - " function fun(bytes32 in) returns (bytes32 out) {}\n" + " function fun(bytes32 input) returns (bytes32 out) {}\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); auto functions = contract->getDefinedFunctions(); @@ -247,7 +247,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) " /// I should not interfere with actual natspec comments\n" " uint256 c;\n" " mapping(address=>bytes32) d;\n" - " string name = \"Solidity\";" + " bytes7 name = \"Solidity\";" " }\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); @@ -270,7 +270,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature) " /// I should not interfere with actual natspec comments\n" " uint256 c;\n" " mapping(address=>bytes32) d;\n" - " string name = \"Solidity\";" + " bytes7 name = \"Solidity\";" " }\n" "}\n"; ETH_TEST_REQUIRE_NO_THROW(contract = parseText(text), "Parsing failed"); @@ -296,7 +296,7 @@ BOOST_AUTO_TEST_CASE(struct_definition) BOOST_AUTO_TEST_CASE(mapping) { char const* text = "contract test {\n" - " mapping(address => string) names;\n" + " mapping(address => bytes32) names;\n" "}\n"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } @@ -344,7 +344,7 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization) " var b = 2;\n" " uint256 c = 0x87;\n" " mapping(address=>bytes32) d;\n" - " string name = \"Solidity\";" + " bytes7 name = \"Solidity\";" " customtype varname;\n" " }\n" "}\n"; @@ -662,7 +662,7 @@ BOOST_AUTO_TEST_CASE(event_arguments) { char const* text = R"( contract c { - event e(uint a, string32 s); + event e(uint a, bytes32 s); })"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } @@ -671,7 +671,7 @@ BOOST_AUTO_TEST_CASE(event_arguments_indexed) { char const* text = R"( contract c { - event e(uint a, string32 indexed s, bool indexed b); + event e(uint a, bytes32 indexed s, bool indexed b); })"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } @@ -799,7 +799,7 @@ BOOST_AUTO_TEST_CASE(arrays_in_events) { char const* text = R"( contract c { - event e(uint[10] a, string7[8] indexed b, c[3] x); + event e(uint[10] a, bytes7[8] indexed b, c[3] x); })"; ETH_TEST_CHECK_NO_THROW(parseText(text), "Parsing failed"); } From d3ed076f01cd1bd6b32f6363cfa6e9f0bf6ab67d Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 14:33:00 +0100 Subject: [PATCH 22/49] style --- test/checkRandomStateTest.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/checkRandomStateTest.cpp b/test/checkRandomStateTest.cpp index ed12b7dc4..9cd42dfd3 100644 --- a/test/checkRandomStateTest.cpp +++ b/test/checkRandomStateTest.cpp @@ -125,8 +125,6 @@ bool doStateTest(mValue& _v) return 1; } - - // check logs //checkLog(theState.pending().size() ? theState.log(0) : LogEntries(), importer.m_environment.sub.logs); eth::LogEntries logs = theState.pending().size() ? theState.log(0) : eth::LogEntries(); @@ -219,7 +217,6 @@ bool doStateTest(mValue& _v) } if(expectedAddrs != resultAddrs) return 1; - #endif if(theState.rootHash() != h256(o["postStateRoot"].get_str()), "wrong post state root") return 1; From 693459af3946eec9e1820a038523d488cb930747 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 12 Mar 2015 17:02:17 +0100 Subject: [PATCH 23/49] Milliseconds granularity and UTC in StructLogger - Using toString() which was adapted from what used to be CommonTime.h from #1258 by Gavin. - Closes #1258 --- libdevcore/StructuredLogger.cpp | 32 ++++++++++---------------------- libdevcore/StructuredLogger.h | 2 -- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/libdevcore/StructuredLogger.cpp b/libdevcore/StructuredLogger.cpp index ff267ff4e..5655b332d 100644 --- a/libdevcore/StructuredLogger.cpp +++ b/libdevcore/StructuredLogger.cpp @@ -22,9 +22,10 @@ */ #include "StructuredLogger.h" -#include #include #include + +#include #include "Guards.h" namespace ba = boost::asio; @@ -33,19 +34,6 @@ using namespace std; namespace dev { -string StructuredLogger::timePointToString(chrono::system_clock::time_point const& _ts) -{ - // not using C++11 std::put_time due to gcc bug - // http://stackoverflow.com/questions/14136833/stdput-time-implementation-status-in-gcc - - char buffer[64]; - time_t time = chrono::system_clock::to_time_t(_ts); - tm* ptm = localtime(&time); - if (strftime(buffer, sizeof(buffer), get().m_timeFormat.c_str(), ptm)) - return string(buffer); - return ""; -} - void StructuredLogger::outputJson(Json::Value const& _value, std::string const& _name) const { Json::Value event; @@ -62,7 +50,7 @@ void StructuredLogger::starting(string const& _clientImpl, const char* _ethVersi Json::Value event; event["client_impl"] = _clientImpl; event["eth_version"] = std::string(_ethVersion); - event["ts"] = timePointToString(std::chrono::system_clock::now()); + event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "starting"); } @@ -75,7 +63,7 @@ void StructuredLogger::stopping(string const& _clientImpl, const char* _ethVersi Json::Value event; event["client_impl"] = _clientImpl; event["eth_version"] = std::string(_ethVersion); - event["ts"] = timePointToString(std::chrono::system_clock::now()); + event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "stopping"); } @@ -97,7 +85,7 @@ void StructuredLogger::p2pConnected( event["remote_addr"] = addrStream.str(); event["remote_id"] = _id; event["num_connections"] = Json::Value(_numConnections); - event["ts"] = timePointToString(_ts); + event["ts"] = dev::toString(_ts, get().m_timeFormat.c_str()); get().outputJson(event, "p2p.connected"); } @@ -113,7 +101,7 @@ void StructuredLogger::p2pDisconnected(string const& _id, bi::tcp::endpoint cons event["remote_addr"] = addrStream.str(); event["remote_id"] = _id; event["num_connections"] = Json::Value(_numConnections); - event["ts"] = timePointToString(chrono::system_clock::now()); + event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "p2p.disconnected"); } @@ -131,7 +119,7 @@ void StructuredLogger::minedNewBlock( event["block_hash"] = _hash; event["block_number"] = _blockNumber; event["chain_head_hash"] = _chainHeadHash; - event["ts"] = timePointToString(std::chrono::system_clock::now()); + event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["block_prev_hash"] = _prevHash; get().outputJson(event, "eth.miner.new_block"); @@ -152,7 +140,7 @@ void StructuredLogger::chainReceivedNewBlock( event["block_number"] = _blockNumber; event["chain_head_hash"] = _chainHeadHash; event["remote_id"] = _remoteID; - event["ts"] = timePointToString(chrono::system_clock::now()); + event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["block_prev_hash"] = _prevHash; get().outputJson(event, "eth.chain.received.new_block"); @@ -171,7 +159,7 @@ void StructuredLogger::chainNewHead( event["block_hash"] = _hash; event["block_number"] = _blockNumber; event["chain_head_hash"] = _chainHeadHash; - event["ts"] = timePointToString(chrono::system_clock::now()); + event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); event["block_prev_hash"] = _prevHash; get().outputJson(event, "eth.miner.new_block"); @@ -185,7 +173,7 @@ void StructuredLogger::transactionReceived(string const& _hash, string const& _r Json::Value event; event["tx_hash"] = _hash; event["remote_id"] = _remoteId; - event["ts"] = timePointToString(chrono::system_clock::now()); + event["ts"] = dev::toString(chrono::system_clock::now(), get().m_timeFormat.c_str()); get().outputJson(event, "eth.tx.received"); } diff --git a/libdevcore/StructuredLogger.h b/libdevcore/StructuredLogger.h index eea19d107..2c30541e4 100644 --- a/libdevcore/StructuredLogger.h +++ b/libdevcore/StructuredLogger.h @@ -98,8 +98,6 @@ private: StructuredLogger(StructuredLogger const&) = delete; void operator=(StructuredLogger const&) = delete; - /// @returns a string representation of a timepoint - static std::string timePointToString(std::chrono::system_clock::time_point const& _ts); void outputJson(Json::Value const& _value, std::string const& _name) const; bool m_enabled = false; From 5c042e2e592ff52542224f61d181c109d15e4573 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Thu, 12 Mar 2015 17:31:39 +0100 Subject: [PATCH 24/49] Small FixedBytes type fixes - Integer Constant is explicitly convertible to FixedBytes, so using that in the tests --- libsolidity/Types.cpp | 7 ++----- test/SolidityEndToEndTest.cpp | 16 +++++++--------- test/SolidityNameAndTypeResolution.cpp | 1 + 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 22e9dfb81..bd55e2a8b 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -191,13 +191,10 @@ TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const // no further unary operators for addresses else if (isAddress()) return TypePointer(); - // "~" is ok for all other types - else if (_operator == Token::BitNot) - return shared_from_this(); // for non-address integers, we allow +, -, ++ and -- else if (_operator == Token::Add || _operator == Token::Sub || _operator == Token::Inc || _operator == Token::Dec || - _operator == Token::After) + _operator == Token::After || _operator == Token::BitNot) return shared_from_this(); else return TypePointer(); @@ -1154,7 +1151,7 @@ MagicType::MagicType(MagicType::Kind _kind): case Kind::Block: m_members = MemberList({{"coinbase", make_shared(0, IntegerType::Modifier::Address)}, {"timestamp", make_shared(256)}, - {"blockhash", make_shared(strings{"uint"}, strings{"bytes"}, FunctionType::Location::BlockHash)}, + {"blockhash", make_shared(strings{"uint"}, strings{"bytes32"}, FunctionType::Location::BlockHash)}, {"difficulty", make_shared(256)}, {"number", make_shared(256)}, {"gaslimit", make_shared(256)}}); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 5f95709c5..2f965849b 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -1182,14 +1182,12 @@ BOOST_AUTO_TEST_CASE(send_ether) BOOST_CHECK(callContractFunction("a(address,uint256)", address, amount) == encodeArgs(1)); BOOST_CHECK_EQUAL(m_state.balance(address), amount); } -// TODO: Note that these tests should actually be -// simply converting integer constant to bytes32. This conversion is not there -// yet. When it's implemented DO change the tests too + BOOST_AUTO_TEST_CASE(log0) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log0(bytes32(1));\n" + " log0(1);\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1204,7 +1202,7 @@ BOOST_AUTO_TEST_CASE(log1) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log1(bytes32(1), bytes32(2));\n" + " log1(1, 2);\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1220,7 +1218,7 @@ BOOST_AUTO_TEST_CASE(log2) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log2(bytes32(1), bytes32(2), bytes32(3));\n" + " log2(1, 2, 3);\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1237,7 +1235,7 @@ BOOST_AUTO_TEST_CASE(log3) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log3(bytes32(1), bytes32(2), bytes32(3), bytes32(4));\n" + " log3(1, 2, 3, 4);\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1254,7 +1252,7 @@ BOOST_AUTO_TEST_CASE(log4) { char const* sourceCode = "contract test {\n" " function a() {\n" - " log4(bytes32(1), bytes32(2), bytes32(3), bytes32(4), bytes32(5));\n" + " log4(1, 2, 3, 4, 5);\n" " }\n" "}\n"; compileAndRun(sourceCode); @@ -1271,7 +1269,7 @@ BOOST_AUTO_TEST_CASE(log_in_constructor) { char const* sourceCode = "contract test {\n" " function test() {\n" - " log1(bytes32(1), bytes32(2));\n" + " log1(1, 2);\n" " }\n" "}\n"; compileAndRun(sourceCode); diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 99a1a8bcb..a310800f7 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -1358,6 +1358,7 @@ BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName) BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt248) == *make_shared(248, IntegerType::Modifier::Unsigned)); BOOST_CHECK(*Type::fromElementaryTypeName(Token::UInt256) == *make_shared(256, IntegerType::Modifier::Unsigned)); + BOOST_CHECK(*Type::fromElementaryTypeName(Token::Byte) == *make_shared(1)); BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes0) == *make_shared(0)); BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes1) == *make_shared(1)); BOOST_CHECK(*Type::fromElementaryTypeName(Token::Bytes2) == *make_shared(2)); From f20a3e10fba202948f63e070c71357edd7226e5c Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 17:44:57 +0100 Subject: [PATCH 25/49] bugfix --- test/checkRandomStateTest.cpp | 5 ++++- test/createRandomStateTest.cpp | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/test/checkRandomStateTest.cpp b/test/checkRandomStateTest.cpp index 9cd42dfd3..601ef1ca9 100644 --- a/test/checkRandomStateTest.cpp +++ b/test/checkRandomStateTest.cpp @@ -218,8 +218,11 @@ bool doStateTest(mValue& _v) if(expectedAddrs != resultAddrs) return 1; #endif - if(theState.rootHash() != h256(o["postStateRoot"].get_str()), "wrong post state root") + if(theState.rootHash() != h256(o["postStateRoot"].get_str())) + { + cout << "wrong post state root" << endl; return 1; + } } return 0; } diff --git a/test/createRandomStateTest.cpp b/test/createRandomStateTest.cpp index 6b24f1216..f9baa0091 100644 --- a/test/createRandomStateTest.cpp +++ b/test/createRandomStateTest.cpp @@ -86,8 +86,8 @@ int main(int argc, char *argv[]) { "randomStatetest" : { "env" : { - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "0x945304eb96065b2a98b57a48a06ae28d285a71b5", + "currentCoinbase" : "945304eb96065b2a98b57a48a06ae28d285a71b5", + "currentDifficulty" : "5623894562375", "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", "currentNumber" : "0", "currentTimestamp" : "1", From 76bd23b61d94771053029b399c16a2e99608078a Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 19:01:09 +0100 Subject: [PATCH 26/49] style --- test/createRandomStateTest.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/createRandomStateTest.cpp b/test/createRandomStateTest.cpp index f9baa0091..13b622bb1 100644 --- a/test/createRandomStateTest.cpp +++ b/test/createRandomStateTest.cpp @@ -58,10 +58,8 @@ int main(int argc, char *argv[]) boost::random::uniform_int_distribution<> lengthOfCodeDist(2, 16); boost::random::uniform_int_distribution<> opcodeDist(0, 255); boost::random::uniform_int_distribution<> BlockInfoOpcodeDist(0x40, 0x45); - boost::random::variate_generator > randGen(gen, opcodeDist); - boost::random::variate_generator > randGenBlockInfoOpcode(gen, BlockInfoOpcodeDist); + boost::random::variate_generator > randGen(gen, opcodeDist); + boost::random::variate_generator > randGenBlockInfoOpcode(gen, BlockInfoOpcodeDist); int lengthOfCode = lengthOfCodeDist(gen); string randomCode; From 77f9a58c61695ad265008065e3c8a693b23c1f39 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Thu, 12 Mar 2015 19:03:07 +0100 Subject: [PATCH 27/49] style --- test/checkRandomStateTest.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/checkRandomStateTest.cpp b/test/checkRandomStateTest.cpp index 601ef1ca9..17e785f60 100644 --- a/test/checkRandomStateTest.cpp +++ b/test/checkRandomStateTest.cpp @@ -215,10 +215,10 @@ bool doStateTest(mValue& _v) if (expectedAddrIt == expectedAddrs.end()) return 1; } - if(expectedAddrs != resultAddrs) + if (expectedAddrs != resultAddrs) return 1; #endif - if(theState.rootHash() != h256(o["postStateRoot"].get_str())) + if (theState.rootHash() != h256(o["postStateRoot"].get_str())) { cout << "wrong post state root" << endl; return 1; From 69e1902aa52469de7ee6cfb62c6779fd4af25fd1 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Mar 2015 12:29:59 +0100 Subject: [PATCH 28/49] fix calldataload --- libevm/VM.cpp | 8 +++++-- test/vmEnvironmentalInfoTestFiller.json | 28 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index e0b487c9b..19339ce49 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -341,8 +341,12 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) break; case Instruction::CALLDATALOAD: { - if ((unsigned)m_stack.back() + (uint64_t)31 < _ext.data.size()) - m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (unsigned)m_stack.back()); + if ((bigint)m_stack.back() + 31 < _ext.data.size()) + m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (size_t)m_stack.back()); + else if ((bigint)m_stack.back() >= _ext.data.size()) + { + m_stack.back() = u256(); + } else { h256 r; diff --git a/test/vmEnvironmentalInfoTestFiller.json b/test/vmEnvironmentalInfoTestFiller.json index d9e1ef654..951e65c32 100644 --- a/test/vmEnvironmentalInfoTestFiller.json +++ b/test/vmEnvironmentalInfoTestFiller.json @@ -367,6 +367,34 @@ } }, + "calldataload_BigOffset": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "100000000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (CALLDATALOAD 0x4200000000000000000000000000000000000000000000000000000000000000)}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "0x4200000000000000000000000000000000000000000000000000000000000000", + "gasPrice" : "1000000000", + "gas" : "100000000000" + } + }, + "calldataload1": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 2df5656fda5681984cc31489f0dc398c9f3f2a23 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Mar 2015 12:33:59 +0100 Subject: [PATCH 29/49] style --- libevm/VM.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libevm/VM.cpp b/libevm/VM.cpp index 19339ce49..6f6e08d4c 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -344,9 +344,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) if ((bigint)m_stack.back() + 31 < _ext.data.size()) m_stack.back() = (u256)*(h256 const*)(_ext.data.data() + (size_t)m_stack.back()); else if ((bigint)m_stack.back() >= _ext.data.size()) - { m_stack.back() = u256(); - } else { h256 r; From c45011b1653a3d836eb4a3c7f3d5d90e39970c05 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Mar 2015 13:04:05 +0100 Subject: [PATCH 30/49] add addmod test in order toc check that nothing get downcasted inbetween --- test/vmArithmeticTestFiller.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/vmArithmeticTestFiller.json b/test/vmArithmeticTestFiller.json index 16e085a12..1aae823bd 100644 --- a/test/vmArithmeticTestFiller.json +++ b/test/vmArithmeticTestFiller.json @@ -1485,6 +1485,34 @@ } }, + "addmodBigIntCast": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (ADDMOD 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 1 5) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "addmod1_overflow2": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", From 0fc5b25783bb199283bca0810d16e537a3cf5194 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Mar 2015 14:58:47 +0100 Subject: [PATCH 31/49] remove seedhash from block header tests --- test/bcBlockChainTestFiller.json | 1 - test/bcInvalidHeaderTestFiller.json | 14 -------------- test/bcUncleTestFiller.json | 13 ------------- test/bcValidBlockTestFiller.json | 8 -------- test/blockchain.cpp | 2 +- 5 files changed, 1 insertion(+), 37 deletions(-) diff --git a/test/bcBlockChainTestFiller.json b/test/bcBlockChainTestFiller.json index b149f5938..ed70a5296 100644 --- a/test/bcBlockChainTestFiller.json +++ b/test/bcBlockChainTestFiller.json @@ -13,7 +13,6 @@ "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", "timestamp" : "0x54c98c81", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" diff --git a/test/bcInvalidHeaderTestFiller.json b/test/bcInvalidHeaderTestFiller.json index 39a91a583..da3d13163 100644 --- a/test/bcInvalidHeaderTestFiller.json +++ b/test/bcInvalidHeaderTestFiller.json @@ -8,7 +8,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -64,7 +63,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -120,7 +118,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -175,7 +172,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -230,7 +226,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -285,7 +280,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -341,7 +335,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -396,7 +389,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -451,7 +443,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -506,7 +497,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -561,7 +551,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -616,7 +605,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -671,7 +659,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -726,7 +713,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/test/bcUncleTestFiller.json b/test/bcUncleTestFiller.json index 73d1e5487..5fb466967 100644 --- a/test/bcUncleTestFiller.json +++ b/test/bcUncleTestFiller.json @@ -13,7 +13,6 @@ "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", "timestamp" : "0x54c98c81", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" @@ -68,7 +67,6 @@ "number" : "1", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -93,7 +91,6 @@ "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", "timestamp" : "0x54c98c81", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" @@ -163,7 +160,6 @@ "number" : "2", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -188,7 +184,6 @@ "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", "timestamp" : "0x54c98c81", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" @@ -258,7 +253,6 @@ "number" : "2", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -286,7 +280,6 @@ "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", "timestamp" : "0x54c98c81", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" @@ -356,7 +349,6 @@ "number" : "2", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -375,7 +367,6 @@ "number" : "2", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -400,7 +391,6 @@ "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", "timestamp" : "0x54c98c81", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" @@ -470,7 +460,6 @@ "number" : "2", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -489,7 +478,6 @@ "number" : "2", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", @@ -508,7 +496,6 @@ "number" : "2", "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", "timestamp" : "0x54c98c82", "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", diff --git a/test/bcValidBlockTestFiller.json b/test/bcValidBlockTestFiller.json index 14d4cfb2c..e184a0849 100644 --- a/test/bcValidBlockTestFiller.json +++ b/test/bcValidBlockTestFiller.json @@ -9,7 +9,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -56,7 +55,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -102,7 +100,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -148,7 +145,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -194,7 +190,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -249,7 +244,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -304,7 +298,6 @@ "gasLimit" : "125000", "gasUsed" : "0", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -356,7 +349,6 @@ "gasLimit" : "125000", "gasUsed" : "100", "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "seedHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "nonce" : "0x0102030405060708", "number" : "0", "parentHash" : "0xefb4db878627027c81b3bb1c7dd3a18dae3914a49cdd24a3e40ab3bbfbb240c5", diff --git a/test/blockchain.cpp b/test/blockchain.cpp index 045f2de5b..b86cd7833 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -386,7 +386,7 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) { mObject uBlH = uBlHeaderObj.get_obj(); cout << "uBlH.size(): " << uBlH.size() << endl; - BOOST_REQUIRE(uBlH.size() == 17); + BOOST_REQUIRE(uBlH.size() == 16); bytes uncleRLP = createBlockRLPFromFields(uBlH); const RLP c_uRLP(uncleRLP); BlockInfo uncleBlockHeader; From 608b4ca70799a4d8f44f5f63099e2d204ce27a37 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Fri, 13 Mar 2015 15:35:32 +0100 Subject: [PATCH 32/49] clean up --- test/blockchain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/blockchain.cpp b/test/blockchain.cpp index b86cd7833..ac872c0f3 100644 --- a/test/blockchain.cpp +++ b/test/blockchain.cpp @@ -533,7 +533,7 @@ void overwriteBlockHeader(BlockInfo& _current_BlockHeader, mObject& _blObj) std::pair ret; while (!ProofOfWork::verify(_current_BlockHeader)) { - ret = pow.mine(_current_BlockHeader, 1000, true, true); // tie(ret, blockFromFields.nonce) + ret = pow.mine(_current_BlockHeader, 1000, true, true); Ethash::assignResult(ret.second, _current_BlockHeader); } } @@ -580,7 +580,7 @@ void updatePoW(BlockInfo& _bi) std::pair ret; while (!ProofOfWork::verify(_bi)) { - ret = pow.mine(_bi, 10000, true, true); // tie(ret, blockFromFields.nonce) + ret = pow.mine(_bi, 10000, true, true); Ethash::assignResult(ret.second, _bi); } _bi.hash = _bi.headerHash(WithNonce); From 5bbd7b5c15de77c194ce72f72901da672faf64a0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Fri, 13 Mar 2015 16:13:43 +0100 Subject: [PATCH 33/49] Squashed 'libjsqrc/ethereumjs/' changes from d509360..eceeda7 eceeda7 gulp cc3e373 Merge pull request #109 from LefterisJP/string_hash_rename 3a22498 string type basically becomes bytes type 760634a Changing abi tests to use fixed bytes type 6554479 Merge pull request #108 from frozeman/apiOverhaul b322378 removed unecessary utils 9a3d320 changed my author url 8516a2f removed uncommented line 1730f21 add version replacement use version.json now 27e5706 bumped version 3614cea bumped version 9c3d1b2 merged develop 2e320ed add versions 08a38b3 removed unecessary open in httpprovidor 5636510 add inputformatter for sha3 50ca903 add build f351e95 removed unecessary log 67ab5ef removed unecessary log git-subtree-dir: libjsqrc/ethereumjs git-subtree-split: eceeda7d0878579cdc6324f3026ae88079c30720 --- dist/ethereum.js | 73 +++++++++++++++++++++++++------------- dist/ethereum.js.map | 20 ++++++----- dist/ethereum.min.js | 2 +- gulpfile.js | 16 ++++++++- lib/solidity/abi.js | 8 ++--- lib/solidity/types.js | 6 ++-- lib/web3.js | 36 ++++++++++++++----- lib/web3/db.js | 9 ++--- lib/web3/eth.js | 3 +- lib/web3/filter.js | 1 + lib/web3/httpprovider.js | 2 +- lib/web3/requestmanager.js | 2 +- package.js | 2 +- package.json | 7 ++-- test/abi.inputParser.js | 66 +++++----------------------------- test/abi.outputParser.js | 72 ++++--------------------------------- test/db.methods.js | 4 +-- version.json | 3 ++ 18 files changed, 145 insertions(+), 187 deletions(-) create mode 100644 version.json diff --git a/dist/ethereum.js b/dist/ethereum.js index 88a5180a9..300daccca 100644 --- a/dist/ethereum.js +++ b/dist/ethereum.js @@ -58,7 +58,7 @@ var isArrayType = function (type) { */ var dynamicTypeBytes = function (type, value) { // TODO: decide what to do with array of strings - if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length. + if (isArrayType(type) || type === 'bytes') return f.formatInputInt(value.length); return ""; }; @@ -99,7 +99,7 @@ var formatInput = function (inputs, params) { toAppendArrayContent += params[i].reduce(function (acc, curr) { return acc + formatter(curr); }, ""); - else if (inputs[i].type === 'string') + else if (inputs[i].type === 'bytes') toAppendArrayContent += formatter(params[i]); else toAppendConstant += formatter(params[i]); @@ -118,7 +118,7 @@ var formatInput = function (inputs, params) { * @returns {Number} length of dynamic type, 0 or multiplication of ETH_PADDING (32) */ var dynamicBytesLength = function (type) { - if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length. + if (isArrayType(type) || type === 'bytes') return c.ETH_PADDING * 2; return 0; }; @@ -168,7 +168,7 @@ var formatOutput = function (outs, output) { } result.push(array); } - else if (types.prefixedType('string')(outs[i].type)) { + else if (types.prefixedType('bytes')(outs[i].type)) { dynamicPart = dynamicPart.slice(padding); result.push(formatter(output.slice(0, padding))); output = output.slice(padding); @@ -509,8 +509,7 @@ var inputTypes = function () { return [ { type: prefixedType('uint'), format: f.formatInputInt }, { type: prefixedType('int'), format: f.formatInputInt }, - { type: prefixedType('hash'), format: f.formatInputInt }, - { type: prefixedType('string'), format: f.formatInputString }, + { type: prefixedType('bytes'), format: f.formatInputString }, { type: prefixedType('real'), format: f.formatInputReal }, { type: prefixedType('ureal'), format: f.formatInputReal }, { type: namedType('address'), format: f.formatInputInt }, @@ -525,8 +524,7 @@ var outputTypes = function () { return [ { type: prefixedType('uint'), format: f.formatOutputUInt }, { type: prefixedType('int'), format: f.formatOutputInt }, - { type: prefixedType('hash'), format: f.formatOutputHash }, - { type: prefixedType('string'), format: f.formatOutputString }, + { type: prefixedType('bytes'), format: f.formatOutputString }, { type: prefixedType('real'), format: f.formatOutputReal }, { type: prefixedType('ureal'), format: f.formatOutputUReal }, { type: namedType('address'), format: f.formatOutputAddress }, @@ -1087,10 +1085,12 @@ module.exports = { * Jeffrey Wilcke * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * Gav Wood * @date 2014 */ +var version = require('../version.json'); var net = require('./web3/net'); var eth = require('./web3/eth'); var db = require('./web3/db'); @@ -1103,11 +1103,14 @@ var requestManager = require('./web3/requestmanager'); var c = require('./utils/config'); /// @returns an array of objects describing web3 api methods -var web3Methods = function () { - return [ - { name: 'sha3', call: 'web3_sha3' } - ]; -}; +var web3Methods = [ + { name: 'sha3', call: 'web3_sha3', inputFormatter: utils.toHex }, +]; +var web3Properties = [ + { name: 'version.client', getter: 'web3_clientVersion' }, + { name: 'version.network', getter: 'net_version' } +]; + /// creates methods in a given object based on method description on input /// setups api calls for these methods @@ -1167,7 +1170,9 @@ var setupMethods = function (obj, methods) { /// setups api calls for these properties var setupProperties = function (obj, properties) { properties.forEach(function (property) { - var proto = {}; + var objectProperties = property.name.split('.'), + proto = {}; + proto.get = function () { // show deprecated warning @@ -1197,7 +1202,14 @@ var setupProperties = function (obj, properties) { } proto.enumerable = !property.newProperty; - Object.defineProperty(obj, property.name, proto); + + if(objectProperties.length > 1) { + if(!obj[objectProperties[0]]) + obj[objectProperties[0]] = {}; + + Object.defineProperty(obj[objectProperties[0]], objectProperties[1], proto); + } else + Object.defineProperty(obj, property.name, proto); }); }; @@ -1227,6 +1239,11 @@ var shhWatch = { /// setups web3 object, and it's in-browser executed methods var web3 = { + + version: { + api: version.version + }, + manager: requestManager(), providers: {}, @@ -1334,7 +1351,8 @@ Object.defineProperty(web3.eth, 'defaultBlock', { /// setups all api methods -setupMethods(web3, web3Methods()); +setupMethods(web3, web3Methods); +setupProperties(web3, web3Properties); setupMethods(web3.net, net.methods); setupProperties(web3.net, net.properties); setupMethods(web3.eth, eth.methods); @@ -1347,7 +1365,7 @@ setupMethods(shhWatch, watches.shh()); module.exports = web3; -},{"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(require,module,exports){ +},{"../version.json":21,"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1615,13 +1633,14 @@ module.exports = contract; * @date 2015 */ + /// @returns an array of objects describing web3.db api methods var methods = function () { return [ - { name: 'put', call: 'db_put' }, - { name: 'get', call: 'db_get' }, - { name: 'putString', call: 'db_putString' }, - { name: 'getString', call: 'db_getString' } + { name: 'putString', call: 'db_putString'}, + { name: 'getString', call: 'db_getString'}, + { name: 'putHex', call: 'db_putHex'}, + { name: 'getHex', call: 'db_getHex'} ]; }; @@ -1649,6 +1668,7 @@ module.exports = { /** @file eth.js * @authors: * Marek Kotewicz + * Fabian Vogelsteller * @date 2015 */ @@ -1734,7 +1754,7 @@ var methods = [ inputFormatter: formatters.inputTransactionFormatter }, { name: 'call', call: 'eth_call', addDefaultblock: 2, inputFormatter: formatters.inputCallFormatter }, - { name: 'compile.solidity', call: 'eth_compileSolidity', inputFormatter: utils.toHex }, + { name: 'compile.solidity', call: 'eth_compileSolidity' }, { name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex }, { name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex }, { name: 'flush', call: 'eth_flush' }, @@ -1941,6 +1961,7 @@ module.exports = { * Jeffrey Wilcke * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * Gav Wood * @date 2014 */ @@ -2322,6 +2343,7 @@ module.exports = { * @authors: * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * @date 2014 */ @@ -2337,7 +2359,6 @@ var HttpProvider = function (host) { HttpProvider.prototype.send = function (payload, callback) { var request = new XMLHttpRequest(); - request.open('POST', this.host, false); // ASYNC if(typeof callback === 'function') { @@ -2539,6 +2560,7 @@ module.exports = QtSyncProvider; * Jeffrey Wilcke * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * Gav Wood * @date 2014 */ @@ -2609,7 +2631,6 @@ var requestManager = function() { var result = provider.send(payload); if (!jsonrpc.isValidResponse(result)) { - console.log(result); if(typeof result === 'object' && result.error && result.error.message) console.error(result.error.message); return null; @@ -2819,6 +2840,10 @@ module.exports = { }; +},{}],21:[function(require,module,exports){ +module.exports={ + "version": "0.1.3" +} },{}],"web3":[function(require,module,exports){ var web3 = require('./lib/web3'); web3.providers.HttpProvider = require('./lib/web3/httpprovider'); diff --git a/dist/ethereum.js.map b/dist/ethereum.js.map index 6d9b9c45a..a36e9ed17 100644 --- a/dist/ethereum.js.map +++ b/dist/ethereum.js.map @@ -22,34 +22,36 @@ "lib/web3/shh.js", "lib/web3/signature.js", "lib/web3/watches.js", + "version.json", "index.js" ], "names": [], - "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", + "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChcA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjDA;AACA;AACA;;ACFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA", "file": "generated.js", "sourceRoot": "", "sourcesContent": [ "(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o.\n*/\n/** @file abi.js\n * @authors:\n * Marek Kotewicz \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar types = require('./types');\nvar f = require('./formatters');\n\n/**\n * throw incorrect type error\n *\n * @method throwTypeError\n * @param {String} type\n * @throws incorrect type error\n */\nvar throwTypeError = function (type) {\n throw new Error('parser does not support type: ' + type);\n};\n\n/** This method should be called if we want to check if givent type is an array type\n *\n * @method isArrayType\n * @param {String} type name\n * @returns {Boolean} true if it is, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * This method should be called to return dynamic type length in hex\n *\n * @method dynamicTypeBytes\n * @param {String} type\n * @param {String|Array} dynamic type\n * @return {String} length of dynamic type in hex or empty string if type is not dynamic\n */\nvar dynamicTypeBytes = function (type, value) {\n // TODO: decide what to do with array of strings\n if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.\n return f.formatInputInt(value.length);\n return \"\";\n};\n\nvar inputTypes = types.inputTypes();\n\n/**\n * Formats input params to bytes\n *\n * @method formatInput\n * @param {Array} abi inputs of method\n * @param {Array} params that will be formatted to bytes\n * @returns bytes representation of input params\n */\nvar formatInput = function (inputs, params) {\n var bytes = \"\";\n var toAppendConstant = \"\";\n var toAppendArrayContent = \"\";\n\n /// first we iterate in search for dynamic\n inputs.forEach(function (input, index) {\n bytes += dynamicTypeBytes(input.type, params[index]);\n });\n\n inputs.forEach(function (input, i) {\n /*jshint maxcomplexity:5 */\n var typeMatch = false;\n for (var j = 0; j < inputTypes.length && !typeMatch; j++) {\n typeMatch = inputTypes[j].type(inputs[i].type, params[i]);\n }\n if (!typeMatch) {\n throwTypeError(inputs[i].type);\n }\n\n var formatter = inputTypes[j - 1].format;\n\n if (isArrayType(inputs[i].type))\n toAppendArrayContent += params[i].reduce(function (acc, curr) {\n return acc + formatter(curr);\n }, \"\");\n else if (inputs[i].type === 'string')\n toAppendArrayContent += formatter(params[i]);\n else\n toAppendConstant += formatter(params[i]);\n });\n\n bytes += toAppendConstant + toAppendArrayContent;\n\n return bytes;\n};\n\n/**\n * This method should be called to predict the length of dynamic type\n *\n * @method dynamicBytesLength\n * @param {String} type\n * @returns {Number} length of dynamic type, 0 or multiplication of ETH_PADDING (32)\n */\nvar dynamicBytesLength = function (type) {\n if (isArrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.\n return c.ETH_PADDING * 2;\n return 0;\n};\n\nvar outputTypes = types.outputTypes();\n\n/** \n * Formats output bytes back to param list\n *\n * @method formatOutput\n * @param {Array} abi outputs of method\n * @param {String} bytes represention of output\n * @returns {Array} output params\n */\nvar formatOutput = function (outs, output) {\n\n output = output.slice(2);\n var result = [];\n var padding = c.ETH_PADDING * 2;\n\n var dynamicPartLength = outs.reduce(function (acc, curr) {\n return acc + dynamicBytesLength(curr.type);\n }, 0);\n\n var dynamicPart = output.slice(0, dynamicPartLength);\n output = output.slice(dynamicPartLength);\n\n outs.forEach(function (out, i) {\n /*jshint maxcomplexity:6 */\n var typeMatch = false;\n for (var j = 0; j < outputTypes.length && !typeMatch; j++) {\n typeMatch = outputTypes[j].type(outs[i].type);\n }\n\n if (!typeMatch) {\n throwTypeError(outs[i].type);\n }\n\n var formatter = outputTypes[j - 1].format;\n if (isArrayType(outs[i].type)) {\n var size = f.formatOutputUInt(dynamicPart.slice(0, padding));\n dynamicPart = dynamicPart.slice(padding);\n var array = [];\n for (var k = 0; k < size; k++) {\n array.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n }\n result.push(array);\n }\n else if (types.prefixedType('string')(outs[i].type)) {\n dynamicPart = dynamicPart.slice(padding);\n result.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n } else {\n result.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n }\n });\n\n return result;\n};\n\n/**\n * Should be called to create input parser for contract with given abi\n *\n * @method inputParser\n * @param {Array} contract abi\n * @returns {Object} input parser object for given json abi\n * TODO: refactor creating the parser, do not double logic from contract\n */\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function () {\n var params = Array.prototype.slice.call(arguments);\n return formatInput(method.inputs, params);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\n/**\n * Should be called to create output parser for contract with given abi\n *\n * @method outputParser\n * @param {Array} contract abi\n * @returns {Object} output parser for given json abi\n */\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function (output) {\n return formatOutput(method.outputs, output);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n formatInput: formatInput,\n formatOutput: formatOutput\n};\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file abi.js\n * @authors:\n * Marek Kotewicz \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar types = require('./types');\nvar f = require('./formatters');\n\n/**\n * throw incorrect type error\n *\n * @method throwTypeError\n * @param {String} type\n * @throws incorrect type error\n */\nvar throwTypeError = function (type) {\n throw new Error('parser does not support type: ' + type);\n};\n\n/** This method should be called if we want to check if givent type is an array type\n *\n * @method isArrayType\n * @param {String} type name\n * @returns {Boolean} true if it is, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * This method should be called to return dynamic type length in hex\n *\n * @method dynamicTypeBytes\n * @param {String} type\n * @param {String|Array} dynamic type\n * @return {String} length of dynamic type in hex or empty string if type is not dynamic\n */\nvar dynamicTypeBytes = function (type, value) {\n // TODO: decide what to do with array of strings\n if (isArrayType(type) || type === 'bytes')\n return f.formatInputInt(value.length);\n return \"\";\n};\n\nvar inputTypes = types.inputTypes();\n\n/**\n * Formats input params to bytes\n *\n * @method formatInput\n * @param {Array} abi inputs of method\n * @param {Array} params that will be formatted to bytes\n * @returns bytes representation of input params\n */\nvar formatInput = function (inputs, params) {\n var bytes = \"\";\n var toAppendConstant = \"\";\n var toAppendArrayContent = \"\";\n\n /// first we iterate in search for dynamic\n inputs.forEach(function (input, index) {\n bytes += dynamicTypeBytes(input.type, params[index]);\n });\n\n inputs.forEach(function (input, i) {\n /*jshint maxcomplexity:5 */\n var typeMatch = false;\n for (var j = 0; j < inputTypes.length && !typeMatch; j++) {\n typeMatch = inputTypes[j].type(inputs[i].type, params[i]);\n }\n if (!typeMatch) {\n throwTypeError(inputs[i].type);\n }\n\n var formatter = inputTypes[j - 1].format;\n\n if (isArrayType(inputs[i].type))\n toAppendArrayContent += params[i].reduce(function (acc, curr) {\n return acc + formatter(curr);\n }, \"\");\n else if (inputs[i].type === 'bytes')\n toAppendArrayContent += formatter(params[i]);\n else\n toAppendConstant += formatter(params[i]);\n });\n\n bytes += toAppendConstant + toAppendArrayContent;\n\n return bytes;\n};\n\n/**\n * This method should be called to predict the length of dynamic type\n *\n * @method dynamicBytesLength\n * @param {String} type\n * @returns {Number} length of dynamic type, 0 or multiplication of ETH_PADDING (32)\n */\nvar dynamicBytesLength = function (type) {\n if (isArrayType(type) || type === 'bytes')\n return c.ETH_PADDING * 2;\n return 0;\n};\n\nvar outputTypes = types.outputTypes();\n\n/** \n * Formats output bytes back to param list\n *\n * @method formatOutput\n * @param {Array} abi outputs of method\n * @param {String} bytes represention of output\n * @returns {Array} output params\n */\nvar formatOutput = function (outs, output) {\n\n output = output.slice(2);\n var result = [];\n var padding = c.ETH_PADDING * 2;\n\n var dynamicPartLength = outs.reduce(function (acc, curr) {\n return acc + dynamicBytesLength(curr.type);\n }, 0);\n\n var dynamicPart = output.slice(0, dynamicPartLength);\n output = output.slice(dynamicPartLength);\n\n outs.forEach(function (out, i) {\n /*jshint maxcomplexity:6 */\n var typeMatch = false;\n for (var j = 0; j < outputTypes.length && !typeMatch; j++) {\n typeMatch = outputTypes[j].type(outs[i].type);\n }\n\n if (!typeMatch) {\n throwTypeError(outs[i].type);\n }\n\n var formatter = outputTypes[j - 1].format;\n if (isArrayType(outs[i].type)) {\n var size = f.formatOutputUInt(dynamicPart.slice(0, padding));\n dynamicPart = dynamicPart.slice(padding);\n var array = [];\n for (var k = 0; k < size; k++) {\n array.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n }\n result.push(array);\n }\n else if (types.prefixedType('bytes')(outs[i].type)) {\n dynamicPart = dynamicPart.slice(padding);\n result.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n } else {\n result.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n }\n });\n\n return result;\n};\n\n/**\n * Should be called to create input parser for contract with given abi\n *\n * @method inputParser\n * @param {Array} contract abi\n * @returns {Object} input parser object for given json abi\n * TODO: refactor creating the parser, do not double logic from contract\n */\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function () {\n var params = Array.prototype.slice.call(arguments);\n return formatInput(method.inputs, params);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\n/**\n * Should be called to create output parser for contract with given abi\n *\n * @method outputParser\n * @param {Array} contract abi\n * @returns {Object} output parser for given json abi\n */\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function (output) {\n return formatOutput(method.outputs, output);\n };\n\n if (parser[displayName] === undefined) {\n parser[displayName] = impl;\n }\n\n parser[displayName][typeName] = impl;\n });\n\n return parser;\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n formatInput: formatInput,\n formatOutput: formatOutput\n};\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file formatters.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nif (\"build\" !== 'build') {/*\n var BigNumber = require('bignumber.js'); // jshint ignore:line\n*/}\n\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\n\n/**\n * Should be called to pad string to expected length\n *\n * @method padLeft\n * @param {String} string to be padded\n * @param {Number} characters that result string should have\n * @param {String} sign, by default 0\n * @returns {String} right aligned string\n */\nvar padLeft = function (string, chars, sign) {\n return new Array(chars - string.length + 1).join(sign ? sign : \"0\") + string;\n};\n\n/**\n * Formats input value to byte representation of int\n * If value is negative, return it's two's complement\n * If the value is floating point, round it down\n *\n * @method formatInputInt\n * @param {String|Number|BigNumber} value that needs to be formatted\n * @returns {String} right-aligned byte representation of int\n */\nvar formatInputInt = function (value) {\n var padding = c.ETH_PADDING * 2;\n BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);\n return padLeft(utils.toTwosComplement(value).round().toString(16), padding);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputString\n * @param {String}\n * @returns {String} left-algined byte representation of string\n */\nvar formatInputString = function (value) {\n return utils.fromAscii(value, c.ETH_PADDING).substr(2);\n};\n\n/**\n * Formats input value to byte representation of bool\n *\n * @method formatInputBool\n * @param {Boolean}\n * @returns {String} right-aligned byte representation bool\n */\nvar formatInputBool = function (value) {\n return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n};\n\n/**\n * Formats input value to byte representation of real\n * Values are multiplied by 2^m and encoded as integers\n *\n * @method formatInputReal\n * @param {String|Number|BigNumber}\n * @returns {String} byte representation of real\n */\nvar formatInputReal = function (value) {\n return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); \n};\n\n/**\n * Check if input value is negative\n *\n * @method signedIsNegative\n * @param {String} value is hex format\n * @returns {Boolean} true if it is negative, otherwise false\n */\nvar signedIsNegative = function (value) {\n return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1';\n};\n\n/**\n * Formats right-aligned output bytes to int\n *\n * @method formatOutputInt\n * @param {String} bytes\n * @returns {BigNumber} right-aligned output bytes formatted to big number\n */\nvar formatOutputInt = function (value) {\n\n value = value || \"0\";\n\n // check if it's negative number\n // it it is, return two's complement\n if (signedIsNegative(value)) {\n return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1);\n }\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to uint\n *\n * @method formatOutputUInt\n * @param {String} bytes\n * @returns {BigNumeber} right-aligned output bytes formatted to uint\n */\nvar formatOutputUInt = function (value) {\n value = value || \"0\";\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to real\n *\n * @method formatOutputReal\n * @param {String}\n * @returns {BigNumber} input bytes formatted to real\n */\nvar formatOutputReal = function (value) {\n return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Formats right-aligned output bytes to ureal\n *\n * @method formatOutputUReal\n * @param {String}\n * @returns {BigNumber} input bytes formatted to ureal\n */\nvar formatOutputUReal = function (value) {\n return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Should be used to format output hash\n *\n * @method formatOutputHash\n * @param {String}\n * @returns {String} right-aligned output bytes formatted to hex\n */\nvar formatOutputHash = function (value) {\n return \"0x\" + value;\n};\n\n/**\n * Should be used to format output bool\n *\n * @method formatOutputBool\n * @param {String}\n * @returns {Boolean} right-aligned input bytes formatted to bool\n */\nvar formatOutputBool = function (value) {\n return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputString\n * @param {Sttring} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputString = function (value) {\n return utils.toAscii(value);\n};\n\n/**\n * Should be used to format output address\n *\n * @method formatOutputAddress\n * @param {String} right-aligned input bytes\n * @returns {String} address\n */\nvar formatOutputAddress = function (value) {\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nmodule.exports = {\n formatInputInt: formatInputInt,\n formatInputString: formatInputString,\n formatInputBool: formatInputBool,\n formatInputReal: formatInputReal,\n formatOutputInt: formatOutputInt,\n formatOutputUInt: formatOutputUInt,\n formatOutputReal: formatOutputReal,\n formatOutputUReal: formatOutputUReal,\n formatOutputHash: formatOutputHash,\n formatOutputBool: formatOutputBool,\n formatOutputString: formatOutputString,\n formatOutputAddress: formatOutputAddress\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file types.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar f = require('./formatters');\n\n/// @param expected type prefix (string)\n/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false\nvar prefixedType = function (prefix) {\n return function (type) {\n return type.indexOf(prefix) === 0;\n };\n};\n\n/// @param expected type name (string)\n/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false\nvar namedType = function (name) {\n return function (type) {\n return name === type;\n };\n};\n\n/// Setups input formatters for solidity types\n/// @returns an array of input formatters \nvar inputTypes = function () {\n \n return [\n { type: prefixedType('uint'), format: f.formatInputInt },\n { type: prefixedType('int'), format: f.formatInputInt },\n { type: prefixedType('hash'), format: f.formatInputInt },\n { type: prefixedType('string'), format: f.formatInputString }, \n { type: prefixedType('real'), format: f.formatInputReal },\n { type: prefixedType('ureal'), format: f.formatInputReal },\n { type: namedType('address'), format: f.formatInputInt },\n { type: namedType('bool'), format: f.formatInputBool }\n ];\n};\n\n/// Setups output formaters for solidity types\n/// @returns an array of output formatters\nvar outputTypes = function () {\n\n return [\n { type: prefixedType('uint'), format: f.formatOutputUInt },\n { type: prefixedType('int'), format: f.formatOutputInt },\n { type: prefixedType('hash'), format: f.formatOutputHash },\n { type: prefixedType('string'), format: f.formatOutputString },\n { type: prefixedType('real'), format: f.formatOutputReal },\n { type: prefixedType('ureal'), format: f.formatOutputUReal },\n { type: namedType('address'), format: f.formatOutputAddress },\n { type: namedType('bool'), format: f.formatOutputBool }\n ];\n};\n\nmodule.exports = {\n prefixedType: prefixedType,\n namedType: namedType,\n inputTypes: inputTypes,\n outputTypes: outputTypes\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file types.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar f = require('./formatters');\n\n/// @param expected type prefix (string)\n/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false\nvar prefixedType = function (prefix) {\n return function (type) {\n return type.indexOf(prefix) === 0;\n };\n};\n\n/// @param expected type name (string)\n/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false\nvar namedType = function (name) {\n return function (type) {\n return name === type;\n };\n};\n\n/// Setups input formatters for solidity types\n/// @returns an array of input formatters \nvar inputTypes = function () {\n \n return [\n { type: prefixedType('uint'), format: f.formatInputInt },\n { type: prefixedType('int'), format: f.formatInputInt },\n { type: prefixedType('bytes'), format: f.formatInputString }, \n { type: prefixedType('real'), format: f.formatInputReal },\n { type: prefixedType('ureal'), format: f.formatInputReal },\n { type: namedType('address'), format: f.formatInputInt },\n { type: namedType('bool'), format: f.formatInputBool }\n ];\n};\n\n/// Setups output formaters for solidity types\n/// @returns an array of output formatters\nvar outputTypes = function () {\n\n return [\n { type: prefixedType('uint'), format: f.formatOutputUInt },\n { type: prefixedType('int'), format: f.formatOutputInt },\n { type: prefixedType('bytes'), format: f.formatOutputString },\n { type: prefixedType('real'), format: f.formatOutputReal },\n { type: prefixedType('ureal'), format: f.formatOutputUReal },\n { type: namedType('address'), format: f.formatOutputAddress },\n { type: namedType('bool'), format: f.formatOutputBool }\n ];\n};\n\nmodule.exports = {\n prefixedType: prefixedType,\n namedType: namedType,\n inputTypes: inputTypes,\n outputTypes: outputTypes\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file config.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] config\n * @constructor\n */\n\n/// required to define ETH_BIGNUMBER_ROUNDING_MODE\nif (\"build\" !== 'build') {/*\n var BigNumber = require('bignumber.js'); // jshint ignore:line\n*/}\n\nvar ETH_UNITS = [ \n 'wei', \n 'Kwei', \n 'Mwei', \n 'Gwei', \n 'szabo', \n 'finney', \n 'ether', \n 'grand', \n 'Mether', \n 'Gether', \n 'Tether', \n 'Pether', \n 'Eether', \n 'Zether', \n 'Yether', \n 'Nether', \n 'Dether', \n 'Vether', \n 'Uether' \n];\n\nmodule.exports = {\n ETH_PADDING: 32,\n ETH_SIGNATURE_LENGTH: 4,\n ETH_UNITS: ETH_UNITS,\n ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN },\n ETH_POLLING_TIMEOUT: 1000,\n ETH_DEFAULTBLOCK: 'latest'\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file utils.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Utils\n * \n * @module utils\n */\n\n/**\n * Utility functions\n * \n * @class [utils] utils\n * @constructor\n */\n\nif (\"build\" !== 'build') {/*\n var BigNumber = require('bignumber.js'); // jshint ignore:line\n*/}\n\nvar unitMap = {\n 'wei': '1',\n 'kwei': '1000',\n 'ada': '1000',\n 'mwei': '1000000',\n 'babbage': '1000000',\n 'gwei': '1000000000',\n 'shannon': '1000000000',\n 'szabo': '1000000000000',\n 'finney': '1000000000000000',\n 'ether': '1000000000000000000',\n 'kether': '1000000000000000000000',\n 'grand': '1000000000000000000000',\n 'einstein': '1000000000000000000000',\n 'mether': '1000000000000000000000000',\n 'gether': '1000000000000000000000000000',\n 'tether': '1000000000000000000000000000000'\n};\n\n\n/** Finds first index of array element matching pattern\n *\n * @method findIndex\n * @param {Array}\n * @param {Function} pattern\n * @returns {Number} index of element\n */\nvar findIndex = function (array, callback) {\n var end = false;\n var i = 0;\n for (; i < array.length && !end; i++) {\n end = callback(array[i]);\n }\n return end ? i - 1 : -1;\n};\n\n/** \n * Should be called to get sting from it's hex representation\n *\n * @method toAscii\n * @param {String} string in hex\n * @returns {String} ascii string representation of hex value\n */\nvar toAscii = function(hex) {\n// Find termination\n var str = \"\";\n var i = 0, l = hex.length;\n if (hex.substring(0, 2) === '0x') {\n i = 2;\n }\n for (; i < l; i+=2) {\n var code = parseInt(hex.substr(i, 2), 16);\n if (code === 0) {\n break;\n }\n\n str += String.fromCharCode(code);\n }\n\n return str;\n};\n \n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method fromAscii\n * @param {String} string\n * @returns {String} hex representation of input string\n */\nvar toHexNative = function(str) {\n var hex = \"\";\n for(var i = 0; i < str.length; i++) {\n var n = str.charCodeAt(i).toString(16);\n hex += n.length < 2 ? '0' + n : n;\n }\n\n return hex;\n};\n\n/**\n * Shold be called to get hex representation (prefixed by 0x) of ascii string \n *\n * @method fromAscii\n * @param {String} string\n * @param {Number} optional padding\n * @returns {String} hex representation of input string\n */\nvar fromAscii = function(str, pad) {\n pad = pad === undefined ? 0 : pad;\n var hex = toHexNative(str);\n while (hex.length < pad*2)\n hex += \"00\";\n return \"0x\" + hex;\n};\n\n/**\n * Should be called to get display name of contract function\n * \n * @method extractDisplayName\n * @param {String} name of function/event\n * @returns {String} display name for function/event eg. multiply(uint256) -> multiply\n */\nvar extractDisplayName = function (name) {\n var length = name.indexOf('('); \n return length !== -1 ? name.substr(0, length) : name;\n};\n\n/// @returns overloaded part of function/event name\nvar extractTypeName = function (name) {\n /// TODO: make it invulnerable\n var length = name.indexOf('(');\n return length !== -1 ? name.substr(length + 1, name.length - 1 - (length + 1)).replace(' ', '') : \"\";\n};\n\n/**\n * Filters all functions from input abi\n *\n * @method filterFunctions\n * @param {Array} abi\n * @returns {Array} abi array with filtered objects of type 'function'\n */\nvar filterFunctions = function (json) {\n return json.filter(function (current) {\n return current.type === 'function'; \n }); \n};\n\n/**\n * Filters all events from input abi\n *\n * @method filterEvents\n * @param {Array} abi\n * @returns {Array} abi array with filtered objects of type 'event'\n */\nvar filterEvents = function (json) {\n return json.filter(function (current) {\n return current.type === 'event';\n });\n};\n\n/**\n * Converts value to it's decimal representation in string\n *\n * @method toDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar toDecimal = function (value) {\n return toBigNumber(value).toNumber();\n};\n\n/**\n * Converts value to it's hex representation\n *\n * @method fromDecimal\n * @param {String|Number|BigNumber}\n * @return {String}\n */\nvar fromDecimal = function (value) {\n var number = toBigNumber(value);\n var result = number.toString(16);\n\n return number.lessThan(0) ? '-0x' + result.substr(1) : '0x' + result;\n};\n\n/**\n * Auto converts any given value into it's hex representation.\n *\n * And even stringifys objects before.\n *\n * @method toHex\n * @param {String|Number|BigNumber|Object}\n * @return {String}\n */\nvar toHex = function (val) {\n /*jshint maxcomplexity:7 */\n\n if(isBoolean(val))\n return val;\n\n if(isBigNumber(val))\n return fromDecimal(val);\n\n if(isObject(val))\n return fromAscii(JSON.stringify(val));\n\n // if its a negative number, pass it through fromDecimal\n if (isString(val)) {\n if (val.indexOf('-0x') === 0)\n return fromDecimal(val);\n else if (!isFinite(val))\n return fromAscii(val);\n }\n\n return fromDecimal(val);\n};\n\n/**\n * Returns value of unit in Wei\n *\n * @method getValueOfUnit\n * @param {String} unit the unit to convert to, default ether\n * @returns {BigNumber} value of the unit (in Wei)\n * @throws error if the unit is not correct:w\n */\nvar getValueOfUnit = function (unit) {\n unit = unit ? unit.toLowerCase() : 'ether';\n var unitValue = unitMap[unit];\n if (unitValue === undefined) {\n throw new Error('This unit doesn\\'t exists, please use the one of the following units' + JSON.stringify(unitMap, null, 2));\n }\n return new BigNumber(unitValue, 10);\n};\n\n/**\n * Takes a number of wei and converts it to any other ether unit.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method fromWei\n * @param {Number|String} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert to, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar fromWei = function(number, unit) {\n var returnValue = toBigNumber(number).dividedBy(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes a number of a unit and converts it to wei.\n *\n * Possible units are:\n * - kwei/ada\n * - mwei/babbage\n * - gwei/shannon\n * - szabo\n * - finney\n * - ether\n * - kether/grand/einstein\n * - mether\n * - gether\n * - tether\n *\n * @method toWei\n * @param {Number|String|BigNumber} number can be a number, number string or a HEX of a decimal\n * @param {String} unit the unit to convert from, default ether\n * @return {String|Object} When given a BigNumber object it returns one as well, otherwise a number\n*/\nvar toWei = function(number, unit) {\n var returnValue = toBigNumber(number).times(getValueOfUnit(unit));\n\n return isBigNumber(number) ? returnValue : returnValue.toString(10); \n};\n\n/**\n * Takes an input and transforms it into an bignumber\n *\n * @method toBigNumber\n * @param {Number|String|BigNumber} a number, string, HEX string or BigNumber\n * @return {BigNumber} BigNumber\n*/\nvar toBigNumber = function(number) {\n /*jshint maxcomplexity:5 */\n number = number || 0;\n if (isBigNumber(number))\n return number;\n\n if (isString(number) && (number.indexOf('0x') === 0 || number.indexOf('-0x') === 0)) {\n return new BigNumber(number.replace('0x',''), 16);\n }\n \n return new BigNumber(number.toString(10), 10);\n};\n\n/**\n * Takes and input transforms it into bignumber and if it is negative value, into two's complement\n *\n * @method toTwosComplement\n * @param {Number|String|BigNumber}\n * @return {BigNumber}\n */\nvar toTwosComplement = function (number) {\n var bigNumber = toBigNumber(number);\n if (bigNumber.lessThan(0)) {\n return new BigNumber(\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\", 16).plus(bigNumber).plus(1);\n }\n return bigNumber;\n};\n\n/**\n * Checks if the given string has proper length\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function(address) {\n if (!isString(address)) {\n return false;\n }\n\n return ((address.indexOf('0x') === 0 && address.length === 42) ||\n (address.indexOf('0x') === -1 && address.length === 40));\n};\n\n/**\n * Returns true if object is BigNumber, otherwise false\n *\n * @method isBigNumber\n * @param {Object}\n * @return {Boolean} \n */\nvar isBigNumber = function (object) {\n return object instanceof BigNumber ||\n (object && object.constructor && object.constructor.name === 'BigNumber');\n};\n\n/**\n * Returns true if object is string, otherwise false\n * \n * @method isString\n * @param {Object}\n * @return {Boolean}\n */\nvar isString = function (object) {\n return typeof object === 'string' ||\n (object && object.constructor && object.constructor.name === 'String');\n};\n\n/**\n * Returns true if object is function, otherwise false\n *\n * @method isFunction\n * @param {Object}\n * @return {Boolean}\n */\nvar isFunction = function (object) {\n return typeof object === 'function';\n};\n\n/**\n * Returns true if object is Objet, otherwise false\n *\n * @method isObject\n * @param {Object}\n * @return {Boolean}\n */\nvar isObject = function (object) {\n return typeof object === 'object';\n};\n\n/**\n * Returns true if object is boolean, otherwise false\n *\n * @method isBoolean\n * @param {Object}\n * @return {Boolean}\n */\nvar isBoolean = function (object) {\n return typeof object === 'boolean';\n};\n\n/**\n * Returns true if object is array, otherwise false\n *\n * @method isArray\n * @param {Object}\n * @return {Boolean}\n */\nvar isArray = function (object) {\n return object instanceof Array; \n};\n\nmodule.exports = {\n findIndex: findIndex,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n filterFunctions: filterFunctions,\n filterEvents: filterEvents,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n isBigNumber: isBigNumber,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file web3.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Gav Wood \n * @date 2014\n */\n\nvar net = require('./web3/net');\nvar eth = require('./web3/eth');\nvar db = require('./web3/db');\nvar shh = require('./web3/shh');\nvar watches = require('./web3/watches');\nvar filter = require('./web3/filter');\nvar utils = require('./utils/utils');\nvar formatters = require('./solidity/formatters');\nvar requestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\n\n/// @returns an array of objects describing web3 api methods\nvar web3Methods = function () {\n return [\n { name: 'sha3', call: 'web3_sha3' }\n ];\n};\n\n/// creates methods in a given object based on method description on input\n/// setups api calls for these methods\nvar setupMethods = function (obj, methods) {\n methods.forEach(function (method) {\n // allow for object methods 'myObject.method'\n var objectMethods = method.name.split('.'),\n callFunction = function () {\n /*jshint maxcomplexity:8 */\n \n var callback = null,\n args = Array.prototype.slice.call(arguments),\n call = typeof method.call === 'function' ? method.call(args) : method.call;\n\n // get the callback if one is available\n if(typeof args[args.length-1] === 'function'){\n callback = args[args.length-1];\n Array.prototype.pop.call(args);\n }\n\n // add the defaultBlock if not given\n if(method.addDefaultblock) {\n if(args.length !== method.addDefaultblock)\n Array.prototype.push.call(args, (isFinite(c.ETH_DEFAULTBLOCK) ? utils.fromDecimal(c.ETH_DEFAULTBLOCK) : c.ETH_DEFAULTBLOCK));\n else\n args[args.length-1] = isFinite(args[args.length-1]) ? utils.fromDecimal(args[args.length-1]) : args[args.length-1];\n }\n\n // show deprecated warning\n if(method.newMethod)\n console.warn('This method is deprecated please use web3.'+ method.newMethod +'() instead.');\n\n return web3.manager.send({\n method: call,\n params: args,\n outputFormatter: method.outputFormatter,\n inputFormatter: method.inputFormatter,\n addDefaultblock: method.addDefaultblock\n }, callback);\n };\n\n if(objectMethods.length > 1) {\n if(!obj[objectMethods[0]])\n obj[objectMethods[0]] = {};\n\n obj[objectMethods[0]][objectMethods[1]] = callFunction;\n \n } else {\n\n obj[objectMethods[0]] = callFunction;\n }\n\n });\n};\n\n/// creates properties in a given object based on properties description on input\n/// setups api calls for these properties\nvar setupProperties = function (obj, properties) {\n properties.forEach(function (property) {\n var proto = {};\n proto.get = function () {\n\n // show deprecated warning\n if(property.newProperty)\n console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');\n\n\n return web3.manager.send({\n method: property.getter,\n outputFormatter: property.outputFormatter\n });\n };\n\n if (property.setter) {\n proto.set = function (val) {\n\n // show deprecated warning\n if(property.newProperty)\n console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');\n\n return web3.manager.send({\n method: property.setter,\n params: [val],\n inputFormatter: property.inputFormatter\n });\n };\n }\n\n proto.enumerable = !property.newProperty;\n Object.defineProperty(obj, property.name, proto);\n\n });\n};\n\n/*jshint maxparams:4 */\nvar startPolling = function (method, id, callback, uninstall) {\n web3.manager.startPolling({\n method: method, \n params: [id]\n }, id, callback, uninstall); \n};\n/*jshint maxparams:3 */\n\nvar stopPolling = function (id) {\n web3.manager.stopPolling(id);\n};\n\nvar ethWatch = {\n startPolling: startPolling.bind(null, 'eth_getFilterChanges'), \n stopPolling: stopPolling\n};\n\nvar shhWatch = {\n startPolling: startPolling.bind(null, 'shh_getFilterChanges'), \n stopPolling: stopPolling\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {\n manager: requestManager(),\n providers: {},\n\n setProvider: function (provider) {\n web3.manager.setProvider(provider);\n },\n \n /// Should be called to reset state of web3 object\n /// Resets everything except manager\n reset: function () {\n web3.manager.reset(); \n },\n\n /// @returns hex string of the input\n toHex: utils.toHex,\n\n /// @returns ascii string representation of hex value prefixed with 0x\n toAscii: utils.toAscii,\n\n /// @returns hex representation (prefixed by 0x) of ascii string\n fromAscii: utils.fromAscii,\n\n /// @returns decimal representaton of hex value prefixed by 0x\n toDecimal: utils.toDecimal,\n\n /// @returns hex representation (prefixed by 0x) of decimal value\n fromDecimal: utils.fromDecimal,\n\n /// @returns a BigNumber object\n toBigNumber: utils.toBigNumber,\n\n toWei: utils.toWei,\n fromWei: utils.fromWei,\n isAddress: utils.isAddress,\n\n // provide network information\n net: {\n // peerCount: \n },\n\n\n /// eth object prototype\n eth: {\n // DEPRECATED\n contractFromAbi: function (abi) {\n console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');\n\n return function(addr) {\n // Default to address of Config. TODO: rremove prior to genesis.\n addr = addr || '0xc6d9d2cd449a754c494264e1809c50e34d64562b';\n var ret = web3.eth.contract(addr, abi);\n ret.address = addr;\n return ret;\n };\n },\n\n /// @param filter may be a string, object or event\n /// @param eventParams is optional, this is an object with optional event eventParams params\n /// @param options is optional, this is an object with optional event options ('max'...)\n /*jshint maxparams:4 */\n filter: function (fil, eventParams, options) {\n\n // if its event, treat it differently\n if (fil._isEvent)\n return fil(eventParams, options);\n\n return filter(fil, ethWatch, formatters.outputLogFormatter);\n },\n // DEPRECATED\n watch: function (fil, eventParams, options) {\n console.warn('eth.watch() is deprecated please use eth.filter() instead.');\n return this.filter(fil, eventParams, options);\n }\n /*jshint maxparams:3 */\n },\n\n /// db object prototype\n db: {},\n\n /// shh object prototype\n shh: {\n /// @param filter may be a string, object or event\n filter: function (fil) {\n return filter(fil, shhWatch, formatters.outputPostFormatter);\n },\n // DEPRECATED\n watch: function (fil) {\n console.warn('shh.watch() is deprecated please use shh.filter() instead.');\n return this.filter(fil);\n }\n }\n};\n\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.ETH_DEFAULTBLOCK;\n },\n set: function (val) {\n c.ETH_DEFAULTBLOCK = val;\n return c.ETH_DEFAULTBLOCK;\n }\n});\n\n\n/// setups all api methods\nsetupMethods(web3, web3Methods());\nsetupMethods(web3.net, net.methods);\nsetupProperties(web3.net, net.properties);\nsetupMethods(web3.eth, eth.methods);\nsetupProperties(web3.eth, eth.properties);\nsetupMethods(web3.db, db.methods());\nsetupMethods(web3.shh, shh.methods());\nsetupMethods(ethWatch, watches.eth());\nsetupMethods(shhWatch, watches.shh());\n\nmodule.exports = web3;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file web3.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar version = require('../version.json');\nvar net = require('./web3/net');\nvar eth = require('./web3/eth');\nvar db = require('./web3/db');\nvar shh = require('./web3/shh');\nvar watches = require('./web3/watches');\nvar filter = require('./web3/filter');\nvar utils = require('./utils/utils');\nvar formatters = require('./solidity/formatters');\nvar requestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\n\n/// @returns an array of objects describing web3 api methods\nvar web3Methods = [\n { name: 'sha3', call: 'web3_sha3', inputFormatter: utils.toHex },\n];\nvar web3Properties = [\n { name: 'version.client', getter: 'web3_clientVersion' },\n { name: 'version.network', getter: 'net_version' }\n];\n\n\n/// creates methods in a given object based on method description on input\n/// setups api calls for these methods\nvar setupMethods = function (obj, methods) {\n methods.forEach(function (method) {\n // allow for object methods 'myObject.method'\n var objectMethods = method.name.split('.'),\n callFunction = function () {\n /*jshint maxcomplexity:8 */\n \n var callback = null,\n args = Array.prototype.slice.call(arguments),\n call = typeof method.call === 'function' ? method.call(args) : method.call;\n\n // get the callback if one is available\n if(typeof args[args.length-1] === 'function'){\n callback = args[args.length-1];\n Array.prototype.pop.call(args);\n }\n\n // add the defaultBlock if not given\n if(method.addDefaultblock) {\n if(args.length !== method.addDefaultblock)\n Array.prototype.push.call(args, (isFinite(c.ETH_DEFAULTBLOCK) ? utils.fromDecimal(c.ETH_DEFAULTBLOCK) : c.ETH_DEFAULTBLOCK));\n else\n args[args.length-1] = isFinite(args[args.length-1]) ? utils.fromDecimal(args[args.length-1]) : args[args.length-1];\n }\n\n // show deprecated warning\n if(method.newMethod)\n console.warn('This method is deprecated please use web3.'+ method.newMethod +'() instead.');\n\n return web3.manager.send({\n method: call,\n params: args,\n outputFormatter: method.outputFormatter,\n inputFormatter: method.inputFormatter,\n addDefaultblock: method.addDefaultblock\n }, callback);\n };\n\n if(objectMethods.length > 1) {\n if(!obj[objectMethods[0]])\n obj[objectMethods[0]] = {};\n\n obj[objectMethods[0]][objectMethods[1]] = callFunction;\n \n } else {\n\n obj[objectMethods[0]] = callFunction;\n }\n\n });\n};\n\n/// creates properties in a given object based on properties description on input\n/// setups api calls for these properties\nvar setupProperties = function (obj, properties) {\n properties.forEach(function (property) {\n var objectProperties = property.name.split('.'),\n proto = {};\n\n proto.get = function () {\n\n // show deprecated warning\n if(property.newProperty)\n console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');\n\n\n return web3.manager.send({\n method: property.getter,\n outputFormatter: property.outputFormatter\n });\n };\n\n if (property.setter) {\n proto.set = function (val) {\n\n // show deprecated warning\n if(property.newProperty)\n console.warn('This property is deprecated please use web3.'+ property.newProperty +' instead.');\n\n return web3.manager.send({\n method: property.setter,\n params: [val],\n inputFormatter: property.inputFormatter\n });\n };\n }\n\n proto.enumerable = !property.newProperty;\n\n if(objectProperties.length > 1) {\n if(!obj[objectProperties[0]])\n obj[objectProperties[0]] = {};\n\n Object.defineProperty(obj[objectProperties[0]], objectProperties[1], proto); \n } else\n Object.defineProperty(obj, property.name, proto);\n\n });\n};\n\n/*jshint maxparams:4 */\nvar startPolling = function (method, id, callback, uninstall) {\n web3.manager.startPolling({\n method: method, \n params: [id]\n }, id, callback, uninstall); \n};\n/*jshint maxparams:3 */\n\nvar stopPolling = function (id) {\n web3.manager.stopPolling(id);\n};\n\nvar ethWatch = {\n startPolling: startPolling.bind(null, 'eth_getFilterChanges'), \n stopPolling: stopPolling\n};\n\nvar shhWatch = {\n startPolling: startPolling.bind(null, 'shh_getFilterChanges'), \n stopPolling: stopPolling\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {\n\n version: {\n api: version.version\n },\n\n manager: requestManager(),\n providers: {},\n\n setProvider: function (provider) {\n web3.manager.setProvider(provider);\n },\n \n /// Should be called to reset state of web3 object\n /// Resets everything except manager\n reset: function () {\n web3.manager.reset(); \n },\n\n /// @returns hex string of the input\n toHex: utils.toHex,\n\n /// @returns ascii string representation of hex value prefixed with 0x\n toAscii: utils.toAscii,\n\n /// @returns hex representation (prefixed by 0x) of ascii string\n fromAscii: utils.fromAscii,\n\n /// @returns decimal representaton of hex value prefixed by 0x\n toDecimal: utils.toDecimal,\n\n /// @returns hex representation (prefixed by 0x) of decimal value\n fromDecimal: utils.fromDecimal,\n\n /// @returns a BigNumber object\n toBigNumber: utils.toBigNumber,\n\n toWei: utils.toWei,\n fromWei: utils.fromWei,\n isAddress: utils.isAddress,\n\n // provide network information\n net: {\n // peerCount: \n },\n\n\n /// eth object prototype\n eth: {\n // DEPRECATED\n contractFromAbi: function (abi) {\n console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');\n\n return function(addr) {\n // Default to address of Config. TODO: rremove prior to genesis.\n addr = addr || '0xc6d9d2cd449a754c494264e1809c50e34d64562b';\n var ret = web3.eth.contract(addr, abi);\n ret.address = addr;\n return ret;\n };\n },\n\n /// @param filter may be a string, object or event\n /// @param eventParams is optional, this is an object with optional event eventParams params\n /// @param options is optional, this is an object with optional event options ('max'...)\n /*jshint maxparams:4 */\n filter: function (fil, eventParams, options) {\n\n // if its event, treat it differently\n if (fil._isEvent)\n return fil(eventParams, options);\n\n return filter(fil, ethWatch, formatters.outputLogFormatter);\n },\n // DEPRECATED\n watch: function (fil, eventParams, options) {\n console.warn('eth.watch() is deprecated please use eth.filter() instead.');\n return this.filter(fil, eventParams, options);\n }\n /*jshint maxparams:3 */\n },\n\n /// db object prototype\n db: {},\n\n /// shh object prototype\n shh: {\n /// @param filter may be a string, object or event\n filter: function (fil) {\n return filter(fil, shhWatch, formatters.outputPostFormatter);\n },\n // DEPRECATED\n watch: function (fil) {\n console.warn('shh.watch() is deprecated please use shh.filter() instead.');\n return this.filter(fil);\n }\n }\n};\n\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.ETH_DEFAULTBLOCK;\n },\n set: function (val) {\n c.ETH_DEFAULTBLOCK = val;\n return c.ETH_DEFAULTBLOCK;\n }\n});\n\n\n/// setups all api methods\nsetupMethods(web3, web3Methods);\nsetupProperties(web3, web3Properties);\nsetupMethods(web3.net, net.methods);\nsetupProperties(web3.net, net.properties);\nsetupMethods(web3.eth, eth.methods);\nsetupProperties(web3.eth, eth.properties);\nsetupMethods(web3.db, db.methods());\nsetupMethods(web3.shh, shh.methods());\nsetupMethods(ethWatch, watches.eth());\nsetupMethods(shhWatch, watches.shh());\n\nmodule.exports = web3;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file contract.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar abi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar eventImpl = require('./event');\nvar signature = require('./signature');\n\nvar exportNatspecGlobals = function (vars) {\n // it's used byt natspec.js\n // TODO: figure out better way to solve this\n web3._currentContractAbi = vars.abi;\n web3._currentContractAddress = vars.address;\n web3._currentContractMethodName = vars.method;\n web3._currentContractMethodParams = vars.params;\n};\n\nvar addFunctionRelatedPropertiesToContract = function (contract) {\n \n contract.call = function (options) {\n contract._isTransaction = false;\n contract._options = options;\n return contract;\n };\n\n\n contract.sendTransaction = function (options) {\n contract._isTransaction = true;\n contract._options = options;\n return contract;\n };\n // DEPRECATED\n contract.transact = function (options) {\n\n console.warn('myContract.transact() is deprecated please use myContract.sendTransaction() instead.');\n\n return contract.sendTransaction(options);\n };\n\n contract._options = {};\n ['gas', 'gasPrice', 'value', 'from'].forEach(function(p) {\n contract[p] = function (v) {\n contract._options[p] = v;\n return contract;\n };\n });\n\n};\n\nvar addFunctionsToContract = function (contract, desc, address) {\n var inputParser = abi.inputParser(desc);\n var outputParser = abi.outputParser(desc);\n\n // create contract functions\n utils.filterFunctions(desc).forEach(function (method) {\n\n var displayName = utils.extractDisplayName(method.name);\n var typeName = utils.extractTypeName(method.name);\n\n var impl = function () {\n /*jshint maxcomplexity:7 */\n var params = Array.prototype.slice.call(arguments);\n var sign = signature.functionSignatureFromAscii(method.name);\n var parsed = inputParser[displayName][typeName].apply(null, params);\n\n var options = contract._options || {};\n options.to = address;\n options.data = sign + parsed;\n \n var isTransaction = contract._isTransaction === true || (contract._isTransaction !== false && !method.constant);\n var collapse = options.collapse !== false;\n \n // reset\n contract._options = {};\n contract._isTransaction = null;\n\n if (isTransaction) {\n \n exportNatspecGlobals({\n abi: desc,\n address: address,\n method: method.name,\n params: params\n });\n\n // transactions do not have any output, cause we do not know, when they will be processed\n web3.eth.sendTransaction(options);\n return;\n }\n \n var output = web3.eth.call(options);\n var ret = outputParser[displayName][typeName](output);\n if (collapse)\n {\n if (ret.length === 1)\n ret = ret[0];\n else if (ret.length === 0)\n ret = null;\n }\n return ret;\n };\n\n if (contract[displayName] === undefined) {\n contract[displayName] = impl;\n }\n\n contract[displayName][typeName] = impl;\n });\n};\n\nvar addEventRelatedPropertiesToContract = function (contract, desc, address) {\n contract.address = address;\n contract._onWatchEventResult = function (data) {\n var matchingEvent = event.getMatchingEvent(utils.filterEvents(desc));\n var parser = eventImpl.outputParser(matchingEvent);\n return parser(data);\n };\n \n Object.defineProperty(contract, 'topics', {\n get: function() {\n return utils.filterEvents(desc).map(function (e) {\n return signature.eventSignatureFromAscii(e.name);\n });\n }\n });\n\n};\n\nvar addEventsToContract = function (contract, desc, address) {\n // create contract events\n utils.filterEvents(desc).forEach(function (e) {\n\n var impl = function () {\n var params = Array.prototype.slice.call(arguments);\n var sign = signature.eventSignatureFromAscii(e.name);\n var event = eventImpl.inputParser(address, sign, e);\n var o = event.apply(null, params);\n var outputFormatter = function (data) {\n var parser = eventImpl.outputParser(e);\n return parser(data);\n };\n return web3.eth.filter(o, undefined, undefined, outputFormatter);\n };\n \n // this property should be used by eth.filter to check if object is an event\n impl._isEvent = true;\n\n var displayName = utils.extractDisplayName(e.name);\n var typeName = utils.extractTypeName(e.name);\n\n if (contract[displayName] === undefined) {\n contract[displayName] = impl;\n }\n\n contract[displayName][typeName] = impl;\n\n });\n};\n\n\n/**\n * This method should be called when we want to call / transact some solidity method from javascript\n * it returns an object which has same methods available as solidity contract description\n * usage example: \n *\n * var abi = [{\n * name: 'myMethod',\n * inputs: [{ name: 'a', type: 'string' }],\n * outputs: [{name: 'd', type: 'string' }]\n * }]; // contract abi\n *\n * var MyContract = web3.eth.contract(abi); // creation of contract prototype\n *\n * var contractInstance = new MyContract('0x0123123121');\n *\n * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default)\n * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit)\n * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction\n *\n * @param abi - abi json description of the contract, which is being created\n * @returns contract object\n */\nvar contract = function (abi) {\n\n // return prototype\n if(abi instanceof Array && arguments.length === 1) {\n return Contract.bind(null, abi);\n\n // deprecated: auto initiate contract\n } else {\n\n console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');\n\n return new Contract(arguments[1], arguments[0]);\n }\n\n};\n\nfunction Contract(abi, address) {\n\n // workaround for invalid assumption that method.name is the full anonymous prototype of the method.\n // it's not. it's just the name. the rest of the code assumes it's actually the anonymous\n // prototype, so we make it so as a workaround.\n // TODO: we may not want to modify input params, maybe use copy instead?\n abi.forEach(function (method) {\n if (method.name.indexOf('(') === -1) {\n var displayName = method.name;\n var typeName = method.inputs.map(function(i){return i.type; }).join();\n method.name = displayName + '(' + typeName + ')';\n }\n });\n\n var result = {};\n addFunctionRelatedPropertiesToContract(result);\n addFunctionsToContract(result, abi, address);\n addEventRelatedPropertiesToContract(result, abi, address);\n addEventsToContract(result, abi, address);\n\n return result;\n}\n\nmodule.exports = contract;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file db.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/// @returns an array of objects describing web3.db api methods\nvar methods = function () {\n return [\n { name: 'put', call: 'db_put' },\n { name: 'get', call: 'db_get' },\n { name: 'putString', call: 'db_putString' },\n { name: 'getString', call: 'db_getString' }\n ];\n};\n\nmodule.exports = {\n methods: methods\n};\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Web3\n * \n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ if(!param) return false; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n { name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,\n outputFormatter: formatters.convertToBigNumber},\n { name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2},\n { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,\n inputFormatter: utils.toHex},\n { name: 'getData', call: 'eth_getData', addDefaultblock: 2},\n { name: 'getBlock', call: blockCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getUncle', call: uncleCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getCompilers', call: 'eth_getCompilers' },\n { name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getBlockUncleCount', call: uncleCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getTransaction', call: 'eth_getTransactionByHash',\n outputFormatter: formatters.outputTransactionFormatter },\n { name: 'getTransactionFromBlock', call: transactionFromBlockCall,\n outputFormatter: formatters.outputTransactionFormatter,\n inputFormatter: utils.toHex },\n { name: 'getTransactionCount', call: 'eth_getTransactionCount', addDefaultblock: 2,\n outputFormatter: utils.toDecimal},\n { name: 'sendTransaction', call: 'eth_sendTransaction',\n inputFormatter: formatters.inputTransactionFormatter },\n { name: 'call', call: 'eth_call', addDefaultblock: 2,\n inputFormatter: formatters.inputCallFormatter },\n { name: 'compile.solidity', call: 'eth_compileSolidity', inputFormatter: utils.toHex },\n { name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },\n { name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },\n { name: 'flush', call: 'eth_flush' },\n\n // deprecated methods\n { name: 'balanceAt', call: 'eth_balanceAt', newMethod: 'eth.getBalance' },\n { name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },\n { name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },\n { name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },\n { name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getData' },\n { name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },\n { name: 'block', call: blockCall, newMethod: 'eth.getBlock' },\n { name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },\n { name: 'uncle', call: uncleCall, newMethod: 'eth.getUncle' },\n { name: 'compilers', call: 'eth_compilers', newMethod: 'eth.getCompilers' },\n { name: 'solidity', call: 'eth_solidity', newMethod: 'eth.compile.solidity' },\n { name: 'lll', call: 'eth_lll', newMethod: 'eth.compile.lll' },\n { name: 'serpent', call: 'eth_serpent', newMethod: 'eth.compile.serpent' },\n { name: 'transactionCount', call: getBlockTransactionCountCall, newMethod: 'eth.getBlockTransactionCount' },\n { name: 'uncleCount', call: uncleCountCall, newMethod: 'eth.getBlockUncleCount' },\n { name: 'logs', call: 'eth_logs' }\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n { name: 'coinbase', getter: 'eth_coinbase'},\n { name: 'mining', getter: 'eth_mining'},\n { name: 'gasPrice', getter: 'eth_gasPrice', outputFormatter: formatters.convertToBigNumber},\n { name: 'accounts', getter: 'eth_accounts' },\n { name: 'blockNumber', getter: 'eth_blockNumber', outputFormatter: utils.toDecimal},\n\n // deprecated properties\n { name: 'listening', getter: 'net_listening', setter: 'eth_setListening', newProperty: 'net.listening'},\n { name: 'peerCount', getter: 'net_peerCount', newProperty: 'net.peerCount'},\n { name: 'number', getter: 'eth_number', newProperty: 'eth.blockNumber'}\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file db.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n\n/// @returns an array of objects describing web3.db api methods\nvar methods = function () {\n return [\n { name: 'putString', call: 'db_putString'},\n { name: 'getString', call: 'db_getString'},\n { name: 'putHex', call: 'db_putHex'},\n { name: 'getHex', call: 'db_getHex'}\n ];\n};\n\nmodule.exports = {\n methods: methods\n};\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * Fabian Vogelsteller \n * @date 2015\n */\n\n/**\n * Web3\n * \n * @module web3\n */\n\n/**\n * Eth methods and properties\n *\n * An example method object can look as follows:\n *\n * {\n * name: 'getBlock',\n * call: blockCall,\n * outputFormatter: formatters.outputBlockFormatter,\n * inputFormatter: [ // can be a formatter funciton or an array of functions. Where each item in the array will be used for one parameter\n * utils.toHex, // formats paramter 1\n * function(param){ if(!param) return false; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n\nvar blockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? \"eth_getBlockByHash\" : \"eth_getBlockByNumber\";\n};\n\nvar transactionFromBlockCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getTransactionByBlockHashAndIndex' : 'eth_getTransactionByBlockNumberAndIndex';\n};\n\nvar uncleCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleByBlockHashAndIndex' : 'eth_getUncleByBlockNumberAndIndex';\n};\n\nvar getBlockTransactionCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getBlockTransactionCountByHash' : 'eth_getBlockTransactionCountByNumber';\n};\n\nvar uncleCountCall = function (args) {\n return (utils.isString(args[0]) && args[0].indexOf('0x') === 0) ? 'eth_getUncleCountByBlockHash' : 'eth_getUncleCountByBlockNumber';\n};\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n { name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2,\n outputFormatter: formatters.convertToBigNumber},\n { name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2},\n { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3,\n inputFormatter: utils.toHex},\n { name: 'getData', call: 'eth_getData', addDefaultblock: 2},\n { name: 'getBlock', call: blockCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getUncle', call: uncleCall,\n outputFormatter: formatters.outputBlockFormatter,\n inputFormatter: [utils.toHex, utils.toHex, function(param){ return (!param) ? false : true; }]},\n { name: 'getCompilers', call: 'eth_getCompilers' },\n { name: 'getBlockTransactionCount', call: getBlockTransactionCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getBlockUncleCount', call: uncleCountCall,\n outputFormatter: utils.toDecimal,\n inputFormatter: utils.toHex },\n { name: 'getTransaction', call: 'eth_getTransactionByHash',\n outputFormatter: formatters.outputTransactionFormatter },\n { name: 'getTransactionFromBlock', call: transactionFromBlockCall,\n outputFormatter: formatters.outputTransactionFormatter,\n inputFormatter: utils.toHex },\n { name: 'getTransactionCount', call: 'eth_getTransactionCount', addDefaultblock: 2,\n outputFormatter: utils.toDecimal},\n { name: 'sendTransaction', call: 'eth_sendTransaction',\n inputFormatter: formatters.inputTransactionFormatter },\n { name: 'call', call: 'eth_call', addDefaultblock: 2,\n inputFormatter: formatters.inputCallFormatter },\n { name: 'compile.solidity', call: 'eth_compileSolidity' },\n { name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex },\n { name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex },\n { name: 'flush', call: 'eth_flush' },\n\n // deprecated methods\n { name: 'balanceAt', call: 'eth_balanceAt', newMethod: 'eth.getBalance' },\n { name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' },\n { name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' },\n { name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' },\n { name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getData' },\n { name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' },\n { name: 'block', call: blockCall, newMethod: 'eth.getBlock' },\n { name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' },\n { name: 'uncle', call: uncleCall, newMethod: 'eth.getUncle' },\n { name: 'compilers', call: 'eth_compilers', newMethod: 'eth.getCompilers' },\n { name: 'solidity', call: 'eth_solidity', newMethod: 'eth.compile.solidity' },\n { name: 'lll', call: 'eth_lll', newMethod: 'eth.compile.lll' },\n { name: 'serpent', call: 'eth_serpent', newMethod: 'eth.compile.serpent' },\n { name: 'transactionCount', call: getBlockTransactionCountCall, newMethod: 'eth.getBlockTransactionCount' },\n { name: 'uncleCount', call: uncleCountCall, newMethod: 'eth.getBlockUncleCount' },\n { name: 'logs', call: 'eth_logs' }\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n { name: 'coinbase', getter: 'eth_coinbase'},\n { name: 'mining', getter: 'eth_mining'},\n { name: 'gasPrice', getter: 'eth_gasPrice', outputFormatter: formatters.convertToBigNumber},\n { name: 'accounts', getter: 'eth_accounts' },\n { name: 'blockNumber', getter: 'eth_blockNumber', outputFormatter: utils.toDecimal},\n\n // deprecated properties\n { name: 'listening', getter: 'net_listening', setter: 'eth_setListening', newProperty: 'net.listening'},\n { name: 'peerCount', getter: 'net_peerCount', newProperty: 'net.peerCount'},\n { name: 'number', getter: 'eth_number', newProperty: 'eth.blockNumber'}\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file event.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\nvar abi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar signature = require('./signature');\n\n/// filter inputs array && returns only indexed (or not) inputs\n/// @param inputs array\n/// @param bool if result should be an array of indexed params on not\n/// @returns array of (not?) indexed params\nvar filterInputs = function (inputs, indexed) {\n return inputs.filter(function (current) {\n return current.indexed === indexed;\n });\n};\n\nvar inputWithName = function (inputs, name) {\n var index = utils.findIndex(inputs, function (input) {\n return input.name === name;\n });\n \n if (index === -1) {\n console.error('indexed param with name ' + name + ' not found');\n return undefined;\n }\n return inputs[index];\n};\n\nvar indexedParamsToTopics = function (event, indexed) {\n // sort keys?\n return Object.keys(indexed).map(function (key) {\n var inputs = [inputWithName(filterInputs(event.inputs, true), key)];\n\n var value = indexed[key];\n if (value instanceof Array) {\n return value.map(function (v) {\n return abi.formatInput(inputs, [v]);\n }); \n }\n return abi.formatInput(inputs, [value]);\n });\n};\n\nvar inputParser = function (address, sign, event) {\n \n // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.filter'\n return function (indexed, options) {\n var o = options || {};\n o.address = address;\n o.topics = [];\n o.topics.push(sign);\n if (indexed) {\n o.topics = o.topics.concat(indexedParamsToTopics(event, indexed));\n }\n return o;\n };\n};\n\nvar getArgumentsObject = function (inputs, indexed, notIndexed) {\n var indexedCopy = indexed.slice();\n var notIndexedCopy = notIndexed.slice();\n return inputs.reduce(function (acc, current) {\n var value;\n if (current.indexed)\n value = indexedCopy.splice(0, 1)[0];\n else\n value = notIndexedCopy.splice(0, 1)[0];\n\n acc[current.name] = value;\n return acc;\n }, {}); \n};\n \nvar outputParser = function (event) {\n \n return function (output) {\n var result = {\n event: utils.extractDisplayName(event.name),\n number: output.number,\n hash: output.hash,\n args: {}\n };\n\n output.topics = output.topic; // fallback for go-ethereum\n if (!output.topics) {\n return result;\n }\n \n var indexedOutputs = filterInputs(event.inputs, true);\n var indexedData = \"0x\" + output.topics.slice(1, output.topics.length).map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedRes = abi.formatOutput(indexedOutputs, indexedData);\n\n var notIndexedOutputs = filterInputs(event.inputs, false);\n var notIndexedRes = abi.formatOutput(notIndexedOutputs, output.data);\n\n result.args = getArgumentsObject(event.inputs, indexedRes, notIndexedRes);\n\n return result;\n };\n};\n\nvar getMatchingEvent = function (events, payload) {\n for (var i = 0; i < events.length; i++) {\n var sign = signature.eventSignatureFromAscii(events[i].name); \n if (sign === payload.topics[0]) {\n return events[i];\n }\n }\n return undefined;\n};\n\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n getMatchingEvent: getMatchingEvent\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\n\n/// Should be called to check if filter implementation is valid\n/// @returns true if it is, otherwise false\nvar implementationIsValid = function (i) {\n return !!i && \n typeof i.newFilter === 'function' && \n typeof i.getLogs === 'function' && \n typeof i.uninstallFilter === 'function' &&\n typeof i.startPolling === 'function' &&\n typeof i.stopPolling === 'function';\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n /*jshint maxcomplexity:9 */\n\n if (typeof options === 'string') {\n return options;\n } \n\n options = options || {};\n\n if (options.topic) {\n console.warn('\"topic\" is deprecated, is \"topics\" instead');\n options.topics = options.topic;\n }\n\n if (options.earliest) {\n console.warn('\"earliest\" is deprecated, is \"fromBlock\" instead');\n options.fromBlock = options.earliest;\n }\n\n if (options.latest) {\n console.warn('\"latest\" is deprecated, is \"toBlock\" instead');\n options.toBlock = options.latest;\n }\n\n if (options.skip) {\n console.warn('\"skip\" is deprecated, is \"offset\" instead');\n options.offset = options.skip;\n }\n\n if (options.max) {\n console.warn('\"max\" is deprecated, is \"limit\" instead');\n options.limit = options.max;\n }\n\n // make sure topics, get converted to hex\n if(options.topics instanceof Array) {\n options.topics = options.topics.map(function(topic){\n return utils.toHex(topic);\n });\n }\n\n\n // evaluate lazy properties\n return {\n fromBlock: utils.toHex(options.fromBlock),\n toBlock: utils.toHex(options.toBlock),\n limit: utils.toHex(options.limit),\n offset: utils.toHex(options.offset),\n to: options.to,\n address: options.address,\n topics: options.topics\n };\n};\n\n/// Should be used when we want to watch something\n/// it's using inner polling mechanism and is notified about changes\n/// @param options are filter options\n/// @param implementation, an abstract polling implementation\n/// @param formatter (optional), callback function which formats output before 'real' callback \nvar filter = function(options, implementation, formatter) {\n if (!implementationIsValid(implementation)) {\n console.error('filter implemenation is invalid');\n return;\n }\n\n options = getOptions(options);\n var callbacks = [];\n var filterId = implementation.newFilter(options);\n\n // call the callbacks\n var onMessages = function (messages) {\n messages.forEach(function (message) {\n message = formatter ? formatter(message) : message;\n callbacks.forEach(function (callback) {\n callback(message);\n });\n });\n };\n\n implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);\n\n var watch = function(callback) {\n callbacks.push(callback);\n };\n\n var stopWatching = function() {\n implementation.stopPolling(filterId);\n implementation.uninstallFilter(filterId);\n callbacks = [];\n };\n\n var get = function () {\n var results = implementation.getLogs(filterId);\n\n return utils.isArray(results) ? results.map(function(message){\n return formatter ? formatter(message) : message;\n }) : results;\n };\n \n return {\n watch: watch,\n stopWatching: stopWatching,\n get: get,\n\n // DEPRECATED methods\n changed: function(){\n console.warn('watch().changed() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n arrived: function(){\n console.warn('watch().arrived() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n happened: function(){\n console.warn('watch().happened() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n uninstall: function(){\n console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');\n return stopWatching.apply(this, arguments);\n },\n messages: function(){\n console.warn('watch().messages() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n },\n logs: function(){\n console.warn('watch().logs() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n }\n };\n};\n\nmodule.exports = filter;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\n\n/// Should be called to check if filter implementation is valid\n/// @returns true if it is, otherwise false\nvar implementationIsValid = function (i) {\n return !!i && \n typeof i.newFilter === 'function' && \n typeof i.getLogs === 'function' && \n typeof i.uninstallFilter === 'function' &&\n typeof i.startPolling === 'function' &&\n typeof i.stopPolling === 'function';\n};\n\n/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones\n/// @param should be string or object\n/// @returns options string or object\nvar getOptions = function (options) {\n /*jshint maxcomplexity:9 */\n\n if (typeof options === 'string') {\n return options;\n } \n\n options = options || {};\n\n if (options.topic) {\n console.warn('\"topic\" is deprecated, is \"topics\" instead');\n options.topics = options.topic;\n }\n\n if (options.earliest) {\n console.warn('\"earliest\" is deprecated, is \"fromBlock\" instead');\n options.fromBlock = options.earliest;\n }\n\n if (options.latest) {\n console.warn('\"latest\" is deprecated, is \"toBlock\" instead');\n options.toBlock = options.latest;\n }\n\n if (options.skip) {\n console.warn('\"skip\" is deprecated, is \"offset\" instead');\n options.offset = options.skip;\n }\n\n if (options.max) {\n console.warn('\"max\" is deprecated, is \"limit\" instead');\n options.limit = options.max;\n }\n\n // make sure topics, get converted to hex\n if(options.topics instanceof Array) {\n options.topics = options.topics.map(function(topic){\n return utils.toHex(topic);\n });\n }\n\n\n // evaluate lazy properties\n return {\n fromBlock: utils.toHex(options.fromBlock),\n toBlock: utils.toHex(options.toBlock),\n limit: utils.toHex(options.limit),\n offset: utils.toHex(options.offset),\n to: options.to,\n address: options.address,\n topics: options.topics\n };\n};\n\n/// Should be used when we want to watch something\n/// it's using inner polling mechanism and is notified about changes\n/// @param options are filter options\n/// @param implementation, an abstract polling implementation\n/// @param formatter (optional), callback function which formats output before 'real' callback \nvar filter = function(options, implementation, formatter) {\n if (!implementationIsValid(implementation)) {\n console.error('filter implemenation is invalid');\n return;\n }\n\n options = getOptions(options);\n var callbacks = [];\n var filterId = implementation.newFilter(options);\n\n // call the callbacks\n var onMessages = function (messages) {\n messages.forEach(function (message) {\n message = formatter ? formatter(message) : message;\n callbacks.forEach(function (callback) {\n callback(message);\n });\n });\n };\n\n implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);\n\n var watch = function(callback) {\n callbacks.push(callback);\n };\n\n var stopWatching = function() {\n implementation.stopPolling(filterId);\n implementation.uninstallFilter(filterId);\n callbacks = [];\n };\n\n var get = function () {\n var results = implementation.getLogs(filterId);\n\n return utils.isArray(results) ? results.map(function(message){\n return formatter ? formatter(message) : message;\n }) : results;\n };\n \n return {\n watch: watch,\n stopWatching: stopWatching,\n get: get,\n\n // DEPRECATED methods\n changed: function(){\n console.warn('watch().changed() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n arrived: function(){\n console.warn('watch().arrived() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n happened: function(){\n console.warn('watch().happened() is deprecated please use filter().watch() instead.');\n return watch.apply(this, arguments);\n },\n uninstall: function(){\n console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');\n return stopWatching.apply(this, arguments);\n },\n messages: function(){\n console.warn('watch().messages() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n },\n logs: function(){\n console.warn('watch().logs() is deprecated please use filter().get() instead.');\n return get.apply(this, arguments);\n }\n };\n};\n\nmodule.exports = filter;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file formatters.js\n * @authors:\n * Marek Kotewicz \n * Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * Should the input to a big number\n *\n * @method convertToBigNumber\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar convertToBigNumber = function (value) {\n return utils.toBigNumber(value);\n};\n\n/**\n * Formats the input of a transaction and converts all values to HEX\n *\n * @method inputTransactionFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputTransactionFormatter = function (options){\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value'].forEach(function(key){\n options[key] = utils.fromDecimal(options[key]);\n });\n\n return options;\n};\n\n/**\n * Formats the output of a transaction to its proper values\n * \n * @method outputTransactionFormatter\n * @param {Object} transaction\n * @returns {Object} transaction\n*/\nvar outputTransactionFormatter = function (tx){\n tx.gas = utils.toDecimal(tx.gas);\n tx.gasPrice = utils.toBigNumber(tx.gasPrice);\n tx.value = utils.toBigNumber(tx.value);\n return tx;\n};\n\n/**\n * Formats the input of a call and converts all values to HEX\n *\n * @method inputCallFormatter\n * @param {Object} transaction options\n * @returns object\n*/\nvar inputCallFormatter = function (options){\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n return options;\n};\n\n\n/**\n * Formats the output of a block to its proper values\n *\n * @method outputBlockFormatter\n * @param {Object} block object \n * @returns {Object} block object\n*/\nvar outputBlockFormatter = function(block){\n\n // transform to number\n block.gasLimit = utils.toDecimal(block.gasLimit);\n block.gasUsed = utils.toDecimal(block.gasUsed);\n block.size = utils.toDecimal(block.size);\n block.timestamp = utils.toDecimal(block.timestamp);\n block.number = utils.toDecimal(block.number);\n\n block.minGasPrice = utils.toBigNumber(block.minGasPrice);\n block.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if(block.transactions instanceof Array) {\n block.transactions.forEach(function(item){\n if(!utils.isString(item))\n return outputTransactionFormatter(item);\n });\n }\n\n return block;\n};\n\n/**\n * Formats the output of a log\n * \n * @method outputLogFormatter\n * @param {Object} log object\n * @returns {Object} log\n*/\nvar outputLogFormatter = function(log){\n log.blockNumber = utils.toDecimal(log.blockNumber);\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n log.logIndex = utils.toDecimal(log.logIndex);\n\n return log;\n};\n\n\n/**\n * Formats the input of a whisper post and converts all values to HEX\n *\n * @method inputPostFormatter\n * @param {Object} transaction object\n * @returns {Object}\n*/\nvar inputPostFormatter = function(post){\n\n post.payload = utils.toHex(post.payload);\n post.ttl = utils.fromDecimal(post.ttl);\n post.priority = utils.fromDecimal(post.priority);\n\n if(!(post.topics instanceof Array))\n post.topics = [post.topics];\n\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.fromAscii(topic);\n });\n\n return post;\n};\n\n/**\n * Formats the output of a received post message\n *\n * @method outputPostFormatter\n * @param {Object}\n * @returns {Object}\n */\nvar outputPostFormatter = function(post){\n\n post.expiry = utils.toDecimal(post.expiry);\n post.sent = utils.toDecimal(post.sent);\n post.ttl = utils.toDecimal(post.ttl);\n post.workProved = utils.toDecimal(post.workProved);\n post.payloadRaw = post.payload;\n post.payload = utils.toAscii(post.payload);\n\n if(post.payload.indexOf('{') === 0 || post.payload.indexOf('[') === 0) {\n try {\n post.payload = JSON.parse(post.payload);\n } catch (e) { }\n }\n\n // format the following options\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n convertToBigNumber: convertToBigNumber,\n inputTransactionFormatter: inputTransactionFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n inputCallFormatter: inputCallFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\n inputPostFormatter: inputPostFormatter,\n outputPostFormatter: outputPostFormatter\n};\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\nif (\"build\" !== 'build') {/*\n var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\n*/}\n\nvar HttpProvider = function (host) {\n this.name = 'HTTP';\n this.handlers = [];\n this.host = host || 'http://localhost:8080';\n};\n\nHttpProvider.prototype.send = function (payload, callback) {\n var request = new XMLHttpRequest();\n request.open('POST', this.host, false);\n\n // ASYNC\n if(typeof callback === 'function') {\n request.onreadystatechange = function() {\n if(request.readyState === 4) {\n var result = '';\n try {\n result = JSON.parse(request.responseText);\n } catch(error) {\n result = error;\n }\n callback(result, request.status);\n }\n };\n\n request.open('POST', this.host, true);\n request.send(JSON.stringify(payload));\n\n // SYNC\n } else {\n request.open('POST', this.host, false);\n request.send(JSON.stringify(payload));\n\n // check request.status\n if(request.status !== 200)\n return;\n return JSON.parse(request.responseText);\n \n }\n};\n\nmodule.exports = HttpProvider;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file httpprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * @date 2014\n */\n\nif (\"build\" !== 'build') {/*\n var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\n*/}\n\nvar HttpProvider = function (host) {\n this.name = 'HTTP';\n this.handlers = [];\n this.host = host || 'http://localhost:8080';\n};\n\nHttpProvider.prototype.send = function (payload, callback) {\n var request = new XMLHttpRequest();\n\n // ASYNC\n if(typeof callback === 'function') {\n request.onreadystatechange = function() {\n if(request.readyState === 4) {\n var result = '';\n try {\n result = JSON.parse(request.responseText);\n } catch(error) {\n result = error;\n }\n callback(result, request.status);\n }\n };\n\n request.open('POST', this.host, true);\n request.send(JSON.stringify(payload));\n\n // SYNC\n } else {\n request.open('POST', this.host, false);\n request.send(JSON.stringify(payload));\n\n // check request.status\n if(request.status !== 200)\n return;\n return JSON.parse(request.responseText);\n \n }\n};\n\nmodule.exports = HttpProvider;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file jsonrpc.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar messageId = 1;\n\n/// Should be called to valid json create payload object\n/// @param method of jsonrpc call, required\n/// @param params, an array of method params, optional\n/// @returns valid jsonrpc payload object\nvar toPayload = function (method, params) {\n if (!method)\n console.error('jsonrpc method should be specified!');\n\n return {\n jsonrpc: '2.0',\n method: method,\n params: params || [],\n id: messageId++\n }; \n};\n\n/// Should be called to check if jsonrpc response is valid\n/// @returns true if response is valid, otherwise false \nvar isValidResponse = function (response) {\n return !!response &&\n !response.error &&\n response.jsonrpc === '2.0' &&\n typeof response.id === 'number' &&\n response.result !== undefined; // only undefined is not valid json object\n};\n\n/// Should be called to create batch payload object\n/// @param messages, an array of objects with method (required) and params (optional) fields\nvar toBatchPayload = function (messages) {\n return messages.map(function (message) {\n return toPayload(message.method, message.params);\n }); \n};\n\nmodule.exports = {\n toPayload: toPayload,\n isValidResponse: isValidResponse,\n toBatchPayload: toBatchPayload\n};\n\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file eth.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n // { name: 'getBalance', call: 'eth_balanceAt', outputFormatter: formatters.convertToBigNumber},\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n { name: 'listening', getter: 'net_listening'},\n { name: 'peerCount', getter: 'net_peerCount', outputFormatter: utils.toDecimal },\n];\n\n\nmodule.exports = {\n methods: methods,\n properties: properties\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file qtsync.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\nvar QtSyncProvider = function () {\n};\n\nQtSyncProvider.prototype.send = function (payload) {\n var result = navigator.qt.callMethod(JSON.stringify(payload));\n return JSON.parse(result);\n};\n\nmodule.exports = QtSyncProvider;\n\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file requestmanager.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Gav Wood \n * @date 2014\n */\n\nvar jsonrpc = require('./jsonrpc');\nvar c = require('../utils/config');\n\n/**\n * It's responsible for passing messages to providers\n * It's also responsible for polling the ethereum node for incoming messages\n * Default poll timeout is 1 second\n */\nvar requestManager = function() {\n var polls = [];\n var timeout = null;\n var provider;\n\n var send = function (data, callback) {\n /*jshint maxcomplexity: 8 */\n\n // FORMAT BASED ON ONE FORMATTER function\n if(typeof data.inputFormatter === 'function') {\n data.params = Array.prototype.map.call(data.params, function(item, index){\n // format everything besides the defaultblock, which is already formated\n return (!data.addDefaultblock || index+1 < data.addDefaultblock) ? data.inputFormatter(item) : item;\n });\n\n // FORMAT BASED ON the input FORMATTER ARRAY\n } else if(data.inputFormatter instanceof Array) {\n data.params = Array.prototype.map.call(data.inputFormatter, function(formatter, index){\n // format everything besides the defaultblock, which is already formated\n return (!data.addDefaultblock || index+1 < data.addDefaultblock) ? formatter(data.params[index]) : data.params[index];\n });\n }\n\n\n var payload = jsonrpc.toPayload(data.method, data.params);\n \n if (!provider) {\n console.error('provider is not set');\n return null;\n }\n\n // HTTP ASYNC (only when callback is given, and it a HttpProvidor)\n if(typeof callback === 'function' && provider.name === 'HTTP'){\n provider.send(payload, function(result, status){\n\n if (!jsonrpc.isValidResponse(result)) {\n if(typeof result === 'object' && result.error && result.error.message) {\n console.error(result.error.message);\n callback(result.error);\n } else {\n callback(new Error({\n status: status,\n error: result,\n message: 'Bad Request'\n }));\n }\n return null;\n }\n\n // format the output\n callback(null, (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result);\n });\n\n // SYNC\n } else {\n var result = provider.send(payload);\n\n if (!jsonrpc.isValidResponse(result)) {\n console.log(result);\n if(typeof result === 'object' && result.error && result.error.message)\n console.error(result.error.message);\n return null;\n }\n\n // format the output\n return (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result;\n }\n \n };\n\n var setProvider = function (p) {\n provider = p;\n };\n\n /*jshint maxparams:4 */\n var startPolling = function (data, pollId, callback, uninstall) {\n polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});\n };\n /*jshint maxparams:3 */\n\n var stopPolling = function (pollId) {\n for (var i = polls.length; i--;) {\n var poll = polls[i];\n if (poll.id === pollId) {\n polls.splice(i, 1);\n }\n }\n };\n\n var reset = function () {\n polls.forEach(function (poll) {\n poll.uninstall(poll.id); \n });\n polls = [];\n\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n poll();\n };\n\n var poll = function () {\n polls.forEach(function (data) {\n // send async\n send(data.data, function(error, result){\n if (!(result instanceof Array) || result.length === 0) {\n return;\n }\n data.callback(result);\n });\n });\n timeout = setTimeout(poll, c.ETH_POLLING_TIMEOUT);\n };\n \n poll();\n\n return {\n send: send,\n setProvider: setProvider,\n startPolling: startPolling,\n stopPolling: stopPolling,\n reset: reset\n };\n};\n\nmodule.exports = requestManager;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file requestmanager.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Fabian Vogelsteller \n * Gav Wood \n * @date 2014\n */\n\nvar jsonrpc = require('./jsonrpc');\nvar c = require('../utils/config');\n\n/**\n * It's responsible for passing messages to providers\n * It's also responsible for polling the ethereum node for incoming messages\n * Default poll timeout is 1 second\n */\nvar requestManager = function() {\n var polls = [];\n var timeout = null;\n var provider;\n\n var send = function (data, callback) {\n /*jshint maxcomplexity: 8 */\n\n // FORMAT BASED ON ONE FORMATTER function\n if(typeof data.inputFormatter === 'function') {\n data.params = Array.prototype.map.call(data.params, function(item, index){\n // format everything besides the defaultblock, which is already formated\n return (!data.addDefaultblock || index+1 < data.addDefaultblock) ? data.inputFormatter(item) : item;\n });\n\n // FORMAT BASED ON the input FORMATTER ARRAY\n } else if(data.inputFormatter instanceof Array) {\n data.params = Array.prototype.map.call(data.inputFormatter, function(formatter, index){\n // format everything besides the defaultblock, which is already formated\n return (!data.addDefaultblock || index+1 < data.addDefaultblock) ? formatter(data.params[index]) : data.params[index];\n });\n }\n\n\n var payload = jsonrpc.toPayload(data.method, data.params);\n \n if (!provider) {\n console.error('provider is not set');\n return null;\n }\n\n // HTTP ASYNC (only when callback is given, and it a HttpProvidor)\n if(typeof callback === 'function' && provider.name === 'HTTP'){\n provider.send(payload, function(result, status){\n\n if (!jsonrpc.isValidResponse(result)) {\n if(typeof result === 'object' && result.error && result.error.message) {\n console.error(result.error.message);\n callback(result.error);\n } else {\n callback(new Error({\n status: status,\n error: result,\n message: 'Bad Request'\n }));\n }\n return null;\n }\n\n // format the output\n callback(null, (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result);\n });\n\n // SYNC\n } else {\n var result = provider.send(payload);\n\n if (!jsonrpc.isValidResponse(result)) {\n if(typeof result === 'object' && result.error && result.error.message)\n console.error(result.error.message);\n return null;\n }\n\n // format the output\n return (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result;\n }\n \n };\n\n var setProvider = function (p) {\n provider = p;\n };\n\n /*jshint maxparams:4 */\n var startPolling = function (data, pollId, callback, uninstall) {\n polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});\n };\n /*jshint maxparams:3 */\n\n var stopPolling = function (pollId) {\n for (var i = polls.length; i--;) {\n var poll = polls[i];\n if (poll.id === pollId) {\n polls.splice(i, 1);\n }\n }\n };\n\n var reset = function () {\n polls.forEach(function (poll) {\n poll.uninstall(poll.id); \n });\n polls = [];\n\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n poll();\n };\n\n var poll = function () {\n polls.forEach(function (data) {\n // send async\n send(data.data, function(error, result){\n if (!(result instanceof Array) || result.length === 0) {\n return;\n }\n data.callback(result);\n });\n });\n timeout = setTimeout(poll, c.ETH_POLLING_TIMEOUT);\n };\n \n poll();\n\n return {\n send: send,\n setProvider: setProvider,\n startPolling: startPolling,\n stopPolling: stopPolling,\n reset: reset\n };\n};\n\nmodule.exports = requestManager;\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file shh.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar formatters = require('./formatters');\n\n/// @returns an array of objects describing web3.shh api methods\nvar methods = function () {\n return [\n { name: 'post', call: 'shh_post', inputFormatter: formatters.inputPostFormatter },\n { name: 'newIdentity', call: 'shh_newIdentity' },\n { name: 'hasIdentity', call: 'shh_hasIdentity' },\n { name: 'newGroup', call: 'shh_newGroup' },\n { name: 'addToGroup', call: 'shh_addToGroup' },\n\n // deprecated\n { name: 'haveIdentity', call: 'shh_haveIdentity', newMethod: 'shh.hasIdentity' },\n ];\n};\n\nmodule.exports = {\n methods: methods\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file signature.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar web3 = require('../web3'); \nvar c = require('../utils/config');\n\n/// @param function name for which we want to get signature\n/// @returns signature of function with given name\nvar functionSignatureFromAscii = function (name) {\n return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_SIGNATURE_LENGTH * 2);\n};\n\n/// @param event name for which we want to get signature\n/// @returns signature of event with given name\nvar eventSignatureFromAscii = function (name) {\n return web3.sha3(web3.fromAscii(name));\n};\n\nmodule.exports = {\n functionSignatureFromAscii: functionSignatureFromAscii,\n eventSignatureFromAscii: eventSignatureFromAscii\n};\n\n", "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file watches.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\n/// @returns an array of objects describing web3.eth.filter api methods\nvar eth = function () {\n var newFilter = function (args) {\n return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter';\n };\n\n return [\n { name: 'newFilter', call: newFilter },\n { name: 'uninstallFilter', call: 'eth_uninstallFilter' },\n { name: 'getLogs', call: 'eth_getFilterLogs' }\n ];\n};\n\n/// @returns an array of objects describing web3.shh.watch api methods\nvar shh = function () {\n return [\n { name: 'newFilter', call: 'shh_newFilter' },\n { name: 'uninstallFilter', call: 'shh_uninstallFilter' },\n { name: 'getLogs', call: 'shh_getMessages' }\n ];\n};\n\nmodule.exports = {\n eth: eth,\n shh: shh\n};\n\n", + "module.exports={\n \"version\": \"0.1.3\"\n}", "var web3 = require('./lib/web3');\nweb3.providers.HttpProvider = require('./lib/web3/httpprovider');\nweb3.providers.QtSyncProvider = require('./lib/web3/qtsync');\nweb3.eth.contract = require('./lib/web3/contract');\nweb3.abi = require('./lib/solidity/abi');\n\nmodule.exports = web3;\n" ] } \ No newline at end of file diff --git a/dist/ethereum.min.js b/dist/ethereum.min.js index fc5a3691a..e0cb5a491 100644 --- a/dist/ethereum.min.js +++ b/dist/ethereum.min.js @@ -1 +1 @@ -require=function t(e,n,r){function o(i,u){if(!n[i]){if(!e[i]){var s="function"==typeof require&&require;if(!u&&s)return s(i,!0);if(a)return a(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[i]={exports:{}};e[i][0].call(l.exports,function(t){var n=e[i][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[i].exports}for(var a="function"==typeof require&&require,i=0;iy;y++)g.push(d(e.slice(0,s))),e=e.slice(s);n.push(g)}else o.prefixedType("string")(t[c].type)?(l=l.slice(s),n.push(d(e.slice(0,s))),e=e.slice(s)):(n.push(d(e.slice(0,s))),e=e.slice(s))}),n},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),a=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=a),e[r][o]=a}),e},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),a=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=a),e[r][o]=a}),e};e.exports={inputParser:d,outputParser:h,formatInput:l,formatOutput:m}},{"../utils/config":4,"../utils/utils":5,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("../utils/utils"),r=t("../utils/config"),o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t){var e=2*r.ETH_PADDING;return BigNumber.config(r.ETH_BIGNUMBER_ROUNDING_MODE),o(n.toTwosComplement(t).round().toString(16),e)},i=function(t){return n.fromAscii(t,r.ETH_PADDING).substr(2)},u=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},s=function(t){return a(new BigNumber(t).times(new BigNumber(2).pow(128)))},c=function(t){return"1"===new BigNumber(t.substr(0,1),16).toString(2).substr(0,1)},l=function(t){return t=t||"0",c(t)?new BigNumber(t,16).minus(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new BigNumber(t,16)},f=function(t){return t=t||"0",new BigNumber(t,16)},p=function(t){return l(t).dividedBy(new BigNumber(2).pow(128))},m=function(t){return f(t).dividedBy(new BigNumber(2).pow(128))},d=function(t){return"0x"+t},h=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},g=function(t){return n.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:a,formatInputString:i,formatInputBool:u,formatInputReal:s,formatOutputInt:l,formatOutputUInt:f,formatOutputReal:p,formatOutputUReal:m,formatOutputHash:d,formatOutputBool:h,formatOutputString:g,formatOutputAddress:y}},{"../utils/config":4,"../utils/utils":5}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},a=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("hash"),format:n.formatInputInt},{type:r("string"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},i=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("hash"),format:n.formatOutputHash},{type:r("string"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:a,outputTypes:i}},{"./formatters":2}],4:[function(t,e){var n=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:n,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:BigNumber.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{}],5:[function(t,e){var n={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},r=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},a=function(t){for(var e="",n=0;n1?(t[n[0]]||(t[n[0]]={}),t[n[0]][n[1]]=r):t[n[0]]=r})},d=function(t,e){e.forEach(function(e){var n={};n.get=function(){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),v.manager.send({method:e.getter,outputFormatter:e.outputFormatter})},e.setter&&(n.set=function(t){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),v.manager.send({method:e.setter,params:[t],inputFormatter:e.inputFormatter})}),n.enumerable=!e.newProperty,Object.defineProperty(t,e.name,n)})},h=function(t,e,n,r){v.manager.startPolling({method:t,params:[e]},e,n,r)},g=function(t){v.manager.stopPolling(t)},y={startPolling:h.bind(null,"eth_getFilterChanges"),stopPolling:g},b={startPolling:h.bind(null,"shh_getFilterChanges"),stopPolling:g},v={manager:l(),providers:{},setProvider:function(t){v.manager.setProvider(t)},reset:function(){v.manager.reset()},toHex:s.toHex,toAscii:s.toAscii,fromAscii:s.fromAscii,toDecimal:s.toDecimal,fromDecimal:s.fromDecimal,toBigNumber:s.toBigNumber,toWei:s.toWei,fromWei:s.fromWei,isAddress:s.isAddress,net:{},eth:{contractFromAbi:function(t){return console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),function(e){e=e||"0xc6d9d2cd449a754c494264e1809c50e34d64562b";var n=v.eth.contract(e,t);return n.address=e,n}},filter:function(t,e,n){return t._isEvent?t(e,n):u(t,y,c.outputLogFormatter)},watch:function(t,e,n){return console.warn("eth.watch() is deprecated please use eth.filter() instead."),this.filter(t,e,n)}},db:{},shh:{filter:function(t){return u(t,b,c.outputPostFormatter)},watch:function(t){return console.warn("shh.watch() is deprecated please use shh.filter() instead."),this.filter(t)}}};Object.defineProperty(v.eth,"defaultBlock",{get:function(){return f.ETH_DEFAULTBLOCK},set:function(t){return f.ETH_DEFAULTBLOCK=t,f.ETH_DEFAULTBLOCK}}),m(v,p()),m(v.net,n.methods),d(v.net,n.properties),m(v.eth,r.methods),d(v.eth,r.properties),m(v.db,o.methods()),m(v.shh,a.methods()),m(y,i.eth()),m(b,i.shh()),e.exports=v},{"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(t,e){function n(t,e){t.forEach(function(t){if(-1===t.name.indexOf("(")){var e=t.name,n=t.inputs.map(function(t){return t.type}).join();t.name=e+"("+n+")"}});var n={};return c(n),l(n,t,e),f(n,t,e),p(n,t,e),n}var r=t("../web3"),o=t("../solidity/abi"),a=t("../utils/utils"),i=t("./event"),u=t("./signature"),s=function(t){r._currentContractAbi=t.abi,r._currentContractAddress=t.address,r._currentContractMethodName=t.method,r._currentContractMethodParams=t.params},c=function(t){t.call=function(e){return t._isTransaction=!1,t._options=e,t},t.sendTransaction=function(e){return t._isTransaction=!0,t._options=e,t},t.transact=function(e){return console.warn("myContract.transact() is deprecated please use myContract.sendTransaction() instead."),t.sendTransaction(e)},t._options={},["gas","gasPrice","value","from"].forEach(function(e){t[e]=function(n){return t._options[e]=n,t}})},l=function(t,e,n){var i=o.inputParser(e),c=o.outputParser(e);a.filterFunctions(e).forEach(function(o){var l=a.extractDisplayName(o.name),f=a.extractTypeName(o.name),p=function(){var a=Array.prototype.slice.call(arguments),p=u.functionSignatureFromAscii(o.name),m=i[l][f].apply(null,a),d=t._options||{};d.to=n,d.data=p+m;var h=t._isTransaction===!0||t._isTransaction!==!1&&!o.constant,g=d.collapse!==!1;if(t._options={},t._isTransaction=null,h)return s({abi:e,address:n,method:o.name,params:a}),void r.eth.sendTransaction(d);var y=r.eth.call(d),b=c[l][f](y);return g&&(1===b.length?b=b[0]:0===b.length&&(b=null)),b};void 0===t[l]&&(t[l]=p),t[l][f]=p})},f=function(t,e,n){t.address=n,t._onWatchEventResult=function(t){var n=event.getMatchingEvent(a.filterEvents(e)),r=i.outputParser(n);return r(t)},Object.defineProperty(t,"topics",{get:function(){return a.filterEvents(e).map(function(t){return u.eventSignatureFromAscii(t.name)})}})},p=function(t,e,n){a.filterEvents(e).forEach(function(e){var o=function(){var t=Array.prototype.slice.call(arguments),o=u.eventSignatureFromAscii(e.name),a=i.inputParser(n,o,e),s=a.apply(null,t),c=function(t){var n=i.outputParser(e);return n(t)};return r.eth.filter(s,void 0,void 0,c)};o._isEvent=!0;var s=a.extractDisplayName(e.name),c=a.extractTypeName(e.name);void 0===t[s]&&(t[s]=o),t[s][c]=o})},m=function(t){return t instanceof Array&&1===arguments.length?n.bind(null,t):(console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),new n(arguments[1],arguments[0]))};e.exports=m},{"../solidity/abi":1,"../utils/utils":5,"../web3":6,"./event":10,"./signature":19}],8:[function(t,e){var n=function(){return[{name:"put",call:"db_put"},{name:"get",call:"db_get"},{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"}]};e.exports={methods:n}},{}],9:[function(t,e){var n=t("./formatters"),r=t("../utils/utils"),o=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockByHash":"eth_getBlockByNumber"},a=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getTransactionByBlockHashAndIndex":"eth_getTransactionByBlockNumberAndIndex"},i=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleByBlockHashAndIndex":"eth_getUncleByBlockNumberAndIndex"},u=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockTransactionCountByHash":"eth_getBlockTransactionCountByNumber"},s=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleCountByBlockHash":"eth_getUncleCountByBlockNumber"},c=[{name:"getBalance",call:"eth_getBalance",addDefaultblock:2,outputFormatter:n.convertToBigNumber},{name:"getStorage",call:"eth_getStorage",addDefaultblock:2},{name:"getStorageAt",call:"eth_getStorageAt",addDefaultblock:3,inputFormatter:r.toHex},{name:"getData",call:"eth_getData",addDefaultblock:2},{name:"getBlock",call:o,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,function(t){return t?!0:!1}]},{name:"getUncle",call:i,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,r.toHex,function(t){return t?!0:!1}]},{name:"getCompilers",call:"eth_getCompilers"},{name:"getBlockTransactionCount",call:u,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getBlockUncleCount",call:s,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getTransaction",call:"eth_getTransactionByHash",outputFormatter:n.outputTransactionFormatter},{name:"getTransactionFromBlock",call:a,outputFormatter:n.outputTransactionFormatter,inputFormatter:r.toHex},{name:"getTransactionCount",call:"eth_getTransactionCount",addDefaultblock:2,outputFormatter:r.toDecimal},{name:"sendTransaction",call:"eth_sendTransaction",inputFormatter:n.inputTransactionFormatter},{name:"call",call:"eth_call",addDefaultblock:2,inputFormatter:n.inputCallFormatter},{name:"compile.solidity",call:"eth_compileSolidity",inputFormatter:r.toHex},{name:"compile.lll",call:"eth_compileLLL",inputFormatter:r.toHex},{name:"compile.serpent",call:"eth_compileSerpent",inputFormatter:r.toHex},{name:"flush",call:"eth_flush"},{name:"balanceAt",call:"eth_balanceAt",newMethod:"eth.getBalance"},{name:"stateAt",call:"eth_stateAt",newMethod:"eth.getStorageAt"},{name:"storageAt",call:"eth_storageAt",newMethod:"eth.getStorage"},{name:"countAt",call:"eth_countAt",newMethod:"eth.getTransactionCount"},{name:"codeAt",call:"eth_codeAt",newMethod:"eth.getData"},{name:"transact",call:"eth_transact",newMethod:"eth.sendTransaction"},{name:"block",call:o,newMethod:"eth.getBlock"},{name:"transaction",call:a,newMethod:"eth.getTransaction"},{name:"uncle",call:i,newMethod:"eth.getUncle"},{name:"compilers",call:"eth_compilers",newMethod:"eth.getCompilers"},{name:"solidity",call:"eth_solidity",newMethod:"eth.compile.solidity"},{name:"lll",call:"eth_lll",newMethod:"eth.compile.lll"},{name:"serpent",call:"eth_serpent",newMethod:"eth.compile.serpent"},{name:"transactionCount",call:u,newMethod:"eth.getBlockTransactionCount"},{name:"uncleCount",call:s,newMethod:"eth.getBlockUncleCount"},{name:"logs",call:"eth_logs"}],l=[{name:"coinbase",getter:"eth_coinbase"},{name:"mining",getter:"eth_mining"},{name:"gasPrice",getter:"eth_gasPrice",outputFormatter:n.convertToBigNumber},{name:"accounts",getter:"eth_accounts"},{name:"blockNumber",getter:"eth_blockNumber",outputFormatter:r.toDecimal},{name:"listening",getter:"net_listening",setter:"eth_setListening",newProperty:"net.listening"},{name:"peerCount",getter:"net_peerCount",newProperty:"net.peerCount"},{name:"number",getter:"eth_number",newProperty:"eth.blockNumber"}];e.exports={methods:c,properties:l}},{"../utils/utils":5,"./formatters":12}],10:[function(t,e){var n=t("../solidity/abi"),r=t("../utils/utils"),o=t("./signature"),a=function(t,e){return t.filter(function(t){return t.indexed===e})},i=function(t,e){var n=r.findIndex(t,function(t){return t.name===e});return-1===n?void console.error("indexed param with name "+e+" not found"):t[n]},u=function(t,e){return Object.keys(e).map(function(r){var o=[i(a(t.inputs,!0),r)],u=e[r];return u instanceof Array?u.map(function(t){return n.formatInput(o,[t])}):n.formatInput(o,[u])})},s=function(t,e,n){return function(r,o){var a=o||{};return a.address=t,a.topics=[],a.topics.push(e),r&&(a.topics=a.topics.concat(u(n,r))),a}},c=function(t,e,n){var r=e.slice(),o=n.slice();return t.reduce(function(t,e){var n;return n=e.indexed?r.splice(0,1)[0]:o.splice(0,1)[0],t[e.name]=n,t},{})},l=function(t){return function(e){var o={event:r.extractDisplayName(t.name),number:e.number,hash:e.hash,args:{}};if(e.topics=e.topic,!e.topics)return o;var i=a(t.inputs,!0),u="0x"+e.topics.slice(1,e.topics.length).map(function(t){return t.slice(2)}).join(""),s=n.formatOutput(i,u),l=a(t.inputs,!1),f=n.formatOutput(l,e.data);return o.args=c(t.inputs,s,f),o}},f=function(t,e){for(var n=0;ny;y++)g.push(d(e.slice(0,s))),e=e.slice(s);n.push(g)}else o.prefixedType("bytes")(t[c].type)?(l=l.slice(s),n.push(d(e.slice(0,s))),e=e.slice(s)):(n.push(d(e.slice(0,s))),e=e.slice(s))}),n},d=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(){var e=Array.prototype.slice.call(arguments);return l(t.inputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e},h=function(t){var e={};return t.forEach(function(t){var r=n.extractDisplayName(t.name),o=n.extractTypeName(t.name),i=function(e){return m(t.outputs,e)};void 0===e[r]&&(e[r]=i),e[r][o]=i}),e};e.exports={inputParser:d,outputParser:h,formatInput:l,formatOutput:m}},{"../utils/config":4,"../utils/utils":5,"./formatters":2,"./types":3}],2:[function(t,e){var n=t("../utils/utils"),r=t("../utils/config"),o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},i=function(t){var e=2*r.ETH_PADDING;return BigNumber.config(r.ETH_BIGNUMBER_ROUNDING_MODE),o(n.toTwosComplement(t).round().toString(16),e)},a=function(t){return n.fromAscii(t,r.ETH_PADDING).substr(2)},u=function(t){return"000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0")},s=function(t){return i(new BigNumber(t).times(new BigNumber(2).pow(128)))},c=function(t){return"1"===new BigNumber(t.substr(0,1),16).toString(2).substr(0,1)},l=function(t){return t=t||"0",c(t)?new BigNumber(t,16).minus(new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new BigNumber(t,16)},f=function(t){return t=t||"0",new BigNumber(t,16)},p=function(t){return l(t).dividedBy(new BigNumber(2).pow(128))},m=function(t){return f(t).dividedBy(new BigNumber(2).pow(128))},d=function(t){return"0x"+t},h=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t?!0:!1},g=function(t){return n.toAscii(t)},y=function(t){return"0x"+t.slice(t.length-40,t.length)};e.exports={formatInputInt:i,formatInputString:a,formatInputBool:u,formatInputReal:s,formatOutputInt:l,formatOutputUInt:f,formatOutputReal:p,formatOutputUReal:m,formatOutputHash:d,formatOutputBool:h,formatOutputString:g,formatOutputAddress:y}},{"../utils/config":4,"../utils/utils":5}],3:[function(t,e){var n=t("./formatters"),r=function(t){return function(e){return 0===e.indexOf(t)}},o=function(t){return function(e){return t===e}},i=function(){return[{type:r("uint"),format:n.formatInputInt},{type:r("int"),format:n.formatInputInt},{type:r("bytes"),format:n.formatInputString},{type:r("real"),format:n.formatInputReal},{type:r("ureal"),format:n.formatInputReal},{type:o("address"),format:n.formatInputInt},{type:o("bool"),format:n.formatInputBool}]},a=function(){return[{type:r("uint"),format:n.formatOutputUInt},{type:r("int"),format:n.formatOutputInt},{type:r("bytes"),format:n.formatOutputString},{type:r("real"),format:n.formatOutputReal},{type:r("ureal"),format:n.formatOutputUReal},{type:o("address"),format:n.formatOutputAddress},{type:o("bool"),format:n.formatOutputBool}]};e.exports={prefixedType:r,namedType:o,inputTypes:i,outputTypes:a}},{"./formatters":2}],4:[function(t,e){var n=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:n,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:BigNumber.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,ETH_DEFAULTBLOCK:"latest"}},{}],5:[function(t,e){var n={wei:"1",kwei:"1000",ada:"1000",mwei:"1000000",babbage:"1000000",gwei:"1000000000",shannon:"1000000000",szabo:"1000000000000",finney:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},r=function(t,e){for(var n=!1,r=0;rn;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},i=function(t){for(var e="",n=0;n1?(t[n[0]]||(t[n[0]]={}),t[n[0]][n[1]]=r):t[n[0]]=r})},g=function(t,e){e.forEach(function(e){var n=e.name.split("."),r={};r.get=function(){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),x.manager.send({method:e.getter,outputFormatter:e.outputFormatter})},e.setter&&(r.set=function(t){return e.newProperty&&console.warn("This property is deprecated please use web3."+e.newProperty+" instead."),x.manager.send({method:e.setter,params:[t],inputFormatter:e.inputFormatter})}),r.enumerable=!e.newProperty,n.length>1?(t[n[0]]||(t[n[0]]={}),Object.defineProperty(t[n[0]],n[1],r)):Object.defineProperty(t,e.name,r)})},y=function(t,e,n,r){x.manager.startPolling({method:t,params:[e]},e,n,r)},b=function(t){x.manager.stopPolling(t)},v={startPolling:y.bind(null,"eth_getFilterChanges"),stopPolling:b},w={startPolling:y.bind(null,"shh_getFilterChanges"),stopPolling:b},x={version:{api:n.version},manager:f(),providers:{},setProvider:function(t){x.manager.setProvider(t)},reset:function(){x.manager.reset()},toHex:c.toHex,toAscii:c.toAscii,fromAscii:c.fromAscii,toDecimal:c.toDecimal,fromDecimal:c.fromDecimal,toBigNumber:c.toBigNumber,toWei:c.toWei,fromWei:c.fromWei,isAddress:c.isAddress,net:{},eth:{contractFromAbi:function(t){return console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),function(e){e=e||"0xc6d9d2cd449a754c494264e1809c50e34d64562b";var n=x.eth.contract(e,t);return n.address=e,n}},filter:function(t,e,n){return t._isEvent?t(e,n):s(t,v,l.outputLogFormatter)},watch:function(t,e,n){return console.warn("eth.watch() is deprecated please use eth.filter() instead."),this.filter(t,e,n)}},db:{},shh:{filter:function(t){return s(t,w,l.outputPostFormatter)},watch:function(t){return console.warn("shh.watch() is deprecated please use shh.filter() instead."),this.filter(t)}}};Object.defineProperty(x.eth,"defaultBlock",{get:function(){return p.ETH_DEFAULTBLOCK},set:function(t){return p.ETH_DEFAULTBLOCK=t,p.ETH_DEFAULTBLOCK}}),h(x,m),g(x,d),h(x.net,r.methods),g(x.net,r.properties),h(x.eth,o.methods),g(x.eth,o.properties),h(x.db,i.methods()),h(x.shh,a.methods()),h(v,u.eth()),h(w,u.shh()),e.exports=x},{"../version.json":21,"./solidity/formatters":2,"./utils/config":4,"./utils/utils":5,"./web3/db":8,"./web3/eth":9,"./web3/filter":11,"./web3/net":15,"./web3/requestmanager":17,"./web3/shh":18,"./web3/watches":20}],7:[function(t,e){function n(t,e){t.forEach(function(t){if(-1===t.name.indexOf("(")){var e=t.name,n=t.inputs.map(function(t){return t.type}).join();t.name=e+"("+n+")"}});var n={};return c(n),l(n,t,e),f(n,t,e),p(n,t,e),n}var r=t("../web3"),o=t("../solidity/abi"),i=t("../utils/utils"),a=t("./event"),u=t("./signature"),s=function(t){r._currentContractAbi=t.abi,r._currentContractAddress=t.address,r._currentContractMethodName=t.method,r._currentContractMethodParams=t.params},c=function(t){t.call=function(e){return t._isTransaction=!1,t._options=e,t},t.sendTransaction=function(e){return t._isTransaction=!0,t._options=e,t},t.transact=function(e){return console.warn("myContract.transact() is deprecated please use myContract.sendTransaction() instead."),t.sendTransaction(e)},t._options={},["gas","gasPrice","value","from"].forEach(function(e){t[e]=function(n){return t._options[e]=n,t}})},l=function(t,e,n){var a=o.inputParser(e),c=o.outputParser(e);i.filterFunctions(e).forEach(function(o){var l=i.extractDisplayName(o.name),f=i.extractTypeName(o.name),p=function(){var i=Array.prototype.slice.call(arguments),p=u.functionSignatureFromAscii(o.name),m=a[l][f].apply(null,i),d=t._options||{};d.to=n,d.data=p+m;var h=t._isTransaction===!0||t._isTransaction!==!1&&!o.constant,g=d.collapse!==!1;if(t._options={},t._isTransaction=null,h)return s({abi:e,address:n,method:o.name,params:i}),void r.eth.sendTransaction(d);var y=r.eth.call(d),b=c[l][f](y);return g&&(1===b.length?b=b[0]:0===b.length&&(b=null)),b};void 0===t[l]&&(t[l]=p),t[l][f]=p})},f=function(t,e,n){t.address=n,t._onWatchEventResult=function(t){var n=event.getMatchingEvent(i.filterEvents(e)),r=a.outputParser(n);return r(t)},Object.defineProperty(t,"topics",{get:function(){return i.filterEvents(e).map(function(t){return u.eventSignatureFromAscii(t.name)})}})},p=function(t,e,n){i.filterEvents(e).forEach(function(e){var o=function(){var t=Array.prototype.slice.call(arguments),o=u.eventSignatureFromAscii(e.name),i=a.inputParser(n,o,e),s=i.apply(null,t),c=function(t){var n=a.outputParser(e);return n(t)};return r.eth.filter(s,void 0,void 0,c)};o._isEvent=!0;var s=i.extractDisplayName(e.name),c=i.extractTypeName(e.name);void 0===t[s]&&(t[s]=o),t[s][c]=o})},m=function(t){return t instanceof Array&&1===arguments.length?n.bind(null,t):(console.warn("Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead."),new n(arguments[1],arguments[0]))};e.exports=m},{"../solidity/abi":1,"../utils/utils":5,"../web3":6,"./event":10,"./signature":19}],8:[function(t,e){var n=function(){return[{name:"putString",call:"db_putString"},{name:"getString",call:"db_getString"},{name:"putHex",call:"db_putHex"},{name:"getHex",call:"db_getHex"}]};e.exports={methods:n}},{}],9:[function(t,e){var n=t("./formatters"),r=t("../utils/utils"),o=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockByHash":"eth_getBlockByNumber"},i=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getTransactionByBlockHashAndIndex":"eth_getTransactionByBlockNumberAndIndex"},a=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleByBlockHashAndIndex":"eth_getUncleByBlockNumberAndIndex"},u=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getBlockTransactionCountByHash":"eth_getBlockTransactionCountByNumber"},s=function(t){return r.isString(t[0])&&0===t[0].indexOf("0x")?"eth_getUncleCountByBlockHash":"eth_getUncleCountByBlockNumber"},c=[{name:"getBalance",call:"eth_getBalance",addDefaultblock:2,outputFormatter:n.convertToBigNumber},{name:"getStorage",call:"eth_getStorage",addDefaultblock:2},{name:"getStorageAt",call:"eth_getStorageAt",addDefaultblock:3,inputFormatter:r.toHex},{name:"getData",call:"eth_getData",addDefaultblock:2},{name:"getBlock",call:o,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,function(t){return t?!0:!1}]},{name:"getUncle",call:a,outputFormatter:n.outputBlockFormatter,inputFormatter:[r.toHex,r.toHex,function(t){return t?!0:!1}]},{name:"getCompilers",call:"eth_getCompilers"},{name:"getBlockTransactionCount",call:u,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getBlockUncleCount",call:s,outputFormatter:r.toDecimal,inputFormatter:r.toHex},{name:"getTransaction",call:"eth_getTransactionByHash",outputFormatter:n.outputTransactionFormatter},{name:"getTransactionFromBlock",call:i,outputFormatter:n.outputTransactionFormatter,inputFormatter:r.toHex},{name:"getTransactionCount",call:"eth_getTransactionCount",addDefaultblock:2,outputFormatter:r.toDecimal},{name:"sendTransaction",call:"eth_sendTransaction",inputFormatter:n.inputTransactionFormatter},{name:"call",call:"eth_call",addDefaultblock:2,inputFormatter:n.inputCallFormatter},{name:"compile.solidity",call:"eth_compileSolidity"},{name:"compile.lll",call:"eth_compileLLL",inputFormatter:r.toHex},{name:"compile.serpent",call:"eth_compileSerpent",inputFormatter:r.toHex},{name:"flush",call:"eth_flush"},{name:"balanceAt",call:"eth_balanceAt",newMethod:"eth.getBalance"},{name:"stateAt",call:"eth_stateAt",newMethod:"eth.getStorageAt"},{name:"storageAt",call:"eth_storageAt",newMethod:"eth.getStorage"},{name:"countAt",call:"eth_countAt",newMethod:"eth.getTransactionCount"},{name:"codeAt",call:"eth_codeAt",newMethod:"eth.getData"},{name:"transact",call:"eth_transact",newMethod:"eth.sendTransaction"},{name:"block",call:o,newMethod:"eth.getBlock"},{name:"transaction",call:i,newMethod:"eth.getTransaction"},{name:"uncle",call:a,newMethod:"eth.getUncle"},{name:"compilers",call:"eth_compilers",newMethod:"eth.getCompilers"},{name:"solidity",call:"eth_solidity",newMethod:"eth.compile.solidity"},{name:"lll",call:"eth_lll",newMethod:"eth.compile.lll"},{name:"serpent",call:"eth_serpent",newMethod:"eth.compile.serpent"},{name:"transactionCount",call:u,newMethod:"eth.getBlockTransactionCount"},{name:"uncleCount",call:s,newMethod:"eth.getBlockUncleCount"},{name:"logs",call:"eth_logs"}],l=[{name:"coinbase",getter:"eth_coinbase"},{name:"mining",getter:"eth_mining"},{name:"gasPrice",getter:"eth_gasPrice",outputFormatter:n.convertToBigNumber},{name:"accounts",getter:"eth_accounts"},{name:"blockNumber",getter:"eth_blockNumber",outputFormatter:r.toDecimal},{name:"listening",getter:"net_listening",setter:"eth_setListening",newProperty:"net.listening"},{name:"peerCount",getter:"net_peerCount",newProperty:"net.peerCount"},{name:"number",getter:"eth_number",newProperty:"eth.blockNumber"}];e.exports={methods:c,properties:l}},{"../utils/utils":5,"./formatters":12}],10:[function(t,e){var n=t("../solidity/abi"),r=t("../utils/utils"),o=t("./signature"),i=function(t,e){return t.filter(function(t){return t.indexed===e})},a=function(t,e){var n=r.findIndex(t,function(t){return t.name===e});return-1===n?void console.error("indexed param with name "+e+" not found"):t[n]},u=function(t,e){return Object.keys(e).map(function(r){var o=[a(i(t.inputs,!0),r)],u=e[r];return u instanceof Array?u.map(function(t){return n.formatInput(o,[t])}):n.formatInput(o,[u])})},s=function(t,e,n){return function(r,o){var i=o||{};return i.address=t,i.topics=[],i.topics.push(e),r&&(i.topics=i.topics.concat(u(n,r))),i}},c=function(t,e,n){var r=e.slice(),o=n.slice();return t.reduce(function(t,e){var n;return n=e.indexed?r.splice(0,1)[0]:o.splice(0,1)[0],t[e.name]=n,t},{})},l=function(t){return function(e){var o={event:r.extractDisplayName(t.name),number:e.number,hash:e.hash,args:{}};if(e.topics=e.topic,!e.topics)return o;var a=i(t.inputs,!0),u="0x"+e.topics.slice(1,e.topics.length).map(function(t){return t.slice(2)}).join(""),s=n.formatOutput(a,u),l=i(t.inputs,!1),f=n.formatOutput(l,e.data);return o.args=c(t.inputs,s,f),o}},f=function(t,e){for(var n=0;n * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * Gav Wood * @date 2014 */ +var version = require('../version.json'); var net = require('./web3/net'); var eth = require('./web3/eth'); var db = require('./web3/db'); @@ -35,11 +37,14 @@ var requestManager = require('./web3/requestmanager'); var c = require('./utils/config'); /// @returns an array of objects describing web3 api methods -var web3Methods = function () { - return [ - { name: 'sha3', call: 'web3_sha3' } - ]; -}; +var web3Methods = [ + { name: 'sha3', call: 'web3_sha3', inputFormatter: utils.toHex }, +]; +var web3Properties = [ + { name: 'version.client', getter: 'web3_clientVersion' }, + { name: 'version.network', getter: 'net_version' } +]; + /// creates methods in a given object based on method description on input /// setups api calls for these methods @@ -99,7 +104,9 @@ var setupMethods = function (obj, methods) { /// setups api calls for these properties var setupProperties = function (obj, properties) { properties.forEach(function (property) { - var proto = {}; + var objectProperties = property.name.split('.'), + proto = {}; + proto.get = function () { // show deprecated warning @@ -129,7 +136,14 @@ var setupProperties = function (obj, properties) { } proto.enumerable = !property.newProperty; - Object.defineProperty(obj, property.name, proto); + + if(objectProperties.length > 1) { + if(!obj[objectProperties[0]]) + obj[objectProperties[0]] = {}; + + Object.defineProperty(obj[objectProperties[0]], objectProperties[1], proto); + } else + Object.defineProperty(obj, property.name, proto); }); }; @@ -159,6 +173,11 @@ var shhWatch = { /// setups web3 object, and it's in-browser executed methods var web3 = { + + version: { + api: version.version + }, + manager: requestManager(), providers: {}, @@ -266,7 +285,8 @@ Object.defineProperty(web3.eth, 'defaultBlock', { /// setups all api methods -setupMethods(web3, web3Methods()); +setupMethods(web3, web3Methods); +setupProperties(web3, web3Properties); setupMethods(web3.net, net.methods); setupProperties(web3.net, net.properties); setupMethods(web3.eth, eth.methods); diff --git a/lib/web3/db.js b/lib/web3/db.js index 5f5ebc2b1..0db0bb79a 100644 --- a/lib/web3/db.js +++ b/lib/web3/db.js @@ -20,13 +20,14 @@ * @date 2015 */ + /// @returns an array of objects describing web3.db api methods var methods = function () { return [ - { name: 'put', call: 'db_put' }, - { name: 'get', call: 'db_get' }, - { name: 'putString', call: 'db_putString' }, - { name: 'getString', call: 'db_getString' } + { name: 'putString', call: 'db_putString'}, + { name: 'getString', call: 'db_getString'}, + { name: 'putHex', call: 'db_putHex'}, + { name: 'getHex', call: 'db_getHex'} ]; }; diff --git a/lib/web3/eth.js b/lib/web3/eth.js index cdf245198..068b68757 100644 --- a/lib/web3/eth.js +++ b/lib/web3/eth.js @@ -17,6 +17,7 @@ /** @file eth.js * @authors: * Marek Kotewicz + * Fabian Vogelsteller * @date 2015 */ @@ -102,7 +103,7 @@ var methods = [ inputFormatter: formatters.inputTransactionFormatter }, { name: 'call', call: 'eth_call', addDefaultblock: 2, inputFormatter: formatters.inputCallFormatter }, - { name: 'compile.solidity', call: 'eth_compileSolidity', inputFormatter: utils.toHex }, + { name: 'compile.solidity', call: 'eth_compileSolidity' }, { name: 'compile.lll', call: 'eth_compileLLL', inputFormatter: utils.toHex }, { name: 'compile.serpent', call: 'eth_compileSerpent', inputFormatter: utils.toHex }, { name: 'flush', call: 'eth_flush' }, diff --git a/lib/web3/filter.js b/lib/web3/filter.js index 022b762bd..9b5666373 100644 --- a/lib/web3/filter.js +++ b/lib/web3/filter.js @@ -19,6 +19,7 @@ * Jeffrey Wilcke * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * Gav Wood * @date 2014 */ diff --git a/lib/web3/httpprovider.js b/lib/web3/httpprovider.js index 34479f704..8e1daa5c7 100644 --- a/lib/web3/httpprovider.js +++ b/lib/web3/httpprovider.js @@ -18,6 +18,7 @@ * @authors: * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * @date 2014 */ @@ -33,7 +34,6 @@ var HttpProvider = function (host) { HttpProvider.prototype.send = function (payload, callback) { var request = new XMLHttpRequest(); - request.open('POST', this.host, false); // ASYNC if(typeof callback === 'function') { diff --git a/lib/web3/requestmanager.js b/lib/web3/requestmanager.js index 383ca7805..345aaf658 100644 --- a/lib/web3/requestmanager.js +++ b/lib/web3/requestmanager.js @@ -19,6 +19,7 @@ * Jeffrey Wilcke * Marek Kotewicz * Marian Oancea + * Fabian Vogelsteller * Gav Wood * @date 2014 */ @@ -89,7 +90,6 @@ var requestManager = function() { var result = provider.send(payload); if (!jsonrpc.isValidResponse(result)) { - console.log(result); if(typeof result === 'object' && result.error && result.error.message) console.error(result.error.message); return null; diff --git a/package.js b/package.js index 3f8bbe790..f4bc32631 100644 --- a/package.js +++ b/package.js @@ -1,7 +1,7 @@ /* jshint ignore:start */ Package.describe({ name: 'ethereum:js', - version: '0.1.2', + version: '0.1.3', summary: 'Ethereum JavaScript API, middleware to talk to a ethreum node over RPC', git: 'https://github.com/ethereum/ethereum.js', // By default, Meteor will default to using README.md for documentation. diff --git a/package.json b/package.json index 8007f0e6d..258eb5d1d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ethereum.js", "namespace": "ethereum", - "version": "0.1.2", + "version": "0.1.3", "description": "Ethereum JavaScript API, middleware to talk to a ethreum node over RPC", "main": "./index.js", "directories": { @@ -23,6 +23,7 @@ "gulp": ">=3.4.0", "gulp-jshint": ">=1.5.0", "gulp-rename": ">=1.2.0", + "gulp-replace": "^0.5.3", "gulp-streamify": "0.0.5", "gulp-uglify": ">=1.0.0", "istanbul": "^0.3.5", @@ -89,8 +90,8 @@ }, { "name": "Fabian Vogelsteller", - "email": "fabian@ethdev.com", - "homepage": "https://github.com/frozeman" + "email": "fabian@frozeman.de", + "homepage": "http://frozeman.de" } ], "license": "LGPL-3.0" diff --git a/test/abi.inputParser.js b/test/abi.inputParser.js index 2ee87761f..1d3a869e3 100644 --- a/test/abi.inputParser.js +++ b/test/abi.inputParser.js @@ -227,56 +227,6 @@ describe('abi', function() { }); - it('should parse input hash', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "hash" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); - - }); - - it('should parse input hash256', function() { - - // given - var d = clone(description); - - d[0].inputs = [ - { type: "hash256" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); - - }); - - - it('should parse input hash160', function() { - // given - var d = clone(description); - - d[0].inputs = [ - { type: "hash160" } - ]; - - // when - var parser = abi.inputParser(d); - - // then - assert.equal(parser.test("0x407d73d8a49eeb85d32cf465507dd71d507100c1"), "000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1"); - }); - it('should parse input address', function () { // given @@ -294,13 +244,13 @@ describe('abi', function() { }); - it('should parse input string', function () { + it('should parse input fixed bytes type', function () { // given var d = clone(description); d[0].inputs = [ - { type: "string" } + { type: "bytes" } ]; // when @@ -318,14 +268,14 @@ describe('abi', function() { ); }); - it('should parse input int followed by a string', function () { + it('should parse input int followed by a fixed bytes type', function () { // given var d = clone(description); d[0].inputs = [ { type: "int" }, - { type: "string" } + { type: "bytes" } ]; // when @@ -340,13 +290,13 @@ describe('abi', function() { ); }); - it('should parse input string followed by an int', function () { + it('should parse input fixed bytes type followed by an int', function () { // given var d = clone(description); d[0].inputs = [ - { type: "string" }, + { type: "bytes" }, { type: "int" } ]; @@ -391,8 +341,8 @@ describe('abi', function() { },{ name: "test2", type: "function", - inputs: [{ type: "string" }], - outputs: [{ type: "string" }] + inputs: [{ type: "bytes" }], + outputs: [{ type: "bytes" }] }]; // when diff --git a/test/abi.outputParser.js b/test/abi.outputParser.js index 1ddd9d4fd..955c0d5f1 100644 --- a/test/abi.outputParser.js +++ b/test/abi.outputParser.js @@ -21,13 +21,13 @@ var description = [{ describe('abi', function() { describe('outputParser', function() { - it('should parse output string', function() { + it('should parse output fixed bytes type', function() { // given var d = clone(description); d[0].outputs = [ - { type: "string" } + { type: "bytes" } ]; // when @@ -181,64 +181,6 @@ describe('abi', function() { assert.equal(parser.test("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0")[0], -16); }); - it('should parse output hash', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'hash' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal( - parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], - "0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1" - ); - }); - - it('should parse output hash256', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'hash256' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal( - parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], - "0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1" - ); - }); - - it('should parse output hash160', function() { - - // given - var d = clone(description); - - d[0].outputs = [ - { type: 'hash160' } - ]; - - // when - var parser = abi.outputParser(d); - - // then - assert.equal( - parser.test("0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1")[0], - "0x000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1" - ); - // TODO shouldnt' the expected hash be shorter? - }); - it('should parse output address', function() { // given @@ -317,14 +259,14 @@ describe('abi', function() { }); - it('should parse multiple output strings', function() { + it('should parse multiple output fixed bytes type', function() { // given var d = clone(description); d[0].outputs = [ - { type: "string" }, - { type: "string" } + { type: "bytes" }, + { type: "bytes" } ]; // when @@ -380,8 +322,8 @@ describe('abi', function() { },{ name: "test2", type: "function", - inputs: [{ type: "string" }], - outputs: [{ type: "string" }] + inputs: [{ type: "bytes" }], + outputs: [{ type: "bytes" }] }]; // when diff --git a/test/db.methods.js b/test/db.methods.js index 2ad384579..aac8981d2 100644 --- a/test/db.methods.js +++ b/test/db.methods.js @@ -5,8 +5,8 @@ var u = require('./test.utils.js'); describe('web3', function() { describe('db', function() { - u.methodExists(web3.db, 'put'); - u.methodExists(web3.db, 'get'); + u.methodExists(web3.db, 'putHex'); + u.methodExists(web3.db, 'getHex'); u.methodExists(web3.db, 'putString'); u.methodExists(web3.db, 'getString'); }); diff --git a/version.json b/version.json new file mode 100644 index 000000000..39bf64da0 --- /dev/null +++ b/version.json @@ -0,0 +1,3 @@ +{ + "version": "0.1.3" +} \ No newline at end of file From 4d67fe39ac5892ab88ce2e60292948fab93d15c8 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 13 Mar 2015 13:14:51 +0100 Subject: [PATCH 34/49] Fix gas for builtin. Fixes #1300 --- libsolidity/ArrayUtils.cpp | 1 + libsolidity/Compiler.cpp | 2 ++ libsolidity/CompilerUtils.cpp | 4 ++-- libsolidity/ExpressionCompiler.cpp | 6 ++++++ libsolidity/LValue.cpp | 1 + test/SolidityEndToEndTest.cpp | 15 +++++++++++++++ 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/libsolidity/ArrayUtils.cpp b/libsolidity/ArrayUtils.cpp index f0d7d6a81..a064b2f57 100644 --- a/libsolidity/ArrayUtils.cpp +++ b/libsolidity/ArrayUtils.cpp @@ -125,6 +125,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, true, true, false); else solAssert(false, "Copying of unknown type requested: " + sourceBaseType->toString()); + solAssert(2 + sourceBaseType->getSizeOnStack() <= 16, "Stack too deep."); m_context << eth::dupInstruction(2 + sourceBaseType->getSizeOnStack()); StorageItem(m_context, *targetBaseType).storeValue(*sourceBaseType, SourceLocation(), true); } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index dc6e2c5a8..b8ca03d3e 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -228,6 +228,7 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool { // Retrieve data start offset by adding length to start offset of previous dynamic type unsigned stackDepth = m_context.getStackHeight() - stackHeightOfPreviousDynamicArgument; + solAssert(stackDepth <= 16, "Stack too deep."); m_context << eth::dupInstruction(stackDepth) << eth::dupInstruction(stackDepth); ArrayUtils(m_context).convertLengthToSize(*previousDynamicType, true); m_context << eth::Instruction::ADD; @@ -359,6 +360,7 @@ bool Compiler::visit(FunctionDefinition const& _function) stackLayout.push_back(i); stackLayout += vector(c_localVariablesSize, -1); + solAssert(stackLayout.size() <= 17, "Stack too deep."); while (stackLayout.back() != int(stackLayout.size() - 1)) if (stackLayout.back() < 0) { diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 7b078e03e..e517e384d 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -138,6 +138,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) { unsigned const stackPosition = m_context.baseToCurrentStackOffset(m_context.getBaseStackOffsetOfVariable(_variable)); unsigned const size = _variable.getType()->getSizeOnStack(); + solAssert(stackPosition >= size, "Variable size and position mismatch."); // move variable starting from its top end in the stack if (stackPosition - size + 1 > 16) BOOST_THROW_EXCEPTION(CompilerError() << errinfo_sourceLocation(_variable.getLocation()) @@ -148,8 +149,7 @@ void CompilerUtils::moveToStackVariable(VariableDeclaration const& _variable) void CompilerUtils::copyToStackTop(unsigned _stackDepth, unsigned _itemSize) { - if (_stackDepth > 16) - BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Stack too deep.")); + solAssert(_stackDepth <= 16, "Stack too deep."); for (unsigned i = 0; i < _itemSize; ++i) m_context << eth::dupInstruction(_stackDepth); } diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 3cee40df1..331979c7d 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -233,9 +233,12 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) m_currentLValue->retrieveValue(_assignment.getLocation(), true); appendOrdinaryBinaryOperatorCode(Token::AssignmentToBinaryOp(op), *_assignment.getType()); if (lvalueSize > 0) + { + solAssert(itemSize + lvalueSize <= 16, "Stack too deep."); // value [lvalue_ref] updated_value for (unsigned i = 0; i < itemSize; ++i) m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP; + } } m_currentLValue->storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation()); m_currentLValue.reset(); @@ -557,10 +560,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case Location::SHA256: case Location::RIPEMD160: { + _functionCall.getExpression().accept(*this); static const map contractAddresses{{Location::ECRecover, 1}, {Location::SHA256, 2}, {Location::RIPEMD160, 3}}; m_context << contractAddresses.find(function.getLocation())->second; + for (unsigned i = function.getSizeOnStack(); i > 0; --i) + m_context << eth::swapInstruction(i); appendExternalFunctionCall(function, arguments, true); break; } diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index a56ed54c7..68d6797eb 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -167,6 +167,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc // stack: source_ref target_ref member_offset source_member_ref StorageItem(m_context, *memberType).retrieveValue(_location, true); // stack: source_ref target_ref member_offset source_value... + solAssert(2 + memberType->getSizeOnStack() <= 16, "Stack too deep."); m_context << eth::dupInstruction(2 + memberType->getSizeOnStack()) << eth::dupInstruction(2 + memberType->getSizeOnStack()) << eth::Instruction::ADD; // stack: source_ref target_ref member_offset source_value... target_member_ref diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index 2f965849b..07ad3edbc 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -1647,6 +1647,21 @@ BOOST_AUTO_TEST_CASE(gas_and_value_basic) BOOST_REQUIRE(callContractFunction("checkState()", 5) == encodeArgs(false, 20 - 5)); } +BOOST_AUTO_TEST_CASE(gas_for_builtin) +{ + char const* sourceCode = R"( + contract Contract { + function test(uint g) returns (bytes32 data, bool flag) { + data = ripemd160.gas(g)("abc"); + flag = true; + } + } + )"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("test(uint256)", 500) == bytes()); + BOOST_CHECK(callContractFunction("test(uint256)", 800) == encodeArgs(u256("0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"), true)); +} + BOOST_AUTO_TEST_CASE(value_complex) { char const* sourceCode = R"( From bba8184f1e0b1147e4b4a412131d9cc2a51e3557 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Mar 2015 19:37:21 +0100 Subject: [PATCH 35/49] First attempt at GPU integration. --- CMakeLists.txt | 2 +- libethcore/BlockInfo.cpp | 2 +- libethcore/BlockInfo.h | 2 +- libethcore/ProofOfWork.cpp | 115 ++++++++++++++++++++++++++++++++++++- libethcore/ProofOfWork.h | 35 ++++++++++- libethereum/CMakeLists.txt | 4 ++ libethereum/Client.cpp | 5 +- libethereum/Client.h | 8 +-- libethereum/Miner.cpp | 8 +-- libethereum/Miner.h | 30 +++++++++- 10 files changed, 193 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 037728a9e..e7e89a5a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,7 @@ configureProject() set (ETH_HAVE_WEBENGINE 1) message(STATUS "CMAKE_VERSION: ${CMAKE_VERSION}") -message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}; EVMJIT: ${EVMJIT}; FATDB: ${FATDB}; CHROMIUM: ${ETH_HAVE_WEBENGINE}; USENPM: ${USENPM}") +message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}; EVMJIT: ${EVMJIT}; FATDB: ${FATDB}; CHROMIUM: ${ETH_HAVE_WEBENGINE}; USENPM: ${USENPM}; ETHASHCL: ${ETHASHCL}") # Default TARGET_PLATFORM to "linux". diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index ef57264a1..f04353aac 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -61,7 +61,7 @@ void BlockInfo::setEmpty() hash = headerHash(WithNonce); } -h256 BlockInfo::seedHash() const +h256 const& BlockInfo::seedHash() const { if (!m_seedHash) for (u256 n = number; n >= c_epochDuration; n -= c_epochDuration) diff --git a/libethcore/BlockInfo.h b/libethcore/BlockInfo.h index 912978ef0..8f42dc038 100644 --- a/libethcore/BlockInfo.h +++ b/libethcore/BlockInfo.h @@ -128,7 +128,7 @@ public: u256 calculateDifficulty(BlockInfo const& _parent) const; u256 selectGasLimit(BlockInfo const& _parent) const; - h256 seedHash() const; + h256 const& seedHash() const; /// sha3 of the header only. h256 headerHash(IncludeNonce _n) const; diff --git a/libethcore/ProofOfWork.cpp b/libethcore/ProofOfWork.cpp index d261ccb1c..3cbfb4905 100644 --- a/libethcore/ProofOfWork.cpp +++ b/libethcore/ProofOfWork.cpp @@ -30,6 +30,9 @@ #include #include #include +#if ETH_ETHASHCL +#include +#endif #include "BlockInfo.h" #include "Ethasher.h" #include "ProofOfWork.h" @@ -41,12 +44,12 @@ namespace dev namespace eth { -bool Ethash::verify(BlockInfo const& _header) +bool EthashCPU::verify(BlockInfo const& _header) { return Ethasher::verify(_header); } -std::pair Ethash::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) +std::pair EthashCPU::mine(BlockInfo const& _header, unsigned _msTimeout, bool _continue, bool _turbo) { Ethasher::Miner m(_header); @@ -93,5 +96,113 @@ std::pair Ethash::mine(BlockInfo const& _header, unsign return ret; } +#if ETH_ETHASHCL + +/* +struct ethash_cl_search_hook +{ + // reports progress, return true to abort + virtual bool found(uint64_t const* nonces, uint32_t count) = 0; + virtual bool searched(uint64_t start_nonce, uint32_t count) = 0; +}; + +class ethash_cl_miner +{ +public: + ethash_cl_miner(); + + bool init(ethash_params const& params, const uint8_t seed[32], unsigned workgroup_size = 64); + + void hash(uint8_t* ret, uint8_t const* header, uint64_t nonce, unsigned count); + void search(uint8_t const* header, uint64_t target, search_hook& hook); +}; +*/ + +struct EthashCLHook: public ethash_cl_search_hook +{ + virtual bool found(uint64_t const* _nonces, uint32_t _count) + { + Guard l(x_all); + for (unsigned i = 0; i < _count; ++i) + found.push_back((Nonce)(u64)_nonces[i]); + if (abort) + { + aborted = true; + return true; + } + return false; + } + + virtual bool searched(uint64_t _startNonce, uint32_t _count) + { + Guard l(x_all); + total += _count; + last = _startNonce + _count; + if (abort) + { + aborted = true; + return true; + } + return false; + } + + vector fetchFound() { vector ret; Guard l(x_all); std::swap(ret, found); return ret; } + uint64_t fetchTotal() { Guard l(x_all); auto ret = total; total = 0; return ret; } + + Mutex x_all; + vector found; + uint64_t total; + uint64_t last; + bool abort = false; + bool aborted = false; +}; + +EthashCL::EthashCL(): + m_miner(new ethash_cl_miner), + m_hook(new EthashCLHook) +{ +} + +EthashCL::~EthashCL() +{ + m_hook->abort = true; + for (unsigned timeout = 0; timeout < 100 && !m_hook->aborted; ++timeout) + std::this_thread::sleep_for(chrono::milliseconds(30)); + if (!m_hook->aborted) + cwarn << "Couldn't abort. Abandoning OpenCL process."; +} + +bool EthashCL::verify(BlockInfo const& _header) +{ + return Ethasher::verify(_header); +} + +std::pair EthashCL::mine(BlockInfo const& _header, unsigned _msTimeout, bool, bool) +{ + if (m_lastHeader.seedHash() != _header.seedHash()) + { + m_miner->init(Ethasher::params(_header), _header.seedHash().data()); + // TODO: reinit probably won't work when seed changes. + } + if (m_lastHeader != _header) + { + static std::random_device s_eng; + uint64_t tryNonce = (uint64_t)(u64)(m_last = Nonce::random(s_eng)); + m_miner->search(_header.headerHash(WithoutNonce).data(), tryNonce, *m_hook); + } + m_lastHeader = _header; + + std::this_thread::sleep_for(chrono::milliseconds(_msTimeout)); + auto found = m_hook->fetchFound(); + if (!found.empty()) + { + h256 mixHash; // ????? + return std::make_pair(MineInfo{0.0, 1e99, 0, true}, EthashCL::Proof((Nonce)(u64)found[0], mixHash)); + } + return std::make_pair(MineInfo{0.0, 1e99, 0, false}, EthashCL::Proof()); +} + +#endif + } } diff --git a/libethcore/ProofOfWork.h b/libethcore/ProofOfWork.h index 250ddb73d..245a96a02 100644 --- a/libethcore/ProofOfWork.h +++ b/libethcore/ProofOfWork.h @@ -32,6 +32,9 @@ #define FAKE_DAGGER 1 +class ethash_cl_miner; +struct ethash_cl_search_hook; + namespace dev { namespace eth @@ -46,7 +49,7 @@ struct MineInfo bool completed = false; }; -class Ethash +class EthashCPU { public: struct Proof @@ -63,6 +66,36 @@ protected: Nonce m_last; }; +#if ETH_ETHASHCL +class EthashCL +{ +public: + struct Proof + { + Nonce nonce; + h256 mixHash; + }; + + EthashCL(); + ~EthashCL(); + + static bool verify(BlockInfo const& _header); + std::pair mine(BlockInfo const& _header, unsigned _msTimeout = 100, bool _continue = true, bool _turbo = false); + static void assignResult(Proof const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } + +protected: + Nonce m_last; + BlockInfo m_lastHeader; + Nonce m_mined; + std::unique_ptr m_miner; + std::unique_ptr m_hook; +}; + +using Ethash = EthashCL; +#else +using Ethash = EthashCPU; +#endif + template class ProofOfWorkEngine: public Evaluator { diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index 94a4e4497..3df3b9bc3 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -36,6 +36,10 @@ target_link_libraries(${EXECUTABLE} devcrypto) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} secp256k1) +if (ETHASHCL) + target_link_libraries(${EXECUTABLE} ethash-cl) +endif () + if (CMAKE_COMPILER_IS_MINGW) target_link_libraries(${EXECUTABLE} ssp shlwapi) endif() diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index bd8b3da40..f46d0d3c9 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -411,8 +411,11 @@ void Client::setForceMining(bool _enable) void Client::setMiningThreads(unsigned _threads) { stopMining(); - +#if ETH_ETHASHCL + unsigned t = 1; +#else auto t = _threads ? _threads : thread::hardware_concurrency(); +#endif WriteGuard l(x_localMiners); m_localMiners.clear(); m_localMiners.resize(t); diff --git a/libethereum/Client.h b/libethereum/Client.h index cdfdcd1eb..04798ecdb 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -323,12 +323,12 @@ public: virtual unsigned miningThreads() const { ReadGuard l(x_localMiners); return m_localMiners.size(); } /// Start mining. /// NOT thread-safe - call it & stopMining only from a single thread - virtual void startMining() { startWorking(); ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); } + virtual void startMining() { startWorking(); { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.start(); } } /// Stop mining. /// NOT thread-safe - virtual void stopMining() { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); } + virtual void stopMining() { { ReadGuard l(x_localMiners); for (auto& m: m_localMiners) m.stop(); } } /// Are we mining now? - virtual bool isMining() { ReadGuard l(x_localMiners); return m_localMiners.size() && m_localMiners[0].isRunning(); } + virtual bool isMining() { { ReadGuard l(x_localMiners); if (!m_localMiners.empty() && m_localMiners[0].isRunning()) return true; } return false; } /// Check the progress of the mining. virtual MineProgress miningProgress() const; /// Get and clear the mining history. @@ -405,8 +405,6 @@ private: bool m_forceMining = false; ///< Mine even when there are no transactions pending? bool m_verifyOwnBlocks = true; ///< Should be verify blocks that we mined? - - mutable Mutex m_filterLock; std::map m_filters; std::map m_watches; diff --git a/libethereum/Miner.cpp b/libethereum/Miner.cpp index a049fca2f..08bc426dc 100644 --- a/libethereum/Miner.cpp +++ b/libethereum/Miner.cpp @@ -31,15 +31,15 @@ using namespace dev::eth; Miner::~Miner() {} LocalMiner::LocalMiner(MinerHost* _host, unsigned _id): - Worker("miner-" + toString(_id)), - m_host(_host) + AsyncMiner(_host, _id), + Worker("miner-" + toString(_id)) { } void LocalMiner::setup(MinerHost* _host, unsigned _id) { - m_host = _host; - setName("miner-" + toString(_id)); + AsyncMiner::setup(_host, _id); + setName("miner-" + toString(m_id)); } void LocalMiner::doWork() diff --git a/libethereum/Miner.h b/libethereum/Miner.h index e472c6f64..eaa9c9e8c 100644 --- a/libethereum/Miner.h +++ b/libethereum/Miner.h @@ -74,6 +74,32 @@ public: virtual bytes const& blockData() const = 0; }; +class AsyncMiner: public Miner +{ +public: + /// Null constructor. + AsyncMiner(): m_host(nullptr) {} + + /// Constructor. + AsyncMiner(MinerHost* _host, unsigned _id = 0): m_host(_host), m_id(_id) {} + + /// Setup its basics. + void setup(MinerHost* _host, unsigned _id = 0) { m_host = _host; m_id = _id; } + + /// Start mining. + virtual void start() {} + + /// Stop mining. + virtual void stop() {} + + /// @returns true iff the mining has been start()ed. It may still not be actually mining, depending on the host's turbo() & force(). + virtual bool isRunning() { return false; } + +protected: + MinerHost* m_host = nullptr; ///< Our host. + unsigned m_id = 0; ///< Our unique id. +}; + /** * @brief Implements Miner. * To begin mining, use start() & stop(). noteStateChange() can be used to reset the mining and set up the @@ -86,11 +112,11 @@ public: * @threadsafe * @todo Signal Miner to restart once with condition variables. */ -class LocalMiner: public Miner, Worker +class LocalMiner: public AsyncMiner, Worker { public: /// Null constructor. - LocalMiner(): m_host(nullptr) {} + LocalMiner() {} /// Constructor. LocalMiner(MinerHost* _host, unsigned _id = 0); From 09094cbc07e5f533c161d567a9c03b9549db543a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Fri, 13 Mar 2015 20:07:18 +0100 Subject: [PATCH 36/49] Silly shadow bug fix. --- libethereum/Miner.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libethereum/Miner.h b/libethereum/Miner.h index eaa9c9e8c..7c4f7e767 100644 --- a/libethereum/Miner.h +++ b/libethereum/Miner.h @@ -164,8 +164,6 @@ private: /// Do some work on the mining. virtual void doWork(); - MinerHost* m_host = nullptr; ///< Our host. - enum MiningStatus { Waiting, Preparing, Mining, Mined, Stopping, Stopped }; MiningStatus m_miningStatus = Waiting; ///< TODO: consider mutex/atomic variable. State m_mineState; ///< The state on which we are mining, generally equivalent to m_postMine. From 9b851e9359c18ecd740f934bdd0ec1a3bfc5a114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 13 Mar 2015 11:19:26 +0100 Subject: [PATCH 37/49] Stats for testeth Simple listener support added to testeth. Stats class implements the Listener interface and collects tests execution times. Try options: --stats or --stats=full. Closes ethereum/cpp-ethereum#1285 --- test/CMakeLists.txt | 8 ++--- test/Stats.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++ test/Stats.h | 50 +++++++++++++++++++++++++++ test/TestHelper.cpp | 28 +++++++++++++++ test/TestHelper.h | 30 +++++++++++++++- test/state.cpp | 21 +++--------- test/vm.cpp | 39 +++++---------------- 7 files changed, 207 insertions(+), 52 deletions(-) create mode 100644 test/Stats.cpp create mode 100644 test/Stats.h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d7761b8d3..ef292c2bb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -19,10 +19,10 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) file(GLOB HEADERS "*.h") add_executable(testeth ${SRC_LIST} ${HEADERS}) -add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp) -add_executable(createRandomStateTest createRandomStateTest.cpp TestHelper.cpp) -add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp) -add_executable(checkRandomStateTest checkRandomStateTest.cpp TestHelper.cpp) +add_executable(createRandomVMTest createRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp) +add_executable(createRandomStateTest createRandomStateTest.cpp TestHelper.cpp Stats.cpp) +add_executable(checkRandomVMTest checkRandomVMTest.cpp vm.cpp TestHelper.cpp Stats.cpp) +add_executable(checkRandomStateTest checkRandomStateTest.cpp TestHelper.cpp Stats.cpp) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) diff --git a/test/Stats.cpp b/test/Stats.cpp new file mode 100644 index 000000000..fa615cb50 --- /dev/null +++ b/test/Stats.cpp @@ -0,0 +1,83 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +#include "Stats.h" + +#include +#include + +namespace dev +{ +namespace test +{ + +Stats& Stats::get() +{ + static Stats instance; + return instance; +} + +void Stats::testStarted(std::string const& _name) +{ + m_currentTest = _name; + m_tp = clock::now(); +} + +void Stats::testFinished() +{ + m_stats[clock::now() - m_tp] = std::move(m_currentTest); +} + +std::ostream& operator<<(std::ostream& out, Stats::clock::duration const& d) +{ + return out << std::setw(10) << std::right << std::chrono::duration_cast(d).count() << " us"; +} + +Stats::~Stats() +{ + if (m_stats.empty()) + return; + + auto& out = std::cout; + auto itr = m_stats.begin(); + auto min = *itr; + auto max = *m_stats.rbegin(); + std::advance(itr, m_stats.size() / 2); + auto med = *itr; + auto tot = std::accumulate(m_stats.begin(), m_stats.end(), clock::duration{}, [](clock::duration const& a, stats_t::value_type const& v) + { + return a + v.first; + }); + + out << "\nSTATS:\n\n" << std::setfill(' '); + + if (Options::get().statsFull) + { + for (auto&& s: m_stats) + out << " " << std::setw(40) << std::left << s.second.substr(0, 40) << s.first << " \n"; + out << "\n"; + } + + out << " tot: " << tot << "\n" + << " avg: " << (tot / m_stats.size()) << "\n\n" + << " min: " << min.first << " (" << min.second << ")\n" + << " med: " << med.first << " (" << med.second << ")\n" + << " max: " << max.first << " (" << max.second << ")\n"; +} + +} +} diff --git a/test/Stats.h b/test/Stats.h new file mode 100644 index 000000000..7692a2b30 --- /dev/null +++ b/test/Stats.h @@ -0,0 +1,50 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ + +#pragma once + +#include +#include + +#include "TestHelper.h" + +namespace dev +{ +namespace test +{ + +class Stats: public Listener +{ +public: + using clock = std::chrono::high_resolution_clock; + using stats_t = std::map; + + static Stats& get(); + + ~Stats(); + + void testStarted(std::string const& _name) override; + void testFinished() override; + +private: + clock::time_point m_tp; + std::string m_currentTest; + stats_t m_stats; +}; + +} +} diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index ddc929e4e..72fecf593 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -551,6 +551,10 @@ Options::Options() vmtrace = true; else if (arg == "--filltests") fillTests = true; + else if (arg == "--stats") + stats = true; + else if (arg == "--stats=full") + stats = statsFull = true; else if (arg == "--performance") performance = true; else if (arg == "--quadratic") @@ -578,6 +582,7 @@ Options const& Options::get() return instance; } + LastHashes lastHashes(u256 _currentBlockNumber) { LastHashes ret; @@ -586,4 +591,27 @@ LastHashes lastHashes(u256 _currentBlockNumber) return ret; } + +namespace +{ + Listener* g_listener; +} + +void Listener::registerListener(Listener& _listener) +{ + g_listener = &_listener; +} + +void Listener::notifyTestStarted(std::string const& _name) +{ + if (g_listener) + g_listener->testStarted(_name); +} + +void Listener::notifyTestFinished() +{ + if (g_listener) + g_listener->testFinished(); +} + } } // namespaces diff --git a/test/TestHelper.h b/test/TestHelper.h index 9efed0fa6..ade20f5e4 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -162,8 +162,9 @@ class Options public: bool jit = false; ///< Use JIT bool vmtrace = false; ///< Create EVM execution tracer // TODO: Link with log verbosity? - bool showTimes = false; ///< Print test groups execution times bool fillTests = false; ///< Create JSON test files from execution results + bool stats = false; ///< Execution time stats + bool statsFull = false; ///< Output full stats - execution times for every test /// Test selection /// @{ @@ -183,5 +184,32 @@ private: Options(Options const&) = delete; }; +/// Allows observing test execution process. +/// This class also provides methods for registering and notifying the listener +class Listener +{ +public: + virtual ~Listener() = default; + + virtual void testStarted(std::string const& _name) = 0; + virtual void testFinished() = 0; + + static void registerListener(Listener& _listener); + static void notifyTestStarted(std::string const& _name); + static void notifyTestFinished(); + + /// Test started/finished notification RAII helper + class ExecTimeGuard + { + public: + ExecTimeGuard(std::string const& _testName) { notifyTestStarted(_testName); } + ~ExecTimeGuard() { notifyTestFinished(); } + ExecTimeGuard(ExecTimeGuard const&) = delete; + ExecTimeGuard& operator=(ExecTimeGuard) = delete; + }; +}; + + + } } diff --git a/test/state.cpp b/test/state.cpp index d6790029a..8c191aa70 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -31,6 +31,7 @@ #include #include #include "TestHelper.h" +#include "Stats.h" using namespace std; using namespace json_spirit; @@ -41,7 +42,8 @@ namespace dev { namespace test { void doStateTests(json_spirit::mValue& v, bool _fillin) { - Options::get(); // process command line options + if (Options::get().stats) + Listener::registerListener(Stats::get()); for (auto& i: v.get_obj()) { @@ -60,6 +62,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) try { + Listener::ExecTimeGuard guard{i.first}; theState.execute(lastHashes(importer.m_environment.currentBlock.number), tx, &output); } catch (Exception const& _e) @@ -178,29 +181,13 @@ BOOST_AUTO_TEST_CASE(stBlockHashTest) BOOST_AUTO_TEST_CASE(stQuadraticComplexityTest) { if (test::Options::get().quadratic) - { - auto start = chrono::steady_clock::now(); - dev::test::executeTests("stQuadraticComplexityTest", "/StateTests", dev::test::doStateTests); - - auto end = chrono::steady_clock::now(); - auto duration(chrono::duration_cast(end - start)); - cnote << "test duration: " << duration.count() << " milliseconds.\n"; - } } BOOST_AUTO_TEST_CASE(stMemoryStressTest) { if (test::Options::get().memory) - { - auto start = chrono::steady_clock::now(); - dev::test::executeTests("stMemoryStressTest", "/StateTests", dev::test::doStateTests); - - auto end = chrono::steady_clock::now(); - auto duration(chrono::duration_cast(end - start)); - cnote << "test duration: " << duration.count() << " milliseconds.\n"; - } } BOOST_AUTO_TEST_CASE(stSolidityTest) diff --git a/test/vm.cpp b/test/vm.cpp index 4433a60ee..24ae4e069 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -20,13 +20,12 @@ * vm test functions. */ -#include - #include #include #include #include "vm.h" +#include "Stats.h" using namespace std; using namespace json_spirit; @@ -312,7 +311,8 @@ namespace dev { namespace test { void doVMTests(json_spirit::mValue& v, bool _fillin) { - Options::get(); // process command line options // TODO: We need to control the main() function + if (Options::get().stats) + Listener::registerListener(Stats::get()); for (auto& i: v.get_obj()) { @@ -340,12 +340,16 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) bytes output; u256 gas; bool vmExceptionOccured = false; - auto startTime = std::chrono::high_resolution_clock::now(); try { auto vm = eth::VMFactory::create(fev.gas); auto vmtrace = Options::get().vmtrace ? fev.simpleTrace() : OnOpFunc{}; - output = vm->go(fev, vmtrace).toBytes(); + auto outputRef = bytesConstRef{}; + { + Listener::ExecTimeGuard guard{i.first}; + outputRef = vm->go(fev, vmtrace); + } + output = outputRef.toBytes(); gas = vm->gas(); } catch (VMException const&) @@ -364,15 +368,6 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) BOOST_ERROR("Failed VM Test with Exception: " << _e.what()); } - auto endTime = std::chrono::high_resolution_clock::now(); - if (Options::get().showTimes) - { - auto testDuration = endTime - startTime; - cnote << "Execution time: " - << std::chrono::duration_cast(testDuration).count() - << " ms"; - } - // delete null entries in storage for the sake of comparison for (auto &a: fev.addresses) @@ -513,29 +508,13 @@ BOOST_AUTO_TEST_CASE(vmSystemOperationsTest) BOOST_AUTO_TEST_CASE(vmPerformanceTest) { if (test::Options::get().performance) - { - auto start = chrono::steady_clock::now(); - dev::test::executeTests("vmPerformanceTest", "/VMTests", dev::test::doVMTests); - - auto end = chrono::steady_clock::now(); - auto duration(chrono::duration_cast(end - start)); - cnote << "test duration: " << duration.count() << " milliseconds.\n"; - } } BOOST_AUTO_TEST_CASE(vmInputLimitsTest1) { if (test::Options::get().inputLimits) - { - auto start = chrono::steady_clock::now(); - dev::test::executeTests("vmInputLimits1", "/VMTests", dev::test::doVMTests); - - auto end = chrono::steady_clock::now(); - auto duration(chrono::duration_cast(end - start)); - cnote << "test duration: " << duration.count() << " milliseconds.\n"; - } } BOOST_AUTO_TEST_CASE(vmInputLimitsTest2) From 19fb5d986534262adbfcd98a342395a9dffb4f26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 13 Mar 2015 13:10:38 +0100 Subject: [PATCH 38/49] Prettify VM and State test outputs --- test/TestHelper.cpp | 2 +- test/state.cpp | 6 +++--- test/vm.cpp | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 72fecf593..128318b8c 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -473,7 +473,7 @@ void executeTests(const string& _name, const string& _testPathAppendix, std::fun try { - cnote << "Testing ..." << _name; + std::cout << "TEST " << _name << ":\n"; json_spirit::mValue v; string s = asString(dev::contents(testPath + "/" + _name + ".json")); BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + testPath + "/" + _name + ".json is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); diff --git a/test/state.cpp b/test/state.cpp index 8c191aa70..162ae5f34 100644 --- a/test/state.cpp +++ b/test/state.cpp @@ -47,7 +47,7 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) for (auto& i: v.get_obj()) { - cerr << i.first << endl; + std::cout << " " << i.first << "\n"; mObject& o = i.second.get_obj(); BOOST_REQUIRE(o.count("env") > 0); @@ -67,12 +67,12 @@ void doStateTests(json_spirit::mValue& v, bool _fillin) } catch (Exception const& _e) { - cnote << "state execution did throw an exception: " << diagnostic_information(_e); + cnote << "Exception:\n" << diagnostic_information(_e); theState.commit(); } catch (std::exception const& _e) { - cnote << "state execution did throw an exception: " << _e.what(); + cnote << "state execution exception: " << _e.what(); } if (_fillin) diff --git a/test/vm.cpp b/test/vm.cpp index 24ae4e069..2bdafb270 100644 --- a/test/vm.cpp +++ b/test/vm.cpp @@ -316,7 +316,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) for (auto& i: v.get_obj()) { - cnote << i.first; + std::cout << " " << i.first << "\n"; mObject& o = i.second.get_obj(); BOOST_REQUIRE(o.count("env") > 0); @@ -354,7 +354,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) } catch (VMException const&) { - cnote << "Safe VM Exception"; + std::cout << " Safe VM Exception\n"; vmExceptionOccured = true; } catch (Exception const& _e) @@ -544,7 +544,7 @@ BOOST_AUTO_TEST_CASE(vmRandom) { try { - cnote << "Testing ..." << path.filename(); + std::cout << "TEST " << path.filename() << "\n"; json_spirit::mValue v; string s = asString(dev::contents(path.string())); BOOST_REQUIRE_MESSAGE(s.length() > 0, "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); From 94718485cd4bc0f64ce6cea23eb95b95088d8a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Fri, 13 Mar 2015 13:37:30 +0100 Subject: [PATCH 39/49] Small improvements here and there Add virtual destructor to polymorphic GasPricer. Init v field of SignatureStruct. --- libdevcrypto/Common.h | 4 ++-- libethereum/State.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index 38e5649fb..3159f4e7e 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -45,7 +45,7 @@ using Signature = h520; struct SignatureStruct { - SignatureStruct() {} + SignatureStruct() = default; SignatureStruct(Signature const& _s) { *(h520*)this = _s; } SignatureStruct(h256 const& _r, h256 const& _s, byte _v): r(_r), s(_s), v(_v) {} operator Signature() const { return *(h520 const*)this; } @@ -55,7 +55,7 @@ struct SignatureStruct h256 r; h256 s; - byte v; + byte v = 0; }; /// An Ethereum address: 20 bytes. diff --git a/libethereum/State.h b/libethereum/State.h index 1f8516fce..bfa60e452 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -68,7 +68,8 @@ enum class TransactionPriority class GasPricer { public: - GasPricer() {} + GasPricer() = default; + virtual ~GasPricer() = default; virtual u256 ask(State const&) const = 0; virtual u256 bid(TransactionPriority _p = TransactionPriority::Medium) const = 0; From 1fcb747fefdcb63e4756b2fd02932550b9f5815e Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Sat, 14 Mar 2015 10:17:42 +0100 Subject: [PATCH 40/49] fix CallCode to address 0 --- libethereum/ExtVM.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/ExtVM.cpp b/libethereum/ExtVM.cpp index a8eba5a50..68d146ce1 100644 --- a/libethereum/ExtVM.cpp +++ b/libethereum/ExtVM.cpp @@ -29,7 +29,7 @@ using namespace dev::eth; bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp, Address _myAddressOverride, Address _codeAddressOverride) { Executive e(m_s, lastHashes, depth + 1); - if (!e.call(_receiveAddress, _codeAddressOverride ? _codeAddressOverride : _receiveAddress, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin)) + if (!e.call(_receiveAddress, _codeAddressOverride, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin)) { e.go(_onOp); e.accrueSubState(sub); From 475a14e5b1d3b7d41b9b695838f576994f240ae9 Mon Sep 17 00:00:00 2001 From: CJentzsch Date: Sat, 14 Mar 2015 10:26:06 +0100 Subject: [PATCH 41/49] test for callcode to 0 --- test/stSystemOperationsTestFiller.json | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/stSystemOperationsTestFiller.json b/test/stSystemOperationsTestFiller.json index 23ff8c4c3..a20fdbcaf 100644 --- a/test/stSystemOperationsTestFiller.json +++ b/test/stSystemOperationsTestFiller.json @@ -835,6 +835,40 @@ } }, + "callcodeTo0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "30000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (CALLCODE 50000 0 1 0 0 0 0) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "3000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, "CallToNameRegistratorOutOfGas": { "env" : { From 00694cb2613b1ed7837105eb79c90641aa72772a Mon Sep 17 00:00:00 2001 From: winsvega Date: Thu, 12 Mar 2015 19:34:34 +0300 Subject: [PATCH 42/49] State Tests poc9 --- test/stPreCompiledContractsFiller.json | 14 +- test/stSolidityTestFiller.json | 639 +++++++++++++++++-------- test/stSpecialTestFiller.json | 4 +- 3 files changed, 461 insertions(+), 196 deletions(-) diff --git a/test/stPreCompiledContractsFiller.json b/test/stPreCompiledContractsFiller.json index 9e5fa862a..ff0cda3f5 100644 --- a/test/stPreCompiledContractsFiller.json +++ b/test/stPreCompiledContractsFiller.json @@ -12,7 +12,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -46,7 +46,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 300000 1 0 0 128 64 32) [[ 0 ]] (MOD (MLOAD 64) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -81,7 +81,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) }", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MLOAD 128) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -217,7 +217,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code": "{ [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", + "code": "{ [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -230,7 +230,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "365224", + "gasLimit" : "3652240", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -421,7 +421,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "200000000", "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 20000000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ [[ 2 ]] (CALL 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { @@ -591,7 +591,7 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20000000", "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 500 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { diff --git a/test/stSolidityTestFiller.json b/test/stSolidityTestFiller.json index f2a2a0aa0..253a90c14 100644 --- a/test/stSolidityTestFiller.json +++ b/test/stSolidityTestFiller.json @@ -1,83 +1,24 @@ { - "SolidityTest" : { + "TestCryptographicFunctions" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "45678256", - "currentGasLimit" : "1000000000000000000000000", + "currentGasLimit" : "1000000000000000000000", "currentNumber" : "120", "currentTimestamp" : 1, "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" }, "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "code" : "", - "nonce" : "0", - "storage" : { - } - }, - - "d94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000", - "//" : " ", - "//" : "contract TestContract ", + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//" : "contract main ", "//" : "{ ", - "//" : " function testMethod() returns (int res) ", + "//" : " function run() returns (bool) ", "//" : " { ", - "//" : " return 225; ", - "//" : " } ", - "//" : " ", - "//" : " function destroy(address sendFoundsTo) ", - "//" : " { ", - "//" : " suicide(sendFoundsTo); ", - "//" : " } ", - "//" : "} ", - "//" : " ", - "//" : "contract TestSolidityContracts ", - "//" : "{ ", - "//" : "struct StructTest ", - "//" : " { ", - "//" : " address addr; ", - "//" : " int amount; ", - "//" : " string32 str; ", - "//" : " mapping (uint => address) funders; ", - "//" : " } ", - "//" : " ", - "//" : " int globalValue; ", - "//" : " StructTest globalData; ", - "//" : " function runSolidityTests() returns (hash res) ", - "//" : " { ", - "//" : " //res is a mask of failing tests given the first byte is first test ", - "//" : " res = 0x0000000000000000000000000000000000000000000000000000000000000000; ", - "//" : " ", - "//" : " createContractFromMethod(); ", - "//" : " ", - "//" : " if (!testKeywords()) ", - "//" : " res = hash(int(res) + int(0xf000000000000000000000000000000000000000000000000000000000000000)); ", - "//" : " ", - "//" : " if (!testContractInteraction()) ", - "//" : " res = hash(int(res) + int(0x0f00000000000000000000000000000000000000000000000000000000000000)); ", - "//" : " ", - "//" : " if (!testContractSuicide()) ", - "//" : " res = hash(int(res) + int(0x00f0000000000000000000000000000000000000000000000000000000000000)); ", - "//" : " ", - "//" : " if (!testBlockAndTransactionProperties()) ", - "//" : " res = hash(int(res) + int(0x000f000000000000000000000000000000000000000000000000000000000000)); ", - "//" : " ", - "//" : " globalValue = 255; ", - "//" : " globalData.addr = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ", - "//" : " globalData.amount = 255; ", - "//" : " globalData.str = 'global data 32 length string'; ", - "//" : " globalData.funders[0] = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ", - "//" : " if (!testStructuresAndVariabless()) ", - "//" : " res = hash(int(res) + int(0x0000f00000000000000000000000000000000000000000000000000000000000)); ", - "//" : " ", - "//" : " if (!testCryptographicFunctions()) ", - "//" : " res = hash(int(res) + int(0x00000f0000000000000000000000000000000000000000000000000000000000)); ", - "//" : " ", - "//" : " } ", - "//" : " ", + "//" : " return testCryptographicFunctions(); ", + "//" : " } ", + "//" : " ", "//" : " function testCryptographicFunctions() returns (bool res) ", "//" : " { ", "//" : " res = true; ", @@ -92,139 +33,463 @@ "//" : " ", "//" : " //ecrecover ", "//" : " } ", - "//" : " ", - "//" : " function testStructuresAndVariabless() returns (bool res) ", - "//" : " { ", - "//" : " res = true; ", - "//" : " if (globalValue != 255) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (globalValue != globalData.amount) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (globalData.addr != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (globalData.str != 'global data 32 length string') ", - "//" : " return false; ", - "//" : " ", - "//" : " if (globalData.funders[0] != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", - "//" : " return false; ", - "//" : " } ", - "//" : " ", - "//" : " function testBlockAndTransactionProperties() returns (bool res) ", - "//" : " { ", - "//" : " res = true; ", - "//" : " if (block.coinbase != 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (block.difficulty != 45678256) ", - "//" : " return false; ", - "//" : " ", - "//" : " //for some reason does not work 27.01.2015 ", - "//" : " if (block.gaslimit != 1000000000000000000000) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (block.number != 120) ", - "//" : " return false; ", - "//" : " ", - "//" : " //try to call this ", - "//" : " block.blockhash(120); ", - "//" : " block.timestamp; ", - "//" : " msg.gas; ", - "//" : " ", - "//" : " if (msg.sender != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (msg.value != 100) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (tx.gasprice != 1) ", - "//" : " return false; ", - "//" : " ", - "//" : " if (tx.origin != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", - "//" : " return false; ", - "//" : " ", - "//" : " } ", - "//" : " ", - "//" : " function testContractSuicide() returns (bool res) ", - "//" : " { ", - "//" : " TestContract a = new TestContract(); ", - "//" : " a.destroy(block.coinbase); ", - "//" : " if (a.testMethod() == 225) //we should be able to call a contract ", - "//" : " return true; ", - "//" : " return false; ", - "//" : " } ", - "//" : " ", - "//" : " function testContractInteraction() returns (bool res) ", - "//" : " { ", - "//" : " TestContract a = new TestContract(); ", - "//" : " if (a.testMethod() == 225) ", - "//" : " return true; ", - "//" : " return false; ", - "//" : " } ", - "//" : " ", - "//" : " function testKeywords() returns (bool res) ", - "//" : " { ", - "//" : " //some simple checks for the if statemnt ", - "//" : " //if, else, while, for, break, continue, return ", - "//" : " int i = 0; ", - "//" : " res = false; ", - "//" : " ", - "//" : " if (i == 0) ", - "//" : " { ", - "//" : " if( i <= -25) ", - "//" : " { ", - "//" : " return false; ", - "//" : " } ", - "//" : " else ", - "//" : " { ", - "//" : " while(i < 10) ", - "//" : " i++; ", - "//" : " ", - "//" : " if (i == 10) ", - "//" : " { ", - "//" : " for(var j=10; j>0; j--) ", - "//" : " { ", - "//" : " i--; ", - "//" : " } ", - "//" : " } ", - "//" : " } ", - "//" : " } ", - "//" : " ", - "//" : " if (i == 0) ", - "//" : " return true; ", - "//" : " ", - "//" : " return false; ", - "//" : " } ", - "//" : " ", - "//" : " function createContractFromMethod() returns (TestContract a) ", - "//" : " { ", - "//" : " a = new TestContract(); ", - "//" : " } ", "//" : "} ", - "code" : "0x60003560e060020a900480630c4c9a80146100635780632a9afb8314610075578063380e4396146100875780637ee17e1214610099578063a60eedda146100a7578063e0a9fd28146100b9578063e97384dc146100cb578063ed973fe9146100dd57005b61006b610473565b8060005260206000f35b61007d61064e565b8060005260206000f35b61008f61073f565b8060005260206000f35b6100a16107fe565b60006000f35b6100af6100ef565b8060005260206000f35b6100c1610196565b8060005260206000f35b6100d3610352565b8060005260206000f35b6100e56102eb565b8060005260206000f35b60006000600191506060610815600039606060006000f0905080600160a060020a031662f55d9d600060008260e060020a02600052600441600160a060020a03168152602001600060008660325a03f161014557005b505080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f161017657005b505060005160e1141561018857610191565b60009150610192565b5b5090565b60006001905060007f74657374737472696e67000000000000000000000000000000000000000000008152600a016000207f43c4b4524adb81e4e9a5c4648a98e9d320e3908ac5b6c889144b642cd08ae16d14156101f3576101fc565b600090506102e8565b60026020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a01600060008560325a03f161023a57005b506000517f3c8727e019a42b444667a587b6001251becadabbb36bfed8087a92c18882d111141561026a57610273565b600090506102e8565b60036020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a01600060008560325a03f16102b157005b50600051600160a060020a031673cd566972b5e50104011a92b59fa8e0b1234851ae14156102de576102e7565b600090506102e8565b5b90565b600060006060610815600039606060006000f0905080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f161032f57005b505060005160e11461034057610349565b6001915061034e565b600091505b5090565b60006001905041600160a060020a0316732adc25665018aa1fe0e6bc666dac8fc2697ff9ba14156103825761038b565b60009050610470565b446302b8feb0141561039c576103a5565b60009050610470565b45683635c9adc5dea0000014156103bb576103c4565b60009050610470565b43607814156103d2576103db565b60009050610470565b33600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156104055761040e565b60009050610470565b346064141561041c57610425565b60009050610470565b3a600114156104335761043c565b60009050610470565b32600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156104665761046f565b60009050610470565b5b90565b6000600090506104816107fe565b5061048a61073f565b15610494576104ba565b7ff000000000000000000000000000000000000000000000000000000000000000810190505b6104c26102eb565b156104cc576104f2565b7f0f00000000000000000000000000000000000000000000000000000000000000810190505b6104fa6100ef565b1561050457610529565b7ef0000000000000000000000000000000000000000000000000000000000000810190505b610531610352565b1561053b57610560565b7e0f000000000000000000000000000000000000000000000000000000000000810190505b60ff60008190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b60018190555060ff6002819055507f676c6f62616c2064617461203332206c656e67746820737472696e670000000060038190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b6004600060008152602001908152602001600020819055506105e761064e565b156105f157610615565b7df00000000000000000000000000000000000000000000000000000000000810190505b61061d610196565b156106275761064b565b7d0f0000000000000000000000000000000000000000000000000000000000810190505b90565b60006001905060005460ff14156106645761066d565b6000905061073c565b600254600054141561067e57610687565b6000905061073c565b600154600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156106b3576106bc565b6000905061073c565b6003547f676c6f62616c2064617461203332206c656e67746820737472696e670000000014156106eb576106f4565b6000905061073c565b600460006000815260200190815260200160002054600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156107325761073b565b6000905061073c565b5b90565b60006000600060009150600092508160001461075a576107de565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe78213156107d4575b600a821215610799578180600101925050610783565b81600a146107a6576107cf565b600a90505b60008160ff1611156107ce578180600190039250508080600190039150506107ab565b5b6107dd565b600092506107f9565b5b816000146107eb576107f4565b600192506107f9565b600092505b505090565b60006060610815600039606060006000f09050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b60276004356046565b60006000f35b6033603d565b8060005260206000f35b600060e1905090565b80600160a060020a0316ff5056", + "code" : "0x60003560e060020a90048063c040622614610021578063e0a9fd281461003357005b610029610045565b8060005260206000f35b61003b610054565b8060005260206000f35b600061004f610054565b905090565b60006001905060007f74657374737472696e67000000000000000000000000000000000000000000008152600a017f030d40000000000000000000000000000000000000000000000000000000000081526003016000207f43c4b4524adb81e4e9a5c4648a98e9d320e3908ac5b6c889144b642cd08ae16d14156100d7576100e0565b60009050610218565b60026020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a017f030d4000000000000000000000000000000000000000000000000000000000008152600301600060008560325a03f161014457005b506000517f3c8727e019a42b444667a587b6001251becadabbb36bfed8087a92c18882d11114156101745761017d565b60009050610218565b60036020600060007f74657374737472696e67000000000000000000000000000000000000000000008152600a017f030d4000000000000000000000000000000000000000000000000000000000008152600301600060008560325a03f16101e157005b50600051600160a060020a031673cd566972b5e50104011a92b59fa8e0b1234851ae141561020e57610217565b60009050610218565b5b9056", "nonce" : "0", "storage" : { - } + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "50000000", + "nonce" : "0", + "code" : "", + "storage": {} } }, + "transaction" : + { + "//" : "run()", + "data" : "0xc0406226", + "gasLimit" : "35000000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100" + } + }, + "TestStructuresAndVariabless" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000000000000", + "currentNumber" : "120", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//" : "contract main ", + "//" : "{ ", + "//" : " struct StructTest ", + "//" : " { ", + "//" : " address addr; ", + "//" : " int amount; ", + "//" : " string32 str; ", + "//" : " mapping (uint => address) funders; ", + "//" : " } ", + "//" : " ", + "//" : " int globalValue; ", + "//" : " StructTest globalData; ", + "//" : " function run() returns (bool) ", + "//" : " { ", + "//" : " globalValue = 255; ", + "//" : " globalData.addr = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ", + "//" : " globalData.amount = 255; ", + "//" : " globalData.str = 'global data 32 length string'; ", + "//" : " globalData.funders[0] = 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b; ", + "//" : " return testStructuresAndVariabless(); ", + "//" : " } ", + "//" : " ", + "//" : " function testStructuresAndVariabless() returns (bool res) ", + "//" : " { ", + "//" : " res = true; ", + "//" : " if (globalValue != 255) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalValue != globalData.amount) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalData.addr != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalData.str != 'global data 32 length string') ", + "//" : " return false; ", + "//" : " ", + "//" : " if (globalData.funders[0] != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " } ", + "//" : "} ", + "code" : "0x60003560e060020a900480632a9afb8314610021578063c04062261461003357005b610029610045565b8060005260206000f35b61003b610136565b8060005260206000f35b60006001905060005460ff141561005b57610064565b60009050610133565b60025460005414156100755761007e565b60009050610133565b600154600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b14156100aa576100b3565b60009050610133565b6003547f676c6f62616c2064617461203332206c656e67746820737472696e670000000014156100e2576100eb565b60009050610133565b600460006000815260200190815260200160002054600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b141561012957610132565b60009050610133565b5b90565b600060ff60008190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b60018190555060ff6002819055507f676c6f62616c2064617461203332206c656e67746820737472696e670000000060038190555073a94f5374fce5edbc8e2a8697c15331677e6ebf0b6004600060008152602001908152602001600020819055506101bf610045565b90509056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, "transaction" : - { - "//" : "createContractFromMethod()", - "data" : "0x7ee17e12", - "//" : "runSolidityTests()", - "data" : "0x0c4c9a80", - "gasLimit" : "15000000", + { + "//" : "run()", + "data" : "0xc0406226", + "gasLimit" : "350000", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "to" : "d94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100" } }, + "TestBlockAndTransactionProperties" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "1000000000000000000000", + "currentNumber" : "120", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//" : "contract main ", + "//" : "{ ", + "//" : " function run() returns (bool) ", + "//" : " { ", + "//" : " return testBlockAndTransactionProperties(); ", + "//" : " } ", + "//" : " ", + "//" : " function testBlockAndTransactionProperties() returns (bool res) ", + "//" : " { ", + "//" : " res = true; ", + "//" : " if (block.coinbase != 0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (block.difficulty != 45678256) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (block.gaslimit != 1000000000000000000000) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (block.number != 120) ", + "//" : " return false; ", + "//" : " ", + "//" : " //try to call this ", + "//" : " block.blockhash(120); ", + "//" : " block.timestamp; ", + "//" : " msg.gas; ", + "//" : " ", + "//" : " if (msg.sender != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (msg.value != 100) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (tx.gasprice != 1) ", + "//" : " return false; ", + "//" : " ", + "//" : " if (tx.origin != 0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b) ", + "//" : " return false; ", + "//" : " ", + "//" : " } ", + "//" : "} ", + "code" : "0x60003560e060020a90048063c040622614610021578063e97384dc1461003357005b610029610045565b8060005260206000f35b61003b610054565b8060005260206000f35b600061004f610054565b905090565b60006001905041600160a060020a0316732adc25665018aa1fe0e6bc666dac8fc2697ff9ba14156100845761008d565b60009050610172565b446302b8feb0141561009e576100a7565b60009050610172565b45683635c9adc5dea0000014156100bd576100c6565b60009050610172565b43607814156100d4576100dd565b60009050610172565b33600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b141561010757610110565b60009050610172565b346064141561011e57610127565b60009050610172565b3a600114156101355761013e565b60009050610172565b32600160a060020a031673a94f5374fce5edbc8e2a8697c15331677e6ebf0b141561016857610171565b60009050610172565b5b9056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : + { + "//" : "run()", + "data" : "0xc0406226", + "gasLimit" : "350000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100" + } + }, + + "TestContractSuicide" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "100000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//": "contract TestContract ", + "//": "{ ", + "//": " function testMethod() returns (int res) ", + "//": " { ", + "//": " return 225; ", + "//": " } ", + "//": " ", + "//": " function destroy(address sendFoundsTo) ", + "//": " { ", + "//": " suicide(sendFoundsTo); ", + "//": " } ", + "//": "} ", + "//": "contract main ", + "//": "{ ", + "//": " function run() returns (bool) ", + "//": " { ", + "//": " return testContractSuicide(); ", + "//": " } ", + "//": " ", + "//": " function testContractSuicide() returns (bool res) ", + "//": " { ", + "//": " TestContract a = new TestContract(); ", + "//": " a.destroy(block.coinbase); ", + "//": " if (a.testMethod() == 225) //we should be able to call a contract ", + "//": " return true; ", + "//": " return false; ", + "//": " } ", + "//": "} ", + "code" : "0x60003560e060020a90048063a60eedda14610021578063c04062261461003357005b610029610045565b8060005260206000f35b61003b6100eb565b8060005260206000f35b6000600060606100fb600039606060006000f0905080600160a060020a031662f55d9d600060008260e060020a02600052600441600160a060020a03168152602001600060008660325a03f161009757005b505080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f16100c857005b505060005160e1146100d9576100e2565b600191506100e7565b600091505b5090565b60006100f5610045565b9050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b60276004356046565b60006000f35b6033603d565b8060005260206000f35b600060e1905090565b80600160a060020a0316ff5056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : + { + "//" : "run()", + "data" : "0xc0406226", + "gasLimit" : "350000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + + "TestContractInteraction" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "100000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//": "contract TestContract ", + "//": "{ ", + "//": " function testMethod() returns (int res) ", + "//": " { ", + "//": " return 225; ", + "//": " } ", + "//": " ", + "//": " function destroy(address sendFoundsTo) ", + "//": " { ", + "//": " suicide(sendFoundsTo); ", + "//": " } ", + "//": "} ", + "//": "contract main ", + "//": "{ ", + "//": " function run() returns (bool) ", + "//": " { ", + "//": " return testContractInteraction(); ", + "//": " } ", + "//": " ", + "//" : " function testContractInteraction() returns (bool res) ", + "//" : " { ", + "//" : " TestContract a = new TestContract(); ", + "//" : " if (a.testMethod() == 225) ", + "//" : " return true; ", + "//" : " return false; ", + "//" : " } ", + "//": "} ", + "code" : "0x60003560e060020a90048063c040622614610021578063ed973fe91461003357005b6100296100ac565b8060005260206000f35b61003b610045565b8060005260206000f35b6000600060606100bc600039606060006000f0905080600160a060020a031663b9c3d0a5602060008260e060020a026000526004600060008660325a03f161008957005b505060005160e11461009a576100a3565b600191506100a8565b600091505b5090565b60006100b6610045565b9050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b6027600435603d565b60006000f35b6033604b565b8060005260206000f35b80600160a060020a0316ff50565b600060e190509056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : + { + "//" : "run()", + "data" : "0xc0406226", + "gasLimit" : "350000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + + "TestKeywords" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "100000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//": "contract main ", + "//": "{ ", + "//": " function run() returns (bool) ", + "//": " { ", + "//": " return testKeywords(); ", + "//": " } ", + "//": " ", + "//": " function testKeywords() returns (bool res) ", + "//": " { ", + "//": " //some simple checks for the if statemnt ", + "//": " //if, else, while, for, break, continue, return ", + "//": " int i = 0; ", + "//": " res = false; ", + "//": " ", + "//": " if (i == 0) ", + "//": " { ", + "//": " if( i <= -25) ", + "//": " { ", + "//": " return false; ", + "//": " } ", + "//": " else ", + "//": " { ", + "//": " while(i < 10) ", + "//": " i++; ", + "//": " ", + "//": " if (i == 10) ", + "//": " { ", + "//": " for(var j=10; j>0; j--) ", + "//": " { ", + "//": " i--; ", + "//": " } ", + "//": " } ", + "//": " } ", + "//": " } ", + "//": " ", + "//": " if (i == 0) ", + "//": " return true; ", + "//": " ", + "//": " return false; ", + "//": " } ", + "//": "} ", + "code" : "0x60003560e060020a90048063380e439614601f578063c040622614602f57005b6025603f565b8060005260206000f35b603560f0565b8060005260206000f35b60006000600060009150600092508160001460585760d3565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe782131560ca575b600a82121560945781806001019250506080565b81600a14609f5760c6565b600a90505b60008160ff16111560c55781806001900392505080806001900391505060a4565b5b60d2565b6000925060eb565b5b8160001460de5760e6565b6001925060eb565b600092505b505090565b600060f8603f565b90509056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : + { + "//" : "run()", + "data" : "0xc0406226", + "gasLimit" : "350000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + + "CreateContractFromMethod" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "100000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : + { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "100000", + "//": "contract TestContract ", + "//": "{ ", + "//": " function testMethod() returns (int res) ", + "//": " { ", + "//": " return 225; ", + "//": " } ", + "//": " ", + "//": " function destroy(address sendFoundsTo) ", + "//": " { ", + "//": " suicide(sendFoundsTo); ", + "//": " } ", + "//": "} ", + "//": " ", + "//": "contract main ", + "//": "{ ", + "//": " function run() returns (uint) ", + "//": " { ", + "//": " createContractFromMethod(); ", + "//": " } ", + "//": " ", + "//": " function createContractFromMethod() returns (TestContract a) ", + "//": " { ", + "//": " a = new TestContract(); ", + "//": " } ", + "//": "} ", + "code" : "0x60003560e060020a900480637ee17e1214601f578063c040622614602b57005b60256047565b60006000f35b6031603b565b8060005260206000f35b600060436047565b5090565b60006060605d600039606060006000f09050905600605480600c6000396000f30060003560e060020a90048062f55d9d14601e578063b9c3d0a514602d57005b60276004356046565b60006000f35b6033603d565b8060005260206000f35b600060e1905090565b80600160a060020a0316ff5056", + "nonce" : "0", + "storage" : { + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : + { + "//" : "run()", + "data" : "0xc0406226", + "gasLimit" : "350000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "1" + } + }, + "CallLowLevelCreatesSolidity" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", diff --git a/test/stSpecialTestFiller.json b/test/stSpecialTestFiller.json index 223d9f75f..b6552923f 100644 --- a/test/stSpecialTestFiller.json +++ b/test/stSpecialTestFiller.json @@ -22,7 +22,7 @@ "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "100000", + "balance" : "1000000", "nonce" : "0", "code" : "", "storage": {} @@ -31,7 +31,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "22850", + "gasLimit" : "228500", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "10", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", From ba4f413b8792590732115f77d6a0f11ca7174e1a Mon Sep 17 00:00:00 2001 From: winsvega Date: Fri, 13 Mar 2015 17:46:38 +0300 Subject: [PATCH 43/49] State Tests stSystemOperations poc9 --- test/stSystemOperationsTestFiller.json | 80 +++++++++++++------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/test/stSystemOperationsTestFiller.json b/test/stSystemOperationsTestFiller.json index 23ff8c4c3..bb4484961 100644 --- a/test/stSystemOperationsTestFiller.json +++ b/test/stSystemOperationsTestFiller.json @@ -3,7 +3,7 @@ "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "currentNumber" : "0", - "currentGasLimit" : "1000000", + "currentGasLimit" : "100000000", "currentDifficulty" : "256", "currentTimestamp" : 1, "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" @@ -25,7 +25,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -60,7 +60,7 @@ }, "transaction" : { "data" : "", - "gasLimit" : "30000", + "gasLimit" : "300000", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -95,7 +95,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -129,7 +129,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -163,7 +163,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -197,7 +197,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -232,7 +232,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -257,7 +257,7 @@ "storage": {} }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "100000", + "balance" : "1000000", "nonce" : "0", "code" : "", "storage": {} @@ -266,7 +266,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -300,7 +300,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -334,7 +334,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -368,7 +368,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -452,7 +452,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -494,7 +494,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -536,7 +536,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -578,7 +578,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -619,7 +619,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -660,7 +660,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -701,7 +701,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -743,7 +743,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -785,7 +785,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -870,7 +870,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -911,7 +911,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -952,7 +952,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -993,7 +993,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1035,7 +1035,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1076,7 +1076,7 @@ "transaction" : { "nonce" : "0", "gasPrice" : "1", - "gasLimit" : "30000", + "gasLimit" : "300000", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", "value" : "100000", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1894,12 +1894,12 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", + "code" : "{ [[ (PC) ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : " { [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ", + "code" : " { [[ (PC) ]] (ADD 1 (CALL 50000 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ", "nonce" : "0", "storage" : { } @@ -1935,12 +1935,12 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "{ [[ (PC) ]] (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", + "code" : "{ [[ (PC) ]] (CALL (- (GAS) 100000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : " { [[ (PC) ]] (ADD 1 (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ", + "code" : " { [[ (PC) ]] (ADD 1 (CALL (- (GAS) 100000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ", "nonce" : "0", "storage" : { } @@ -1976,12 +1976,12 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", + "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "0", - "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ", + "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ", "nonce" : "0", "storage" : { } @@ -2017,12 +2017,12 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1025000", "nonce" : "0", - "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", + "code" : "{ [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x945304eb96065b2a98b57a48a06ae28d285a71b5 1 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "0", - "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 1000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ", + "code" : " { [[ 0 ]] (ADD (SLOAD 0) 1) (CALL (- (GAS) 100000) 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 0 0 0 0 0) } ", "nonce" : "0", "storage" : { } @@ -2058,12 +2058,12 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) (SUICIDE 0x945304eb96065b2a98b57a48a06ae28d285a71b5) }", + "code" : "{ [[ (PC) ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) (SUICIDE 0x945304eb96065b2a98b57a48a06ae28d285a71b5) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "{ [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ", + "code" : "{ [[ (PC) ]] (ADD 1 (CALL 50000 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) } ", "nonce" : "0", "storage" : { } @@ -2099,12 +2099,12 @@ "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "1000000000000000000", "nonce" : "0", - "code" : "{ [[ (PC) ]] (CALL 1000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", + "code" : "{ [[ (PC) ]] (CALL 100000 0x945304eb96065b2a98b57a48a06ae28d285a71b5 24 0 0 0 0) }", "storage": {} }, "945304eb96065b2a98b57a48a06ae28d285a71b5" : { "balance" : "23", - "code" : "{ [[ (PC) ]] (ADD 1 (CALL 500 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) (SUICIDE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6) } ", + "code" : "{ [[ (PC) ]] (ADD 1 (CALL 50000 0x095e7baea6a6c7c4c2dfeb977efac326af552d87 23 0 0 0 0)) (SUICIDE 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6) } ", "nonce" : "0", "storage" : { } From a8d84b0d86261b01ef5fc5f6282b68dd6be6d07a Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 14 Mar 2015 19:00:41 +0100 Subject: [PATCH 44/49] getData -> getCode. --- libjsqrc/CMakeLists.txt | 6 ++++++ libjsqrc/ethereumjs/lib/web3/eth.js | 2 +- libweb3jsonrpc/WebThreeStubServerBase.cpp | 2 +- libweb3jsonrpc/WebThreeStubServerBase.h | 2 +- libweb3jsonrpc/abstractwebthreestubserver.h | 6 +++--- test/webthreestubclient.h | 4 ++-- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/libjsqrc/CMakeLists.txt b/libjsqrc/CMakeLists.txt index 6554e523d..e5da5c4ee 100644 --- a/libjsqrc/CMakeLists.txt +++ b/libjsqrc/CMakeLists.txt @@ -23,3 +23,9 @@ if (USENPM) endif() install( TARGETS jsqrc RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) + +file(GLOB_RECURSE SOLFILES "ethereumjs/lib/solidity/*.js") +file(GLOB_RECURSE UTILSFILES "ethereumjs/lib/utils/*.js") +file(GLOB_RECURSE WEB3FILES "ethereumjs/lib/web3/*.js") +add_custom_target(aux_js SOURCES ${SOLFILES} ${UTILSFILES} ${WEB3FILES}) + diff --git a/libjsqrc/ethereumjs/lib/web3/eth.js b/libjsqrc/ethereumjs/lib/web3/eth.js index cdf245198..9b13eccdb 100644 --- a/libjsqrc/ethereumjs/lib/web3/eth.js +++ b/libjsqrc/ethereumjs/lib/web3/eth.js @@ -77,7 +77,7 @@ var methods = [ { name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2}, { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3, inputFormatter: utils.toHex}, - { name: 'getData', call: 'eth_getData', addDefaultblock: 2}, + { name: 'getCode', call: 'eth_getCode', addDefaultblock: 2}, { name: 'getBlock', call: blockCall, outputFormatter: formatters.outputBlockFormatter, inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]}, diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 11f4da3ec..d0cb9c72f 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -435,7 +435,7 @@ string WebThreeStubServerBase::eth_getUncleCountByBlockNumber(string const& _blo return toJS(client()->uncleCount(client()->hashFromNumber(number))); } -string WebThreeStubServerBase::eth_getData(string const& _address, string const& _blockNumber) +string WebThreeStubServerBase::eth_getCode(string const& _address, string const& _blockNumber) { Address address; int number; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index c71d7ee30..9914d071e 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -87,7 +87,7 @@ public: virtual std::string eth_getBlockTransactionCountByNumber(std::string const& _blockNumber); virtual std::string eth_getUncleCountByBlockHash(std::string const& _blockHash); virtual std::string eth_getUncleCountByBlockNumber(std::string const& _blockNumber); - virtual std::string eth_getData(std::string const& _address, std::string const& _blockNumber); + virtual std::string eth_getCode(std::string const& _address, std::string const& _blockNumber); virtual std::string eth_sendTransaction(Json::Value const& _json); virtual std::string eth_call(Json::Value const& _json, std::string const& _blockNumber); virtual bool eth_flush(); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index cc326183d..6d84571a1 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -30,7 +30,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByNumberI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockHashI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockNumberI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_getData", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getDataI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getCode", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getDataI); this->bindAndAddMethod(jsonrpc::Procedure("eth_sendTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_sendTransactionI); this->bindAndAddMethod(jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_callI); this->bindAndAddMethod(jsonrpc::Procedure("eth_flush", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_flushI); @@ -152,7 +152,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_getData(request[0u].asString(), request[1u].asString()); + response = this->eth_getCode(request[0u].asString(), request[1u].asString()); } inline virtual void eth_sendTransactionI(const Json::Value &request, Json::Value &response) { @@ -320,7 +320,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_getData",p); + Json::Value result = this->CallMethod("eth_getCode",p); if (result.isString()) return result.asString(); else From 4495de33312c3f14958b6c48c4f845fa98c1b017 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 14 Mar 2015 19:59:07 +0100 Subject: [PATCH 45/49] Renaming getData -> getCode, remove getStorage, fix a bunch of JSONRPC methods with more expansive error handling. --- libjsqrc/CMakeLists.txt | 6 +- libjsqrc/ethereumjs/dist/ethereum.js | 3 +- libjsqrc/ethereumjs/lib/web3/eth.js | 1 - libweb3jsonrpc/CMakeLists.txt | 1 + libweb3jsonrpc/WebThreeStubServerBase.cpp | 79 +++------------------ libweb3jsonrpc/WebThreeStubServerBase.h | 1 - libweb3jsonrpc/abstractwebthreestubserver.h | 10 +-- libweb3jsonrpc/spec.json | 3 +- test/webthreestubclient.h | 11 --- 9 files changed, 15 insertions(+), 100 deletions(-) diff --git a/libjsqrc/CMakeLists.txt b/libjsqrc/CMakeLists.txt index e5da5c4ee..4e849de12 100644 --- a/libjsqrc/CMakeLists.txt +++ b/libjsqrc/CMakeLists.txt @@ -24,8 +24,6 @@ endif() install( TARGETS jsqrc RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) -file(GLOB_RECURSE SOLFILES "ethereumjs/lib/solidity/*.js") -file(GLOB_RECURSE UTILSFILES "ethereumjs/lib/utils/*.js") -file(GLOB_RECURSE WEB3FILES "ethereumjs/lib/web3/*.js") -add_custom_target(aux_js SOURCES ${SOLFILES} ${UTILSFILES} ${WEB3FILES}) +file(GLOB_RECURSE JSFILES "ethereumjs/lib/*.js") +add_custom_target(aux_js SOURCES ${JSFILES}) diff --git a/libjsqrc/ethereumjs/dist/ethereum.js b/libjsqrc/ethereumjs/dist/ethereum.js index 88a5180a9..725ef476d 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js +++ b/libjsqrc/ethereumjs/dist/ethereum.js @@ -1706,7 +1706,6 @@ var uncleCountCall = function (args) { var methods = [ { name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2, outputFormatter: formatters.convertToBigNumber}, - { name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2}, { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3, inputFormatter: utils.toHex}, { name: 'getData', call: 'eth_getData', addDefaultblock: 2}, @@ -2831,4 +2830,4 @@ module.exports = web3; },{"./lib/solidity/abi":1,"./lib/web3":6,"./lib/web3/contract":7,"./lib/web3/httpprovider":13,"./lib/web3/qtsync":16}]},{},["web3"]) -//# sourceMappingURL=ethereum.js.map \ No newline at end of file +//# sourceMappingURL=ethereum.js.map diff --git a/libjsqrc/ethereumjs/lib/web3/eth.js b/libjsqrc/ethereumjs/lib/web3/eth.js index 9b13eccdb..2875aa94e 100644 --- a/libjsqrc/ethereumjs/lib/web3/eth.js +++ b/libjsqrc/ethereumjs/lib/web3/eth.js @@ -74,7 +74,6 @@ var uncleCountCall = function (args) { var methods = [ { name: 'getBalance', call: 'eth_getBalance', addDefaultblock: 2, outputFormatter: formatters.convertToBigNumber}, - { name: 'getStorage', call: 'eth_getStorage', addDefaultblock: 2}, { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3, inputFormatter: utils.toHex}, { name: 'getCode', call: 'eth_getCode', addDefaultblock: 2}, diff --git a/libweb3jsonrpc/CMakeLists.txt b/libweb3jsonrpc/CMakeLists.txt index b445f77ff..d3f4b70b6 100644 --- a/libweb3jsonrpc/CMakeLists.txt +++ b/libweb3jsonrpc/CMakeLists.txt @@ -56,4 +56,5 @@ endif() install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) +add_custom_target(aux_json SOURCES "spec.json") diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index d0cb9c72f..0434d1e76 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -295,162 +295,99 @@ string WebThreeStubServerBase::eth_blockNumber() string WebThreeStubServerBase::eth_getBalance(string const& _address, string const& _blockNumber) { - Address address; - int number; - - try - { - address = jsToAddress(_address); - number = toBlockNumber(_blockNumber); - } - catch (...) - { - BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); - } - - return toJS(client()->balanceAt(address, number)); -} - - -Json::Value WebThreeStubServerBase::eth_getStorage(string const& _address, string const& _blockNumber) -{ - Address address; - int number; - try { - address = jsToAddress(_address); - number = toBlockNumber(_blockNumber); + return toJS(client()->balanceAt(jsToAddress(_address), toBlockNumber(_blockNumber))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - //TODO: fix this naming ! - return toJson(client()->storageAt(address, number)); } string WebThreeStubServerBase::eth_getStorageAt(string const& _address, string const& _position, string const& _blockNumber) { - Address address; - u256 position; - int number; - try { - address = jsToAddress(_address); - position = jsToU256(_position); - number = toBlockNumber(_blockNumber); + return toJS(client()->stateAt(jsToAddress(_address), jsToU256(_position), toBlockNumber(_blockNumber))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - //TODO: fix this naming ! - return toJS(client()->stateAt(address, position, number)); } string WebThreeStubServerBase::eth_getTransactionCount(string const& _address, string const& _blockNumber) { - Address address; - int number; - try { - address = jsToAddress(_address); - number = toBlockNumber(_blockNumber); + return toJS(client()->countAt(jsToAddress(_address), toBlockNumber(_blockNumber))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - return toJS(client()->countAt(address, number)); } string WebThreeStubServerBase::eth_getBlockTransactionCountByHash(string const& _blockHash) { - h256 hash; - try { - hash = jsToFixed<32>(_blockHash); + return toJS(client()->transactionCount(jsToFixed<32>(_blockHash))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - return toJS(client()->transactionCount(hash)); } string WebThreeStubServerBase::eth_getBlockTransactionCountByNumber(string const& _blockNumber) { - int number; - try { - number = toBlockNumber(_blockNumber); + return toJS(client()->transactionCount(client()->hashFromNumber(toBlockNumber(_blockNumber)))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - return toJS(client()->transactionCount(client()->hashFromNumber(number))); } string WebThreeStubServerBase::eth_getUncleCountByBlockHash(string const& _blockHash) { - h256 hash; - try { - hash = jsToFixed<32>(_blockHash); + return toJS(client()->uncleCount(jsToFixed<32>(_blockHash))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - return toJS(client()->uncleCount(hash)); } string WebThreeStubServerBase::eth_getUncleCountByBlockNumber(string const& _blockNumber) { - int number; - try { - number = toBlockNumber(_blockNumber); + return toJS(client()->uncleCount(client()->hashFromNumber(toBlockNumber(_blockNumber)))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - return toJS(client()->uncleCount(client()->hashFromNumber(number))); } string WebThreeStubServerBase::eth_getCode(string const& _address, string const& _blockNumber) { - Address address; - int number; - try { - address = jsToAddress(_address); - number = toBlockNumber(_blockNumber); + return toJS(client()->codeAt(jsToAddress(_address), toBlockNumber(_blockNumber))); } catch (...) { BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); } - - return toJS(client()->codeAt(address, number)); } static TransactionSkeleton toTransaction(Json::Value const& _json) diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 9914d071e..214573e0d 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -80,7 +80,6 @@ public: virtual Json::Value eth_accounts(); virtual std::string eth_blockNumber(); virtual std::string eth_getBalance(std::string const& _address, std::string const& _blockNumber); - virtual Json::Value eth_getStorage(std::string const& _address, std::string const& _blockNumber); virtual std::string eth_getStorageAt(std::string const& _address, std::string const& _position, std::string const& _blockNumber); virtual std::string eth_getTransactionCount(std::string const& _address, std::string const& _blockNumber); virtual std::string eth_getBlockTransactionCountByHash(std::string const& _blockHash); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 6d84571a1..516817d5c 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -23,14 +23,13 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_accounts", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_accountsI); this->bindAndAddMethod(jsonrpc::Procedure("eth_blockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_blockNumberI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getBalance", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBalanceI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_getStorage", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getStorageI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getStorageAt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getStorageAtI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionCount", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionCountI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByHashI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getBlockTransactionCountByNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getBlockTransactionCountByNumberI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockHashI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleCountByBlockNumber", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleCountByBlockNumberI); - this->bindAndAddMethod(jsonrpc::Procedure("eth_getCode", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getDataI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getCode", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getCodeI); this->bindAndAddMethod(jsonrpc::Procedure("eth_sendTransaction", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_sendTransactionI); this->bindAndAddMethod(jsonrpc::Procedure("eth_call", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_OBJECT,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_callI); this->bindAndAddMethod(jsonrpc::Procedure("eth_flush", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, NULL), &AbstractWebThreeStubServer::eth_flushI); @@ -122,10 +121,6 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_getBalance(request[0u].asString(), request[1u].asString()); } - inline virtual void eth_getStorageI(const Json::Value &request, Json::Value &response) - { - response = this->eth_getStorage(request[0u].asString(), request[1u].asString()); - } inline virtual void eth_getStorageAtI(const Json::Value &request, Json::Value &response) { response = this->eth_getStorageAt(request[0u].asString(), request[1u].asString(), request[2u].asString()); @@ -150,7 +145,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_getUncleCountByBlockNumber(request[0u].asString()); } - inline virtual void eth_getDataI(const Json::Value &request, Json::Value &response) + inline virtual void eth_getCodeI(const Json::Value &request, Json::Value &response) { response = this->eth_getCode(request[0u].asString(), request[1u].asString()); } @@ -313,7 +308,6 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerCallMethod("eth_getStorage",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) { Json::Value p; From 2121dd1e27b9d67eac2bdd05271c8c651ebcdfe0 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 14 Mar 2015 20:01:59 +0100 Subject: [PATCH 46/49] Fixes for getCode. --- libjsqrc/ethereumjs/dist/ethereum.js | 4 ++-- libjsqrc/ethereumjs/lib/web3/eth.js | 2 +- libjsqrc/ethereumjs/test/eth.methods.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libjsqrc/ethereumjs/dist/ethereum.js b/libjsqrc/ethereumjs/dist/ethereum.js index 7adfa28ca..4ae476ca5 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js +++ b/libjsqrc/ethereumjs/dist/ethereum.js @@ -1728,7 +1728,7 @@ var methods = [ outputFormatter: formatters.convertToBigNumber}, { name: 'getStorageAt', call: 'eth_getStorageAt', addDefaultblock: 3, inputFormatter: utils.toHex}, - { name: 'getData', call: 'eth_getData', addDefaultblock: 2}, + { name: 'getCode', call: 'eth_getCode', addDefaultblock: 2}, { name: 'getBlock', call: blockCall, outputFormatter: formatters.outputBlockFormatter, inputFormatter: [utils.toHex, function(param){ return (!param) ? false : true; }]}, @@ -1763,7 +1763,7 @@ var methods = [ { name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' }, { name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' }, { name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' }, - { name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getData' }, + { name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getCode' }, { name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' }, { name: 'block', call: blockCall, newMethod: 'eth.getBlock' }, { name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' }, diff --git a/libjsqrc/ethereumjs/lib/web3/eth.js b/libjsqrc/ethereumjs/lib/web3/eth.js index 4ea5b1886..cfb4280e0 100644 --- a/libjsqrc/ethereumjs/lib/web3/eth.js +++ b/libjsqrc/ethereumjs/lib/web3/eth.js @@ -112,7 +112,7 @@ var methods = [ { name: 'stateAt', call: 'eth_stateAt', newMethod: 'eth.getStorageAt' }, { name: 'storageAt', call: 'eth_storageAt', newMethod: 'eth.getStorage' }, { name: 'countAt', call: 'eth_countAt', newMethod: 'eth.getTransactionCount' }, - { name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getData' }, + { name: 'codeAt', call: 'eth_codeAt', newMethod: 'eth.getCode' }, { name: 'transact', call: 'eth_transact', newMethod: 'eth.sendTransaction' }, { name: 'block', call: blockCall, newMethod: 'eth.getBlock' }, { name: 'transaction', call: transactionFromBlockCall, newMethod: 'eth.getTransaction' }, diff --git a/libjsqrc/ethereumjs/test/eth.methods.js b/libjsqrc/ethereumjs/test/eth.methods.js index e1eea1ec4..7fb8d3b24 100644 --- a/libjsqrc/ethereumjs/test/eth.methods.js +++ b/libjsqrc/ethereumjs/test/eth.methods.js @@ -8,7 +8,7 @@ describe('web3', function() { u.methodExists(web3.eth, 'getStorageAt'); u.methodExists(web3.eth, 'getStorage'); u.methodExists(web3.eth, 'getTransactionCount'); - u.methodExists(web3.eth, 'getData'); + u.methodExists(web3.eth, 'getCode'); u.methodExists(web3.eth, 'sendTransaction'); u.methodExists(web3.eth, 'call'); u.methodExists(web3.eth, 'getBlock'); From 53b50a1213ad64de85774183105e123632aa0397 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 14 Mar 2015 20:13:10 +0100 Subject: [PATCH 47/49] Avoid accidentally reaping properly managed watches. --- alethzero/MainWin.cpp | 2 +- libethereum/Client.cpp | 10 +++++----- libethereum/Client.h | 6 +++--- libethereum/Interface.h | 10 ++++++++-- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index a6ef485df..5d4f9770e 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -263,7 +263,7 @@ unsigned Main::installWatch(LogFilter const& _tf, WatchHandler const& _f) unsigned Main::installWatch(dev::h256 _tf, WatchHandler const& _f) { - auto ret = ethereum()->installWatch(_tf); + auto ret = ethereum()->installWatch(_tf, Reaping::Manual); m_handlers[ret] = _f; return ret; } diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index f46d0d3c9..9d7ecb605 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -249,13 +249,13 @@ void Client::clearPending() noteChanged(changeds); } -unsigned Client::installWatch(h256 _h) +unsigned Client::installWatch(h256 _h, Reaping _r) { unsigned ret; { Guard l(m_filterLock); ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0; - m_watches[ret] = ClientWatch(_h); + m_watches[ret] = ClientWatch(_h, _r); cwatch << "+++" << ret << _h.abridged(); } auto ch = logs(ret); @@ -268,7 +268,7 @@ unsigned Client::installWatch(h256 _h) return ret; } -unsigned Client::installWatch(LogFilter const& _f) +unsigned Client::installWatch(LogFilter const& _f, Reaping _r) { h256 h = _f.sha3(); { @@ -279,7 +279,7 @@ unsigned Client::installWatch(LogFilter const& _f) m_filters.insert(make_pair(h, _f)); } } - return installWatch(h); + return installWatch(h, _r); } bool Client::uninstallWatch(unsigned _i) @@ -692,7 +692,7 @@ void Client::doWork() { Guard l(m_filterLock); for (auto key: keysOf(m_watches)) - if (chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20)) + if (m_watches[key].lastPoll != chrono::system_clock::time_point::max() && chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20)) { toUninstall.push_back(key); cnote << "GC: Uninstall" << key << "(" << chrono::duration_cast(chrono::system_clock::now() - m_watches[key].lastPoll).count() << "s old)"; diff --git a/libethereum/Client.h b/libethereum/Client.h index 04798ecdb..02d8ef6f8 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -92,7 +92,7 @@ static const LocalisedLogEntry InitialChange(SpecialLogEntry, 0); struct ClientWatch { ClientWatch(): lastPoll(std::chrono::system_clock::now()) {} - explicit ClientWatch(h256 _id): id(_id), lastPoll(std::chrono::system_clock::now()) {} + explicit ClientWatch(h256 _id, Reaping _r): id(_id), lastPoll(_r == Reaping::Automatic ? std::chrono::system_clock::now() : std::chrono::system_clock::time_point::max()) {} h256 id; LocalisedLogEntries changes = LocalisedLogEntries{ InitialChange }; @@ -246,8 +246,8 @@ public: virtual bytes codeAt(Address _a, int _block) const; virtual std::map storageAt(Address _a, int _block) const; - virtual unsigned installWatch(LogFilter const& _filter) override; - virtual unsigned installWatch(h256 _filterId) override; + virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) override; + virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) override; virtual bool uninstallWatch(unsigned _watchId) override; virtual LocalisedLogEntries peekWatch(unsigned _watchId) const; virtual LocalisedLogEntries checkWatch(unsigned _watchId); diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 728cb5030..abf7c0a2d 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -39,6 +39,12 @@ namespace eth using TransactionHashes = h256s; +enum class Reaping +{ + Automatic, + Manual +}; + /** * @brief Main API hub for interfacing with Ethereum. */ @@ -92,8 +98,8 @@ public: virtual LocalisedLogEntries logs(LogFilter const& _filter) const = 0; /// Install, uninstall and query watches. - virtual unsigned installWatch(LogFilter const& _filter) = 0; - virtual unsigned installWatch(h256 _filterId) = 0; + virtual unsigned installWatch(LogFilter const& _filter, Reaping _r = Reaping::Automatic) = 0; + virtual unsigned installWatch(h256 _filterId, Reaping _r = Reaping::Automatic) = 0; virtual bool uninstallWatch(unsigned _watchId) = 0; LocalisedLogEntries peekWatchSafe(unsigned _watchId) const { try { return peekWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } } LocalisedLogEntries checkWatchSafe(unsigned _watchId) { try { return checkWatch(_watchId); } catch (...) { return LocalisedLogEntries(); } } From 1e0201142f1e581a0d1c616f98091cc2e12dc85e Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 14 Mar 2015 20:15:15 +0100 Subject: [PATCH 48/49] Mix fix for previous commit. --- mix/MixClient.cpp | 10 ++++++---- mix/MixClient.h | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index a8619f843..e088a093b 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -40,6 +40,8 @@ namespace dev namespace mix { +// TODO: merge as much as possible with the Client.cpp into a mutually inherited base class. + const Secret c_defaultUserAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074"); const u256 c_mixGenesisDifficulty = c_minimumDifficulty; //TODO: make it lower for Mix somehow @@ -360,13 +362,13 @@ eth::LocalisedLogEntries MixClient::logs(eth::LogFilter const& _f) const return ret; } -unsigned MixClient::installWatch(h256 _h) +unsigned MixClient::installWatch(h256 _h, eth::Reaping _r) { unsigned ret; { Guard l(m_filterLock); ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0; - m_watches[ret] = ClientWatch(_h); + m_watches[ret] = ClientWatch(_h, _r); } auto ch = logs(ret); if (ch.empty()) @@ -378,14 +380,14 @@ unsigned MixClient::installWatch(h256 _h) return ret; } -unsigned MixClient::installWatch(eth::LogFilter const& _f) +unsigned MixClient::installWatch(eth::LogFilter const& _f, eth::Reaping _r) { h256 h = _f.sha3(); { Guard l(m_filterLock); m_filters.insert(std::make_pair(h, _f)); } - return installWatch(h); + return installWatch(h, _r); } bool MixClient::uninstallWatch(unsigned _i) diff --git a/mix/MixClient.h b/mix/MixClient.h index ff85d6458..af5c8ec2b 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -60,8 +60,8 @@ public: std::map storageAt(Address _a, int _block) const override; eth::LocalisedLogEntries logs(unsigned _watchId) const override; eth::LocalisedLogEntries logs(eth::LogFilter const& _filter) const override; - unsigned installWatch(eth::LogFilter const& _filter) override; - unsigned installWatch(h256 _filterId) override; + unsigned installWatch(eth::LogFilter const& _filter, eth::Reaping _r = eth::Reaping::Automatic) override; + unsigned installWatch(h256 _filterId, eth::Reaping _r = eth::Reaping::Automatic) override; bool uninstallWatch(unsigned _watchId) override; eth::LocalisedLogEntries peekWatch(unsigned _watchId) const override; eth::LocalisedLogEntries checkWatch(unsigned _watchId) override; From 6531981a734befb4c042082838be15ef2d4dfc05 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Mon, 16 Mar 2015 10:07:57 +0100 Subject: [PATCH 49/49] Wanrings fixes and a cleanup. --- alethzero/DappLoader.cpp | 2 +- libdevcore/Common.h | 1 + libethereum/BlockChain.cpp | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp index 41ac22b23..6482b691d 100644 --- a/alethzero/DappLoader.cpp +++ b/alethzero/DappLoader.cpp @@ -69,7 +69,7 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri) while (address && partIndex < parts.length()) { lastAddress = address; - string32 name = { 0 }; + string32 name = ZeroString32; QByteArray utf8 = parts[partIndex].toUtf8(); std::copy(utf8.data(), utf8.data() + utf8.size(), name.data()); address = abiOut
(web3()->ethereum()->call(address, abiIn("addr(string32)", name))); diff --git a/libdevcore/Common.h b/libdevcore/Common.h index b82cb827e..90b51627e 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -87,6 +87,7 @@ using strings = std::vector; // Fixed-length string types. using string32 = std::array; +static const string32 ZeroString32 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // Null/Invalid values for convenience. static const u256 Invalid256 = ~(u256)0; diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 19a16d193..00ede9054 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -610,8 +610,8 @@ void BlockChain::checkConsistency() static inline unsigned upow(unsigned a, unsigned b) { while (b-- > 0) a *= a; return a; } static inline unsigned ceilDiv(unsigned n, unsigned d) { return n / (n + d - 1); } -static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, b); } -static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return ceilDiv(n, upow(a, b)); } +//static inline unsigned floorDivPow(unsigned n, unsigned a, unsigned b) { return n / upow(a, b); } +//static inline unsigned ceilDivPow(unsigned n, unsigned a, unsigned b) { return ceilDiv(n, upow(a, b)); } // Level 1 // [xxx. ]