diff --git a/CMakeLists.txt b/CMakeLists.txt index 289cecad8..aafdad099 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ option(USENPM "Use npm to recompile ethereum.js if it was changed" OFF) option(PROFILING "Build in support for profiling" OFF) set(BUNDLE "none" CACHE STRING "Predefined bundle of software to build (none, full, user, tests, minimal).") +option(MINER "Build the miner component" ON) option(SOLIDITY "Build the Solidity language components" ON) option(SERPENT "Build the Serpent language components" ON) option(TOOLS "Build the tools components" ON) @@ -187,6 +188,7 @@ eth_format_option(VMTRACE) eth_format_option(EVMJIT) eth_format_option(FATDB) eth_format_option(JSONRPC) +eth_format_option(MINER) eth_format_option(USENPM) eth_format_option(PROFILING) eth_format_option(SOLIDITY) @@ -249,6 +251,16 @@ elseif (BUNDLE STREQUAL "user") set(NCURSES ${DECENT_PLATFORM}) set(TOOLS ON) set(TESTS OFF) +elseif (BUNDLE STREQUAL "miner") + set(SERPENT OFF) + set(SOLIDITY OFF) + set(USENPM OFF) + set(GUI OFF) + set(NCURSES OFF) + set(TOOLS OFF) + set(TESTS OFF) + set(MINER ON) + set(ETHASHCL ON) endif () # Default CMAKE_BUILD_TYPE to "Release". @@ -283,6 +295,7 @@ message("-- FATDB Full database exploring ${FATDB}") message("-- JSONRPC JSON-RPC support ${JSONRPC}") message("-- USENPM Javascript source building ${USENPM}") message("------------------------------------------------------------- components") +message("-- MINER Build miner ${MINER}") message("-- TOOLS Build basic tools ${TOOLS}") message("-- SOLIDITY Build Solidity language components ${SOLIDITY}") message("-- SERPENT Build Serpent language components ${SERPENT}") @@ -310,10 +323,20 @@ if (EVMJIT) add_subdirectory(evmjit) endif() +if (TOOLS OR GUI OR SOLIDITY OR NCURSES OR TESTS) + set(GENERAL 1) +else () + set(GENERAL 0) +endif () + +message("GENERAL ${GENERAL}") + add_subdirectory(libdevcore) -add_subdirectory(libevmcore) -add_subdirectory(libevmasm) -add_subdirectory(liblll) +if (GENERAL) + add_subdirectory(libevmcore) + add_subdirectory(libevmasm) + add_subdirectory(liblll) +endif () if (SERPENT) add_subdirectory(libserpent) @@ -329,31 +352,43 @@ if (TOOLS) if (SOLIDITY) add_subdirectory(solc) endif () -endif() +endif () -if (JSONRPC) +if (JSONRPC AND GENERAL) add_subdirectory(libweb3jsonrpc) -endif() +endif () if (JSCONSOLE) add_subdirectory(libjsengine) add_subdirectory(libjsconsole) -endif() +endif () add_subdirectory(secp256k1) -add_subdirectory(libp2p) add_subdirectory(libdevcrypto) -add_subdirectory(libwhisper) -add_subdirectory(libethash) -if (ETHASHCL) - add_subdirectory(libethash-cl) +if (GENERAL) + add_subdirectory(libp2p) + add_subdirectory(libwhisper) +endif () + +if (GENERAL OR MINER) + add_subdirectory(libethash) + if (ETHASHCL) + add_subdirectory(libethash-cl) + endif () endif () add_subdirectory(libethcore) -add_subdirectory(libevm) -add_subdirectory(libethereum) -add_subdirectory(libwebthree) + +if (GENERAL) + add_subdirectory(libevm) + add_subdirectory(libethereum) + add_subdirectory(libwebthree) +endif () + +if (MINER) + add_subdirectory(ethminer) +endif () if (TESTS) add_subdirectory(libtestutils) @@ -367,7 +402,6 @@ if (TOOLS) add_subdirectory(rlp) add_subdirectory(abi) - add_subdirectory(ethminer) add_subdirectory(eth) if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") diff --git a/abi/main.cpp b/abi/main.cpp index 27c5eea1b..df7fa8811 100644 --- a/abi/main.cpp +++ b/abi/main.cpp @@ -26,7 +26,7 @@ #include "../test/JsonSpiritHeaders.h" #include #include -#include +#include #include using namespace std; using namespace dev; diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp index a91beb2f7..b2249ae5b 100644 --- a/alethzero/DappLoader.cpp +++ b/alethzero/DappLoader.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/alethzero/DownloadView.cpp b/alethzero/DownloadView.cpp index 009e2dc83..210649edb 100644 --- a/alethzero/DownloadView.cpp +++ b/alethzero/DownloadView.cpp @@ -52,7 +52,10 @@ void DownloadView::paintEvent(QPaintEvent*) QPointF pos(0, 0); auto bg = m_man->blocksGot(); - + unsigned subCount = m_man->subCount(); + if (subCount == 0) + return; + unsigned dh = 360 / subCount; for (unsigned i = bg.all().first, ei = bg.all().second; i < ei; ++i) { int s = -2; @@ -68,7 +71,6 @@ void DownloadView::paintEvent(QPaintEvent*) h++; }); } - unsigned dh = 360 / m_man->subCount(); if (s == -2) p.fillRect(QRectF(QPointF(pos) + QPointF(3 * area.width() / 8, 3 * area.height() / 8), area / 4), Qt::black); else if (s == -1) diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 5b0ad7582..b5e22409d 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -151,6 +151,7 @@ + @@ -184,6 +185,7 @@ + @@ -1727,6 +1729,22 @@ font-size: 14pt In&ject Block + + + Prepare Next &DAG + + + + + true + + + true + + + Co&nfirm Transactions + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 87c9c2dc9..07f48c0bc 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -44,7 +44,7 @@ #include #include #endif -#include +#include #include #include #include @@ -204,7 +204,7 @@ Main::Main(QWidget *parent) : QSettings s("ethereum", "alethzero"); m_networkConfig = s.value("peers").toByteArray(); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); - m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth", "shh"}, p2p::NetworkPreferences(), network)); + m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth"/*, "shh"*/}, p2p::NetworkPreferences(), network)); m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads)); m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), this)); @@ -212,7 +212,7 @@ Main::Main(QWidget *parent) : m_server->setIdentities(keysAsVector(owned())); m_server->StartListening(); - WebPage* webPage= new WebPage(this); + WebPage* webPage = new WebPage(this); m_webPage = webPage; connect(webPage, &WebPage::consoleMessage, [this](QString const& _msg) { Main::addConsoleMessage(_msg, QString()); }); ui->webView->setPage(m_webPage); @@ -368,6 +368,11 @@ Address Main::getCurrencies() const return abiOut
(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)3)).output); } +bool Main::doConfirm() +{ + return ui->confirm->isChecked(); +} + void Main::installNameRegWatch() { uninstallWatch(m_nameRegFilter); @@ -943,22 +948,34 @@ void Main::on_preview_triggered() refreshAll(); } +void Main::on_prepNextDAG_triggered() +{ + EthashAux::computeFull( + EthashAux::seedHash( + ethereum()->blockChain().number() + ETHASH_EPOCH_LENGTH + ) + ); +} + void Main::refreshMining() { + pair gp = EthashAux::fullGeneratingProgress(); + QString t; + if (gp.first != EthashAux::NotGenerating) + t = QString("DAG for #%1-#%2: %3% complete; ").arg(gp.first).arg(gp.first + ETHASH_EPOCH_LENGTH - 1).arg(gp.second); MiningProgress p = ethereum()->miningProgress(); - ui->mineStatus->setText(ethereum()->isMining() ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Not mining"); - if (!ui->miningView->isVisible()) - return; - list l = ethereum()->miningHistory(); - static unsigned lh = 0; - if (p.hashes < lh) - ui->miningView->resetStats(); - lh = p.hashes; - ui->miningView->appendStats(l, p); -/* if (p.ms) - for (MineInfo const& i: l) - cnote << i.hashes * 10 << "h/sec, need:" << i.requirement << " best:" << i.best << " best-so-far:" << p.best << " avg-speed:" << (p.hashes * 1000 / p.ms) << "h/sec"; -*/ + ui->mineStatus->setText(t + (ethereum()->isMining() ? p.hashes > 0 ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Awaiting DAG" : "Not mining")); + if (ethereum()->isMining() && p.hashes > 0) + { + if (!ui->miningView->isVisible()) + return; + list l = ethereum()->miningHistory(); + static unsigned lh = 0; + if (p.hashes < lh) + ui->miningView->resetStats(); + lh = p.hashes; + ui->miningView->appendStats(l, p); + } } void Main::setBeneficiary(Address const& _b) @@ -1002,7 +1019,7 @@ void Main::refreshBalances() u256 b = ethereum()->balanceAt(i.first); QListWidgetItem* li = new QListWidgetItem(QString("%4 %2: %1 [%3]").arg(formatBalance(b).c_str()).arg(QString::fromStdString(render(i.first))).arg((unsigned)ethereum()->countAt(i.first)).arg(QString::fromStdString(i.second.first)), ui->ourAccounts); li->setData(Qt::UserRole, QByteArray((char const*)i.first.data(), Address::size)); - li->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); + li->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); li->setCheckState(m_beneficiary == i.first ? Qt::Checked : Qt::Unchecked); totalBalance += b; @@ -1139,7 +1156,7 @@ void Main::refreshBlockCount() { auto d = ethereum()->blockChain().details(); BlockQueueStatus b = ethereum()->blockQueueStatus(); - ui->chainStatus->setText(QString("%3 ready %4 future %5 unknown %6 bad %1 #%2").arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.ready).arg(b.future).arg(b.unknown).arg(b.bad)); + ui->chainStatus->setText(QString("%3 ready %4 verifying %5 unverified %6 future %7 unknown %8 bad %1 #%2").arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet").arg(d.number).arg(b.verified).arg(b.verifying).arg(b.unverified).arg(b.future).arg(b.unknown).arg(b.bad)); } void Main::on_turboMining_triggered() @@ -1149,7 +1166,10 @@ void Main::on_turboMining_triggered() void Main::refreshBlockChain() { - DEV_TIMED_FUNCTION; + if (!ui->blocks->isVisible() && isVisible()) + return; + + DEV_TIMED_FUNCTION_ABOVE(500); cwatch << "refreshBlockChain()"; // TODO: keep the same thing highlighted. @@ -1333,7 +1353,7 @@ void Main::timerEvent(QTimerEvent*) auto ls = ethereum()->checkWatchSafe(i.first); if (ls.size()) { - cnote << "FIRING WATCH" << i.first << ls.size(); +// cnote << "FIRING WATCH" << i.first << ls.size(); i.second(ls); } } @@ -1878,6 +1898,7 @@ void Main::on_mine_triggered() { if (ui->mine->isChecked()) { +// EthashAux::computeFull(ethereum()->blockChain().number()); ethereum()->setAddress(m_beneficiary); ethereum()->startMining(); } @@ -1981,6 +2002,7 @@ void Main::on_killAccount_triggered() m_keyManager.kill(h); if (m_keyManager.accounts().empty()) m_keyManager.import(Secret::random(), "Default account"); + m_beneficiary = *m_keyManager.accounts().begin(); keysChanged(); if (m_beneficiary == h) setBeneficiary(*m_keyManager.accounts().begin()); @@ -2027,6 +2049,7 @@ std::string Main::prettyU256(dev::u256 const& _n) const void Main::on_post_clicked() { + return; shh::Message m; m.setTo(stringToPublic(ui->shhTo->currentText())); m.setPayload(parseData(ui->shhData->toPlainText().toStdString())); @@ -2051,6 +2074,7 @@ int Main::authenticate(QString _title, QString _text) void Main::refreshWhispers() { + return; ui->whispers->clear(); for (auto const& w: whisper()->all()) { diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 51d4cc8f4..9f2082dd0 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -94,6 +94,7 @@ public: dev::u256 gasPrice() const { return 10 * dev::eth::szabo; } dev::eth::KeyManager& keyManager() override { return m_keyManager; } + bool doConfirm(); dev::Secret retrieveSecret(dev::Address const& _a) const override; @@ -124,6 +125,7 @@ private slots: // Mining void on_mine_triggered(); + void on_prepNextDAG_triggered(); // View void on_refresh_triggered(); diff --git a/alethzero/NatspecHandler.cpp b/alethzero/NatspecHandler.cpp index a7cad6853..d00abc44f 100644 --- a/alethzero/NatspecHandler.cpp +++ b/alethzero/NatspecHandler.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include using namespace dev; diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index d3ee4f41b..7e9836818 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -146,6 +146,9 @@ AddressHash OurAccountHolder::realAccounts() const bool OurAccountHolder::validateTransaction(TransactionSkeleton const& _t, bool _toProxy) { + if (!m_main->doConfirm()) + return true; + if (_t.creation) { // show notice concerning the creation code. TODO: this needs entering into natspec. diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index bc37db8ef..1336c3f05 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -299,8 +299,9 @@ void Transact::rejigData() return; // Determine how much balance we have to play with... - auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); - auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock); + //findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice()); + auto s = fromAccount(); + auto b = ethereum()->balanceAt(s, PendingBlock); m_allGood = true; QString htmlInfo; @@ -360,7 +361,7 @@ void Transact::rejigData() to = m_context->fromString(ui->destination->currentText().toStdString()).first; er = ethereum()->call(s, value(), to, m_data, gasNeeded, gasPrice()); } - gasNeeded = (qint64)(er.gasUsed + er.gasRefunded); + gasNeeded = (qint64)(er.gasUsed + er.gasRefunded + c_callStipend); htmlInfo = QString("
INFO Gas required: %1 total = %2 base, %3 exec [%4 refunded later]
").arg(gasNeeded).arg(baseGas).arg(gasNeeded - baseGas).arg((qint64)er.gasRefunded) + htmlInfo; if (er.excepted != TransactionException::None) diff --git a/cmake/FindOpenCL.cmake b/cmake/FindOpenCL.cmake index 4d3ed842c..a786e2e86 100644 --- a/cmake/FindOpenCL.cmake +++ b/cmake/FindOpenCL.cmake @@ -118,7 +118,7 @@ if(WIN32) endif() else() find_library(OpenCL_LIBRARY - NAMES OpenCL) + NAMES OpenCL libOpenCL.so.1) endif() set(OpenCL_LIBRARIES ${OpenCL_LIBRARY}) diff --git a/eth/main.cpp b/eth/main.cpp index daf31a156..924497126 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include @@ -57,6 +57,7 @@ #include "PhoneHome.h" #include "Farm.h" #endif +#include using namespace std; using namespace dev; using namespace dev::p2p; @@ -64,18 +65,6 @@ using namespace dev::eth; using namespace boost::algorithm; using dev::eth::Instruction; -#undef RETURN - -bool isTrue(std::string const& _m) -{ - return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; -} - -bool isFalse(std::string const& _m) -{ - return _m == "off" || _m == "no" || _m == "false" || _m == "0"; -} - void interactiveHelp() { cout @@ -93,6 +82,7 @@ void interactiveHelp() << " mineforce Forces mining, even when there are no transactions." << endl << " block Gives the current block height." << endl << " accounts Gives information on all owned accounts (balances, mining beneficiary and default signer)." << endl + << " newaccount Creates a new account with the given name." << endl << " transact Execute a given transaction." << endl << " send Execute a given transaction with current secret." << endl << " contract Create a new contract with current secret." << endl @@ -158,28 +148,13 @@ void help() << " --port Connect to remote port (default: 30303)." << endl << " --network-id Only connect to other hosts with this network id (default:0)." << endl << " --upnp Use UPnP for NAT (default: on)." << endl -#if ETH_JSONRPC || !ETH_TRUE - << endl - << "Work farming mode:" << endl - << " -F,--farm Put into mining farm mode with the work server at URL. Use with -G/--opencl." << endl - << " --farm-recheck Leave n ms between checks for changed work (default: 500)." << endl -#endif - << endl - << "Ethash verify mode:" << endl - << " -w,--check-pow Check PoW credentials for validity." << endl - << endl - << "Benchmarking mode:" << endl - << " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl - << " --benchmark-warmup Set the duration of warmup for the benchmark tests (default: 3)." << endl - << " --benchmark-trial Set the duration for each trial for the benchmark tests (default: 3)." << endl - << " --benchmark-trials Set the duration of warmup for the benchmark tests (default: 5)." << endl -#if ETH_JSONRPC || !ETH_TRUE - << " --phone-home When benchmarking, publish results (default: on)" << endl -#endif - << endl - << "DAG creation mode:" << endl - << " -D,--create-dag Create the DAG in preparation for mining on given block and exit." << endl - << endl + << endl; + MinerCLI::streamHelp(cout); + cout + << "Client structured logging:" << endl + << " --structured-logging Enable structured logging (default output to stdout)." << endl + << " --structured-logging-format Set the structured logging time format." << endl + << " --structured-logging-url Set the structured logging destination (currently only file:// supported)." << endl << "Import/export modes:" << endl << " -I,--import Import file as a concatenated series of blocks and exit." << endl << " -E,--export Export file as a concatenated series of blocks and exit." << endl @@ -202,20 +177,13 @@ void help() exit(0); } -string credits(bool _interactive = false) +string ethCredits(bool _interactive = false) { std::ostringstream cout; - cout - << "Ethereum (++) " << dev::Version << endl - << " Code by Gav Wood et al, (c) 2013, 2014, 2015." << endl - << " Based on a design by Vitalik Buterin." << endl << endl; - if (_interactive) cout - << "Type 'netstart 30303' to start networking" << endl - << "Type 'connect " << Host::pocHost() << " 30303' to connect" << endl << "Type 'exit' to quit" << endl << endl; - return cout.str(); + return credits() + cout.str(); } void version() @@ -257,23 +225,11 @@ enum class NodeMode Full }; -void doInitDAG(unsigned _n) -{ - BlockInfo bi; - bi.number = _n; - cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl; - Ethash::prep(bi); - exit(0); -} - enum class OperationMode { Node, Import, - Export, - DAGInit, - Benchmark, - Farm + Export }; enum class Format @@ -283,148 +239,6 @@ enum class Format Human }; -enum class MinerType -{ - CPU, - GPU -}; - -void doBenchmark(MinerType _m, bool _phoneHome, unsigned _warmupDuration = 15, unsigned _trialDuration = 3, unsigned _trials = 5) -{ - BlockInfo genesis = CanonBlockChain::genesis(); - genesis.difficulty = 1 << 18; - cdebug << genesis.boundary(); - - GenericFarm f; - f.onSolutionFound([&](ProofOfWork::Solution) { return false; }); - - string platformInfo = _m == MinerType::CPU ? ProofOfWork::CPUMiner::platformInfo() : _m == MinerType::GPU ? ProofOfWork::GPUMiner::platformInfo() : ""; - cout << "Benchmarking on platform: " << platformInfo << endl; - - cout << "Preparing DAG..." << endl; - Ethash::prep(genesis); - - genesis.difficulty = u256(1) << 63; - genesis.noteDirty(); - f.setWork(genesis); - if (_m == MinerType::CPU) - f.startCPU(); - else if (_m == MinerType::GPU) - f.startGPU(); - - map results; - uint64_t mean = 0; - uint64_t innerMean = 0; - for (unsigned i = 0; i <= _trials; ++i) - { - if (!i) - cout << "Warming up..." << endl; - else - cout << "Trial " << i << "... " << flush; - this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration)); - - auto mp = f.miningProgress(); - f.resetMiningProgress(); - if (!i) - continue; - auto rate = mp.rate(); - - cout << rate << endl; - results[rate] = mp; - mean += rate; - if (i > 1 && i < 5) - innerMean += rate; - } - f.stop(); - innerMean /= (_trials - 2); - cout << "min/mean/max: " << results.begin()->second.rate() << "/" << (mean / _trials) << "/" << results.rbegin()->second.rate() << " H/s" << endl; - cout << "inner mean: " << innerMean << " H/s" << endl; - - (void)_phoneHome; -#if ETH_JSONRPC || !ETH_TRUE - if (_phoneHome) - { - cout << "Phoning home to find world ranking..." << endl; - jsonrpc::HttpClient client("http://gav.ethdev.com:3000/benchmark"); - PhoneHome rpc(client); - try - { - unsigned ranking = rpc.report_benchmark(platformInfo, innerMean); - cout << "Ranked: " << ranking << " of all benchmarks." << endl; - } - catch (...) - { - cout << "Error phoning home. ET is sad." << endl; - } - } -#endif - exit(0); -} - -struct HappyChannel: public LogChannel { static const char* name() { return ":-D"; } static const int verbosity = 1; }; -struct SadChannel: public LogChannel { static const char* name() { return ":-("; } static const int verbosity = 1; }; - -void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod) -{ - (void)_m; - (void)_remote; - (void)_recheckPeriod; -#if ETH_JSONRPC || !ETH_TRUE - jsonrpc::HttpClient client(_remote); - Farm rpc(client); - GenericFarm f; - if (_m == MinerType::CPU) - f.startCPU(); - else if (_m == MinerType::GPU) - f.startGPU(); - - ProofOfWork::WorkPackage current; - while (true) - try - { - bool completed = false; - ProofOfWork::Solution solution; - f.onSolutionFound([&](ProofOfWork::Solution sol) - { - solution = sol; - return completed = true; - }); - for (unsigned i = 0; !completed; ++i) - { - if (current) - cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); - else - cnote << "Getting work package..."; - Json::Value v = rpc.eth_getWork(); - h256 hh(v[0].asString()); - if (hh != current.headerHash) - { - current.headerHash = hh; - current.seedHash = h256(v[1].asString()); - current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight); - cnote << "Got work package:" << current.headerHash << " < " << current.boundary; - f.setWork(current); - } - this_thread::sleep_for(chrono::milliseconds(_recheckPeriod)); - } - cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash << "," << solution.mixHash << "] to" << _remote << "..."; - bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash)); - if (ok) - clog(HappyChannel) << "Submitted and accepted."; - else - clog(SadChannel) << "Not accepted."; - current.reset(); - } - catch (jsonrpc::JsonRpcException&) - { - for (auto i = 3; --i; this_thread::sleep_for(chrono::seconds(1))) - cerr << "JSON-RPC problem. Probably couldn't connect. Retrying in " << i << "... \r"; - cerr << endl; - } -#endif - exit(0); -} - void stopMiningAfterXBlocks(eth::Client* _c, unsigned _start, unsigned _mining) { if (_c->isMining() && _c->blockChain().details().number - _start == _mining) @@ -434,73 +248,6 @@ void stopMiningAfterXBlocks(eth::Client* _c, unsigned _start, unsigned _mining) int main(int argc, char** argv) { -#if 0 - cout << "\x1b[30mEthBlack\x1b[0m" << endl; - cout << "\x1b[90mEthCoal\x1b[0m" << endl; - cout << "\x1b[37mEthGray\x1b[0m" << endl; - cout << "\x1b[97mEthWhite\x1b[0m" << endl; - cout << "\x1b[31mEthRed\x1b[0m" << endl; - cout << "\x1b[32mEthGreen\x1b[0m" << endl; - cout << "\x1b[33mEthYellow\x1b[0m" << endl; - cout << "\x1b[34mEthBlue\x1b[0m" << endl; - cout << "\x1b[35mEthPurple\x1b[0m" << endl; - cout << "\x1b[36mEthCyan\x1b[0m" << endl; - // High Intensity - cout << "\x1b[91mEthRedI\x1b[0m" << endl; - cout << "\x1b[92mEthLime\x1b[0m" << endl; - cout << "\x1b[93mEthYellowI\x1b[0m" << endl; - cout << "\x1b[94mEthBlueI\x1b[0m" << endl; - cout << "\x1b[95mEthPurpleI\x1b[0m" << endl; - cout << "\x1b[96mEthCyanI\x1b[0m" << endl; - - // Bold - cout << "\x1b[1;30mEthBlackB\x1b[0m" << endl; - cout << "\x1b[1;90mEthCoalB\x1b[0m" << endl; - cout << "\x1b[1;37mEthGrayB\x1b[0m" << endl; - cout << "\x1b[1;97mEthWhiteB\x1b[0m" << endl; - cout << "\x1b[1;31mEthRedB\x1b[0m" << endl; - cout << "\x1b[1;32mEthGreenB\x1b[0m" << endl; - cout << "\x1b[1;33mEthYellowB\x1b[0m" << endl; - cout << "\x1b[1;34mEthBlueB\x1b[0m" << endl; - cout << "\x1b[1;35mEthPurpleB\x1b[0m" << endl; - cout << "\x1b[1;36mEthCyanB\x1b[0m" << endl; - // Bold High Intensity - cout << "\x1b[1;91mEthRedBI\x1b[0m" << endl; - cout << "\x1b[1;92mEthGreenBI\x1b[0m" << endl; - cout << "\x1b[1;93mEthYellowBI\x1b[0m" << endl; - cout << "\x1b[1;94mEthBlueBI\x1b[0m" << endl; - cout << "\x1b[1;95mEthPurpleBI\x1b[0m" << endl; - cout << "\x1b[1;96mEthCyanBI\x1b[0m" << endl; - - // Background - cout << "\x1b[40mEthBlackOn\x1b[0m" << endl; - cout << "\x1b[100mEthCoalOn\x1b[0m" << endl; - cout << "\x1b[47mEthGrayOn\x1b[0m" << endl; - cout << "\x1b[107mEthWhiteOn\x1b[0m" << endl; - cout << "\x1b[41mEthRedOn\x1b[0m" << endl; - cout << "\x1b[42mEthGreenOn\x1b[0m" << endl; - cout << "\x1b[43mEthYellowOn\x1b[0m" << endl; - cout << "\x1b[44mEthBlueOn\x1b[0m" << endl; - cout << "\x1b[45mEthPurpleOn\x1b[0m" << endl; - cout << "\x1b[46mEthCyanOn\x1b[0m" << endl; - // High Intensity backgrounds - cout << "\x1b[101mEthRedOnI\x1b[0m" << endl; - cout << "\x1b[102mEthGreenOnI\x1b[0m" << endl; - cout << "\x1b[103mEthYellowOnI\x1b[0m" << endl; - cout << "\x1b[104mEthBlueOnI\x1b[0m" << endl; - cout << "\x1b[105mEthPurpleOnI\x1b[0m" << endl; - cout << "\x1b[106mEthCyanOnI\x1b[0m" << endl; - - // Underline - cout << "\x1b[4;30mEthBlackU\x1b[0m" << endl; - cout << "\x1b[4;31mEthRedU\x1b[0m" << endl; - cout << "\x1b[4;32mEthGreenU\x1b[0m" << endl; - cout << "\x1b[4;33mEthYellowU\x1b[0m" << endl; - cout << "\x1b[4;34mEthBlueU\x1b[0m" << endl; - cout << "\x1b[4;35mEthPurpleU\x1b[0m" << endl; - cout << "\x1b[4;36mEthCyanU\x1b[0m" << endl; - cout << "\x1b[4;37mEthWhiteU\x1b[0m" << endl; -#endif // Init defaults Defaults::get(); @@ -508,12 +255,6 @@ int main(int argc, char** argv) OperationMode mode = OperationMode::Node; string dbPath; - /// Mining options - MinerType minerType = MinerType::CPU; - unsigned openclPlatform = 0; - unsigned openclDevice = 0; - unsigned miningThreads = UINT_MAX; - /// File name for import/export. string filename; @@ -522,9 +263,6 @@ int main(int argc, char** argv) string exportTo = "latest"; Format exportFormat = Format::Binary; - /// DAG initialisation param. - unsigned initDAG = 0; - /// General params for Node operation NodeMode nodeMode = NodeMode::Full; bool interactive = false; @@ -542,7 +280,7 @@ int main(int argc, char** argv) string publicIP; string remoteHost; unsigned short remotePort = 30303; - unsigned peers = 5; + unsigned peers = 11; bool bootstrap = false; unsigned networkId = 0; @@ -563,19 +301,9 @@ int main(int argc, char** argv) double etherPrice = 30.679; double blockFees = 15.0; - /// Benchmarking params - bool phoneHome = true; - unsigned benchmarkWarmup = 3; - unsigned benchmarkTrial = 3; - unsigned benchmarkTrials = 5; - // javascript console bool useConsole = false; - /// Farm params - string farmURL = "http://127.0.0.1:8080"; - unsigned farmRecheckPeriod = 500; - /// Wallet password stuff string masterPassword; @@ -597,10 +325,13 @@ int main(int argc, char** argv) beneficiary = config[1].toHash
(); } + MinerCLI m(MinerCLI::OperationMode::None); + for (int i = 1; i < argc; ++i) { string arg = argv[i]; - if (arg == "--listen-ip" && i + 1 < argc) + if (m.interpretOption(i, argc, argv)) {} + else if (arg == "--listen-ip" && i + 1 < argc) listenIP = argv[++i]; else if ((arg == "-l" || arg == "--listen" || arg == "--listen-port") && i + 1 < argc) { @@ -636,52 +367,6 @@ int main(int argc, char** argv) mode = OperationMode::Export; filename = argv[++i]; } - else if ((arg == "-F" || arg == "--farm") && i + 1 < argc) - { - mode = OperationMode::Farm; - farmURL = argv[++i]; - } - else if (arg == "--farm-recheck" && i + 1 < argc) - try { - farmRecheckPeriod = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--opencl-platform" && i + 1 < argc) - try { - openclPlatform = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--opencl-device" && i + 1 < argc) - try { - openclDevice = stol(argv[++i]); - miningThreads = 1; - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--phone-home" && i + 1 < argc) - { - string m = argv[++i]; - if (isTrue(m)) - phoneHome = true; - else if (isFalse(m)) - phoneHome = false; - else - { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; - } - } else if (arg == "--format" && i + 1 < argc) { string m = argv[++i]; @@ -727,33 +412,6 @@ int main(int argc, char** argv) cerr << "Bad " << arg << " option: " << argv[i] << endl; return -1; } - else if (arg == "--benchmark-warmup" && i + 1 < argc) - try { - benchmarkWarmup = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--benchmark-trial" && i + 1 < argc) - try { - benchmarkTrial = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--benchmark-trials" && i + 1 < argc) - try { - benchmarkTrials = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } else if (arg == "-K" || arg == "--kill-blockchain" || arg == "--kill") killChain = WithExisting::Kill; else if (arg == "-R" || arg == "--rebuild") @@ -778,14 +436,6 @@ int main(int argc, char** argv) cerr << "Bad " << arg << " option: " << argv[i] << endl; return -1; } - else if (arg == "-C" || arg == "--cpu") - minerType = MinerType::CPU; - else if (arg == "-G" || arg == "--opencl") - minerType = MinerType::GPU; - /*<< " -s,--import-secret Import a secret key into the key store and use as the default." << endl - << " -S,--import-session-secret Import a secret key into the key store and use as the default for this session only." << endl - << " --sign-key
Sign all transactions with the key of the given address." << endl - << " --session-sign-key
Sign all transactions with the key of the given address for this session only." << endl*/ else if ((arg == "-s" || arg == "--import-secret") && i + 1 < argc) { Secret s(fromHex(argv[++i])); @@ -806,68 +456,13 @@ int main(int argc, char** argv) structuredLoggingFormat = string(argv[++i]); else if (arg == "--structured-logging") structuredLogging = true; - else if (arg == "--structured-logging-destination" && i + 1 < argc) + else if (arg == "--structured-logging-url" && i + 1 < argc) + { + structuredLogging = true; structuredLoggingURL = argv[++i]; + } else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) dbPath = argv[++i]; - else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) - { - string m = boost::to_lower_copy(string(argv[++i])); - mode = OperationMode::DAGInit; - if (m == "next") - initDAG = PendingBlock; - else if (m == "this") - initDAG = LatestBlock; - else - try - { - initDAG = stol(m); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; - } - } - else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc) - { - string m; - try - { - BlockInfo bi; - m = boost::to_lower_copy(string(argv[++i])); - h256 powHash(m); - m = boost::to_lower_copy(string(argv[++i])); - h256 seedHash; - if (m.size() == 64 || m.size() == 66) - seedHash = h256(m); - else - seedHash = EthashAux::seedHash(stol(m)); - m = boost::to_lower_copy(string(argv[++i])); - bi.difficulty = u256(m); - auto boundary = bi.boundary(); - m = boost::to_lower_copy(string(argv[++i])); - bi.nonce = h64(m); - auto r = EthashAux::eval((uint64_t)bi.number, powHash, bi.nonce); - bool valid = r.value < boundary; - cout << (valid ? "VALID :-)" : "INVALID :-(") << endl; - cout << r.value << (valid ? " < " : " >= ") << boundary << endl; - cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl; - cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.nonce << ")" << endl; - cout << " with seed as " << seedHash << endl; - if (valid) - cout << "(mixHash = " << r.mixHash << ")" << endl; - cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light((uint64_t)bi.number)->data()) << endl; - exit(0); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; - } - } - else if (arg == "-M" || arg == "--benchmark") - mode = OperationMode::Benchmark; else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc) { try @@ -930,17 +525,6 @@ int main(int argc, char** argv) return -1; } } - else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc) - { - try { - miningThreads = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - } else if (arg == "-b" || arg == "--bootstrap") bootstrap = true; else if (arg == "-f" || arg == "--force-mining") @@ -991,15 +575,11 @@ int main(int argc, char** argv) } } + m.execute(); + KeyManager keyManager; for (auto const& s: passwordsToNote) keyManager.notePassword(s); - for (auto const& s: toImport) - { - keyManager.import(s, "Imported key"); - if (!signingKey) - signingKey = toAddress(s); - } { RLPStream config(2); @@ -1010,29 +590,31 @@ int main(int argc, char** argv) if (sessionKey) signingKey = sessionKey; - if (minerType == MinerType::CPU) - ProofOfWork::CPUMiner::setNumInstances(miningThreads); - else if (minerType == MinerType::GPU) - { - ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); - ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); - ProofOfWork::GPUMiner::setNumInstances(miningThreads); - } - - // Two codepaths is necessary since named block require database, but numbered - // blocks are superuseful to have when database is already open in another process. - if (mode == OperationMode::DAGInit && !(initDAG == LatestBlock || initDAG == PendingBlock)) - doInitDAG(initDAG); - - if (mode == OperationMode::Benchmark) - doBenchmark(minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials); - - if (mode == OperationMode::Farm) - doFarm(minerType, farmURL, farmRecheckPeriod); - if (!clientName.empty()) clientName += "/"; + string logbuf; + bool silence = false; + std::string additional; + g_logPost = [&](std::string const& a, char const*){ + if (silence) + logbuf += a + "\n"; + else + cout << "\r \r" << a << endl << additional << flush; + }; + + auto getPassword = [&](string const& prompt){ + auto s = silence; + silence = true; + cout << endl; + string ret = dev::getPassword(prompt); + silence = s; + return ret; + }; + auto getAccountPassword = [&](Address const& a){ + return getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): "); + }; + StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat, structuredLoggingURL); VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp); @@ -1042,13 +624,10 @@ int main(int argc, char** argv) clientImplString, dbPath, killChain, - nodeMode == NodeMode::Full ? set{"eth", "shh"} : set(), + nodeMode == NodeMode::Full ? set{"eth"/*, "shh"*/} : set(), netPrefs, &nodesState); - if (mode == OperationMode::DAGInit) - doInitDAG(web3.ethereum()->blockChain().number() + (initDAG == PendingBlock ? 30000 : 0)); - auto toNumber = [&](string const& s) -> unsigned { if (s == "latest") return web3.ethereum()->number(); @@ -1112,31 +691,6 @@ int main(int argc, char** argv) return 0; } - cout << credits(); - web3.setIdealPeerCount(peers); - std::shared_ptr gasPricer = make_shared(u256(double(ether / 1000) / etherPrice), u256(blockFees * 1000)); - eth::Client* c = nodeMode == NodeMode::Full ? web3.ethereum() : nullptr; - StructuredLogger::starting(clientImplString, dev::Version); - if (c) - { - c->setGasPricer(gasPricer); - c->setForceMining(forceMining); - c->setTurboMining(minerType == MinerType::GPU); - c->setAddress(beneficiary); - c->setNetworkId(networkId); - } - - cout << "Transaction Signer: " << signingKey << endl; - cout << "Mining Benefactor: " << beneficiary << endl; - web3.startNetwork(); - cout << "Node ID: " << web3.enode() << endl; - - if (bootstrap) - for (auto const& i: Host::pocHosts()) - web3.requirePeer(i.first, i.second); - if (remoteHost.size()) - web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); - if (keyManager.exists()) while (masterPassword.empty()) { @@ -1162,20 +716,40 @@ int main(int argc, char** argv) keyManager.create(masterPassword); } - string logbuf; - bool silence = false; - std::string additional; - g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; }; + for (auto const& s: toImport) + { + keyManager.import(s, "Imported key (UNSAFE)"); + if (!signingKey) + signingKey = toAddress(s); + } - // TODO: give hints &c. - auto getPassword = [&](Address const& a){ - auto s = silence; - silence = true; - cout << endl; - string ret = dev::getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): "); - silence = s; - return ret; - }; + if (keyManager.accounts().empty()) + keyManager.import(Secret::random(), "Default key"); + + cout << ethCredits(); + web3.setIdealPeerCount(peers); + std::shared_ptr gasPricer = make_shared(u256(double(ether / 1000) / etherPrice), u256(blockFees * 1000)); + eth::Client* c = nodeMode == NodeMode::Full ? web3.ethereum() : nullptr; + StructuredLogger::starting(clientImplString, dev::Version); + if (c) + { + c->setGasPricer(gasPricer); + c->setForceMining(forceMining); + c->setTurboMining(m.minerType() == MinerCLI::MinerType::GPU); + c->setAddress(beneficiary); + c->setNetworkId(networkId); + } + + cout << "Transaction Signer: " << signingKey << endl; + cout << "Mining Benefactor: " << beneficiary << endl; + web3.startNetwork(); + cout << "Node ID: " << web3.enode() << endl; + + if (bootstrap) + for (auto const& i: Host::pocHosts()) + web3.requirePeer(i.first, i.second); + if (remoteHost.size()) + web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); #if ETH_JSONRPC || !ETH_TRUE shared_ptr jsonrpcServer; @@ -1183,7 +757,7 @@ int main(int argc, char** argv) if (jsonrpc > -1) { jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector())); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector())); jsonrpcServer->StartListening(); } #endif @@ -1327,7 +901,7 @@ int main(int argc, char** argv) if (jsonrpc < 0) jsonrpc = SensibleHttpPort; jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector())); + jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector())); jsonrpcServer->StartListening(); } else if (cmd == "jsonstop") @@ -1353,9 +927,36 @@ int main(int argc, char** argv) << std::chrono::duration_cast(it.lastPing).count() << "ms" << endl; } - else if (c && cmd == "balance") + else if (cmd == "newaccount") + { + string name; + std::getline(iss, name); + auto s = Secret::random(); + string password; + while (password.empty()) + { + password = getPassword("Please enter a password to protect this key (press enter for protection only be the MASTER password/keystore): "); + string confirm = getPassword("Please confirm the password by entering it again: "); + if (password != confirm) + { + cout << "Passwords were different. Try again." << endl; + password.clear(); + } + } + if (!password.empty()) + { + cout << "Enter a hint for this password: " << flush; + string hint; + std::getline(cin, hint); + keyManager.import(s, name, password, hint); + } + else + keyManager.import(s, name); + cout << "New account created: " << toAddress(s); + } + else if (c && cmd == "accounts") { - cout << "Current balance:" << endl; + cout << "Accounts:" << endl; u256 total = 0; for (auto const& i: keyManager.accountDetails()) { @@ -1479,7 +1080,7 @@ int main(int argc, char** argv) try { Address dest = h160(fromHex(hexAddr, WhenError::Throw)); - c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), amount, dest, bytes(), minGas); + c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), amount, dest, bytes(), minGas); } catch (BadHexCharacter& _e) { @@ -1548,7 +1149,7 @@ int main(int argc, char** argv) else if (gas < minGas) cwarn << "Minimum gas amount is" << minGas; else - c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), endowment, init, gas, gasPrice); + c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), endowment, init, gas, gasPrice); } else cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX"; @@ -1750,7 +1351,7 @@ int main(int argc, char** argv) if (useConsole) { #if ETH_JSCONSOLE - JSConsole console(web3, vector({sigKey})); + JSConsole console(web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager)); while (!g_exit) { console.repl(); diff --git a/ethminer/CMakeLists.txt b/ethminer/CMakeLists.txt index af38c0c84..d364f6ed1 100644 --- a/ethminer/CMakeLists.txt +++ b/ethminer/CMakeLists.txt @@ -17,12 +17,7 @@ add_dependencies(${EXECUTABLE} BuildInfo.h) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) -if (READLINE_FOUND) - target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) -endif() - if (JSONRPC) - target_link_libraries(${EXECUTABLE} web3jsonrpc) target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_CLIENT_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${CURL_LIBRARIES}) if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW) @@ -30,7 +25,7 @@ if (JSONRPC) endif() endif() -target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} ethash) if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW) diff --git a/ethminer/MinerAux.h b/ethminer/MinerAux.h new file mode 100644 index 000000000..ef0621b7f --- /dev/null +++ b/ethminer/MinerAux.h @@ -0,0 +1,497 @@ +#pragma once + +/* + 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 main.cpp + * @author Gav Wood + * @date 2014 + * Ethereum client. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if ETH_JSONRPC || !ETH_TRUE +#include +#include +#include +#endif +#include "BuildInfo.h" +#if ETH_JSONRPC || !ETH_TRUE +#include "PhoneHome.h" +#include "Farm.h" +#endif +using namespace std; +using namespace dev; +using namespace dev::eth; +using namespace boost::algorithm; +using dev::eth::Instruction; + +#undef RETURN + +bool isTrue(std::string const& _m) +{ + return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; +} + +bool isFalse(std::string const& _m) +{ + return _m == "off" || _m == "no" || _m == "false" || _m == "0"; +} + +inline std::string credits() +{ + std::ostringstream out; + out + << "Ethereum (++) " << dev::Version << endl + << " Code by Gav Wood et al, (c) 2013, 2014, 2015." << endl; + return out.str(); +} + +class BadArgument: public Exception {}; + +class MinerCLI +{ +public: + enum class OperationMode + { + None, + DAGInit, + Benchmark, + Farm + }; + + MinerCLI(OperationMode _mode = OperationMode::None): mode(_mode) {} + + bool interpretOption(int& i, int argc, char** argv) + { + string arg = argv[i]; + if ((arg == "-F" || arg == "--farm") && i + 1 < argc) + { + mode = OperationMode::Farm; + farmURL = argv[++i]; + } + else if (arg == "--farm-recheck" && i + 1 < argc) + try { + farmRecheckPeriod = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + throw BadArgument(); + } + else if (arg == "--opencl-platform" && i + 1 < argc) + try { + openclPlatform = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + throw BadArgument(); + } + else if (arg == "--opencl-device" && i + 1 < argc) + try { + openclDevice = stol(argv[++i]); + miningThreads = 1; + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + throw BadArgument(); + } + else if (arg == "--phone-home" && i + 1 < argc) + { + string m = argv[++i]; + if (isTrue(m)) + phoneHome = true; + else if (isFalse(m)) + phoneHome = false; + else + { + cerr << "Bad " << arg << " option: " << m << endl; + throw BadArgument(); + } + } + else if (arg == "--benchmark-warmup" && i + 1 < argc) + try { + benchmarkWarmup = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + throw BadArgument(); + } + else if (arg == "--benchmark-trial" && i + 1 < argc) + try { + benchmarkTrial = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + throw BadArgument(); + } + else if (arg == "--benchmark-trials" && i + 1 < argc) + try { + benchmarkTrials = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + throw BadArgument(); + } + else if (arg == "-C" || arg == "--cpu") + m_minerType = MinerType::CPU; + else if (arg == "-G" || arg == "--opencl") + { + m_minerType = MinerType::GPU; + miningThreads = 1; + } + else if (arg == "--no-precompute") + { + precompute = false; + } + else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) + { + string m = boost::to_lower_copy(string(argv[++i])); + mode = OperationMode::DAGInit; + try + { + initDAG = stol(m); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << m << endl; + throw BadArgument(); + } + } + else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc) + { + string m; + try + { + BlockInfo bi; + m = boost::to_lower_copy(string(argv[++i])); + h256 powHash(m); + m = boost::to_lower_copy(string(argv[++i])); + h256 seedHash; + if (m.size() == 64 || m.size() == 66) + seedHash = h256(m); + else + seedHash = EthashAux::seedHash(stol(m)); + m = boost::to_lower_copy(string(argv[++i])); + bi.difficulty = u256(m); + auto boundary = bi.boundary(); + m = boost::to_lower_copy(string(argv[++i])); + bi.nonce = h64(m); + auto r = EthashAux::eval(bi.seedHash(), powHash, bi.nonce); + bool valid = r.value < boundary; + cout << (valid ? "VALID :-)" : "INVALID :-(") << endl; + cout << r.value << (valid ? " < " : " >= ") << boundary << endl; + cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl; + cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.nonce << ")" << endl; + cout << " with seed as " << seedHash << endl; + if (valid) + cout << "(mixHash = " << r.mixHash << ")" << endl; + cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(bi.seedHash())->data()) << endl; + exit(0); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << m << endl; + throw BadArgument(); + } + } + else if (arg == "-M" || arg == "--benchmark") + mode = OperationMode::Benchmark; + else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc) + { + try { + miningThreads = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + throw BadArgument(); + } + } + else + return false; + return true; + } + + void execute() + { + if (m_minerType == MinerType::CPU) + ProofOfWork::CPUMiner::setNumInstances(miningThreads); + else if (m_minerType == MinerType::GPU) + { + ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); + ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); + ProofOfWork::GPUMiner::setNumInstances(miningThreads); + } + if (mode == OperationMode::DAGInit) + doInitDAG(initDAG); + else if (mode == OperationMode::Benchmark) + doBenchmark(m_minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials); + else if (mode == OperationMode::Farm) + doFarm(m_minerType, farmURL, farmRecheckPeriod); + } + + static void streamHelp(ostream& _out) + { + _out +#if ETH_JSONRPC || !ETH_TRUE + << "Work farming mode:" << endl + << " -F,--farm Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8545)" << endl + << " --farm-recheck Leave n ms between checks for changed work (default: 500)." << endl + << " --no-precompute Don't precompute the next epoch's DAG." << endl +#endif + << "Ethash verify mode:" << endl + << " -w,--check-pow Check PoW credentials for validity." << endl + << endl + << "Benchmarking mode:" << endl + << " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl + << " --benchmark-warmup Set the duration of warmup for the benchmark tests (default: 3)." << endl + << " --benchmark-trial Set the duration for each trial for the benchmark tests (default: 3)." << endl + << " --benchmark-trials Set the duration of warmup for the benchmark tests (default: 5)." << endl +#if ETH_JSONRPC || !ETH_TRUE + << " --phone-home When benchmarking, publish results (default: on)" << endl +#endif + << "DAG creation mode:" << endl + << " -D,--create-dag Create the DAG in preparation for mining on given block and exit." << endl + << "Mining configuration:" << endl + << " -C,--cpu When mining, use the CPU." << endl + << " -G,--opencl When mining use the GPU via OpenCL." << endl + << " --opencl-platform When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl + << " --opencl-device When mining using -G/--opencl use OpenCL device n (default: 0)." << endl + << " -t, --mining-threads Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl + ; + } + + enum class MinerType + { + CPU, + GPU + }; + + MinerType minerType() const { return m_minerType; } + +private: + void doInitDAG(unsigned _n) + { + BlockInfo bi; + bi.number = _n; + cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl; + Ethash::prep(bi); + exit(0); + } + + void doBenchmark(MinerType _m, bool _phoneHome, unsigned _warmupDuration = 15, unsigned _trialDuration = 3, unsigned _trials = 5) + { + BlockInfo genesis; + genesis.difficulty = 1 << 18; + cdebug << genesis.boundary(); + + GenericFarm f; + f.onSolutionFound([&](ProofOfWork::Solution) { return false; }); + + string platformInfo = _m == MinerType::CPU ? ProofOfWork::CPUMiner::platformInfo() : _m == MinerType::GPU ? ProofOfWork::GPUMiner::platformInfo() : ""; + cout << "Benchmarking on platform: " << platformInfo << endl; + + cout << "Preparing DAG..." << endl; + Ethash::prep(genesis); + + genesis.difficulty = u256(1) << 63; + genesis.noteDirty(); + f.setWork(genesis); + if (_m == MinerType::CPU) + f.startCPU(); + else if (_m == MinerType::GPU) + f.startGPU(); + + map results; + uint64_t mean = 0; + uint64_t innerMean = 0; + for (unsigned i = 0; i <= _trials; ++i) + { + if (!i) + cout << "Warming up..." << endl; + else + cout << "Trial " << i << "... " << flush; + this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration)); + + auto mp = f.miningProgress(); + f.resetMiningProgress(); + if (!i) + continue; + auto rate = mp.rate(); + + cout << rate << endl; + results[rate] = mp; + mean += rate; + } + f.stop(); + int j = -1; + for (auto const& r: results) + if (++j > 0 && j < (int)_trials - 1) + innerMean += r.second.rate(); + innerMean /= (_trials - 2); + cout << "min/mean/max: " << results.begin()->second.rate() << "/" << (mean / _trials) << "/" << results.rbegin()->second.rate() << " H/s" << endl; + cout << "inner mean: " << innerMean << " H/s" << endl; + + (void)_phoneHome; +#if ETH_JSONRPC || !ETH_TRUE + if (_phoneHome) + { + cout << "Phoning home to find world ranking..." << endl; + jsonrpc::HttpClient client("http://gav.ethdev.com:3000"); + PhoneHome rpc(client); + try + { + unsigned ranking = rpc.report_benchmark(platformInfo, innerMean); + cout << "Ranked: " << ranking << " of all benchmarks." << endl; + } + catch (...) + { + cout << "Error phoning home. ET is sad." << endl; + } + } +#endif + exit(0); + } + + void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod) + { + (void)_m; + (void)_remote; + (void)_recheckPeriod; +#if ETH_JSONRPC || !ETH_TRUE + jsonrpc::HttpClient client(_remote); + + Farm rpc(client); + GenericFarm f; + if (_m == MinerType::CPU) + f.startCPU(); + else if (_m == MinerType::GPU) + f.startGPU(); + + ProofOfWork::WorkPackage current; + EthashAux::FullType dag; + while (true) + try + { + bool completed = false; + ProofOfWork::Solution solution; + f.onSolutionFound([&](ProofOfWork::Solution sol) + { + solution = sol; + return completed = true; + }); + for (unsigned i = 0; !completed; ++i) + { + if (current) + cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); + else + cnote << "Getting work package..."; + Json::Value v = rpc.eth_getWork(); + h256 hh(v[0].asString()); + h256 newSeedHash(v[1].asString()); + if (current.seedHash != newSeedHash) + cnote << "Grabbing DAG for" << newSeedHash; + if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; }))) + BOOST_THROW_EXCEPTION(DAGCreationFailure()); + if (precompute) + EthashAux::computeFull(sha3(newSeedHash), true); + if (hh != current.headerHash) + { + current.headerHash = hh; + current.seedHash = newSeedHash; + current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight); + cnote << "Got work package:"; + cnote << " Header-hash:" << current.headerHash.hex(); + cnote << " Seedhash:" << current.seedHash.hex(); + cnote << " Target: " << h256(current.boundary).hex(); + f.setWork(current); + } + this_thread::sleep_for(chrono::milliseconds(_recheckPeriod)); + } + cnote << "Solution found; Submitting to" << _remote << "..."; + cnote << " Nonce:" << solution.nonce.hex(); + cnote << " Mixhash:" << solution.mixHash.hex(); + cnote << " Header-hash:" << current.headerHash.hex(); + cnote << " Seedhash:" << current.seedHash.hex(); + cnote << " Target: " << h256(current.boundary).hex(); + cnote << " Ethash: " << h256(EthashAux::eval(current.seedHash, current.headerHash, solution.nonce).value).hex(); + if (EthashAux::eval(current.seedHash, current.headerHash, solution.nonce).value < current.boundary) + { + bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash)); + if (ok) + cnote << "B-) Submitted and accepted."; + else + cwarn << ":-( Not accepted."; + } + else + cwarn << "FAILURE: GPU gave incorrect result!"; + current.reset(); + } + catch (jsonrpc::JsonRpcException&) + { + for (auto i = 3; --i; this_thread::sleep_for(chrono::seconds(1))) + cerr << "JSON-RPC problem. Probably couldn't connect. Retrying in " << i << "... \r"; + cerr << endl; + } +#endif + exit(0); + } + + /// Operating mode. + OperationMode mode; + + /// Mining options + MinerType m_minerType = MinerType::CPU; + unsigned openclPlatform = 0; + unsigned openclDevice = 0; + unsigned miningThreads = UINT_MAX; + + /// DAG initialisation param. + unsigned initDAG = 0; + + /// Benchmarking params + bool phoneHome = true; + unsigned benchmarkWarmup = 3; + unsigned benchmarkTrial = 3; + unsigned benchmarkTrials = 5; + + /// Farm params + string farmURL = "http://127.0.0.1:8545"; + unsigned farmRecheckPeriod = 500; + bool precompute = true; +}; diff --git a/ethminer/main.cpp b/ethminer/main.cpp index 124d3f779..4deba38d1 100644 --- a/ethminer/main.cpp +++ b/ethminer/main.cpp @@ -25,429 +25,48 @@ #include #include #include - #include #include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if ETH_JSONRPC || !ETH_TRUE -#include -#include -#include -#endif -#include "BuildInfo.h" -#if ETH_JSONRPC || !ETH_TRUE -#include "PhoneHome.h" -#include "Farm.h" -#endif +#include +#include "MinerAux.h" using namespace std; using namespace dev; -using namespace dev::p2p; using namespace dev::eth; using namespace boost::algorithm; -using dev::eth::Instruction; #undef RETURN -bool isTrue(std::string const& _m) -{ - return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; -} - -bool isFalse(std::string const& _m) -{ - return _m == "off" || _m == "no" || _m == "false" || _m == "0"; -} - void help() { cout << "Usage ethminer [OPTIONS]" << endl - << "Options:" << endl << endl -#if ETH_JSONRPC || !ETH_TRUE - << "Work farming mode:" << endl - << " -F,--farm Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8080)" << endl - << " --farm-recheck Leave n ms between checks for changed work (default: 500)." << endl -#endif - << "Benchmarking mode:" << endl - << " -M,--benchmark Benchmark for mining and exit; use with --cpu and --opencl." << endl - << " --benchmark-warmup Set the duration of warmup for the benchmark tests (default: 3)." << endl - << " --benchmark-trial Set the duration for each trial for the benchmark tests (default: 3)." << endl - << " --benchmark-trials Set the duration of warmup for the benchmark tests (default: 5)." << endl -#if ETH_JSONRPC || !ETH_TRUE - << " --phone-home When benchmarking, publish results (default: on)" << endl -#endif - << "DAG creation mode:" << endl - << " -D,--create-dag Create the DAG in preparation for mining on given block and exit." << endl + << "Options:" << endl << endl; + MinerCLI::streamHelp(cout); + cout << "General Options:" << endl - << " -C,--cpu When mining, use the CPU." << endl - << " -G,--opencl When mining use the GPU via OpenCL." << endl - << " --opencl-platform When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl - << " --opencl-device When mining using -G/--opencl use OpenCL device n (default: 0)." << endl - << " -t, --mining-threads Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl << " -V,--version Show the version and exit." << endl << " -h,--help Show this help message and exit." << endl ; - exit(0); -} - -string credits() -{ - std::ostringstream cout; - cout - << "Ethereum (++) " << dev::Version << endl - << " Code by Gav Wood et al, (c) 2013, 2014, 2015." << endl - << " Based on a design by Vitalik Buterin." << endl << endl; - return cout.str(); + exit(0); } void version() { - cout << "eth version " << dev::Version << endl; - cout << "eth network protocol version: " << dev::eth::c_protocolVersion << endl; - cout << "Client database version: " << dev::eth::c_databaseVersion << endl; + cout << "ethminer version " << dev::Version << endl; cout << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl; exit(0); } -void doInitDAG(unsigned _n) -{ - BlockInfo bi; - bi.number = _n; - cout << "Initializing DAG for epoch beginning #" << (bi.number / 30000 * 30000) << " (seedhash " << bi.seedHash().abridged() << "). This will take a while." << endl; - Ethash::prep(bi); - exit(0); -} - -enum class OperationMode -{ - DAGInit, - Benchmark, - Farm -}; - -enum class MinerType -{ - CPU, - GPU -}; - -void doBenchmark(MinerType _m, bool _phoneHome, unsigned _warmupDuration = 15, unsigned _trialDuration = 3, unsigned _trials = 5) -{ - BlockInfo genesis = CanonBlockChain::genesis(); - genesis.difficulty = 1 << 18; - cdebug << genesis.boundary(); - - GenericFarm f; - f.onSolutionFound([&](ProofOfWork::Solution) { return false; }); - - string platformInfo = _m == MinerType::CPU ? ProofOfWork::CPUMiner::platformInfo() : _m == MinerType::GPU ? ProofOfWork::GPUMiner::platformInfo() : ""; - cout << "Benchmarking on platform: " << platformInfo << endl; - - cout << "Preparing DAG..." << endl; - Ethash::prep(genesis); - - genesis.difficulty = u256(1) << 63; - genesis.noteDirty(); - f.setWork(genesis); - if (_m == MinerType::CPU) - f.startCPU(); - else if (_m == MinerType::GPU) - f.startGPU(); - - map results; - uint64_t mean = 0; - uint64_t innerMean = 0; - for (unsigned i = 0; i <= _trials; ++i) - { - if (!i) - cout << "Warming up..." << endl; - else - cout << "Trial " << i << "... " << flush; - this_thread::sleep_for(chrono::seconds(i ? _trialDuration : _warmupDuration)); - - auto mp = f.miningProgress(); - f.resetMiningProgress(); - if (!i) - continue; - auto rate = mp.rate(); - - cout << rate << endl; - results[rate] = mp; - mean += rate; - if (i > 1 && i < 5) - innerMean += rate; - } - f.stop(); - innerMean /= (_trials - 2); - cout << "min/mean/max: " << results.begin()->second.rate() << "/" << (mean / _trials) << "/" << results.rbegin()->second.rate() << " H/s" << endl; - cout << "inner mean: " << innerMean << " H/s" << endl; - - (void)_phoneHome; -#if ETH_JSONRPC || !ETH_TRUE - if (_phoneHome) - { - cout << "Phoning home to find world ranking..." << endl; - jsonrpc::HttpClient client("http://gav.ethdev.com:3000/benchmark"); - PhoneHome rpc(client); - try - { - unsigned ranking = rpc.report_benchmark(platformInfo, innerMean); - cout << "Ranked: " << ranking << " of all benchmarks." << endl; - } - catch (...) - { - cout << "Error phoning home. ET is sad." << endl; - } - } -#endif - exit(0); -} - -struct HappyChannel: public LogChannel { static const char* name() { return ":-D"; } static const int verbosity = 1; }; -struct SadChannel: public LogChannel { static const char* name() { return ":-("; } static const int verbosity = 1; }; - -void doFarm(MinerType _m, string const& _remote, unsigned _recheckPeriod) -{ - (void)_m; - (void)_remote; - (void)_recheckPeriod; -#if ETH_JSONRPC || !ETH_TRUE - jsonrpc::HttpClient client(_remote); - Farm rpc(client); - GenericFarm f; - if (_m == MinerType::CPU) - f.startCPU(); - else if (_m == MinerType::GPU) - f.startGPU(); - - ProofOfWork::WorkPackage current; - while (true) - try - { - bool completed = false; - ProofOfWork::Solution solution; - f.onSolutionFound([&](ProofOfWork::Solution sol) - { - solution = sol; - return completed = true; - }); - for (unsigned i = 0; !completed; ++i) - { - if (current) - cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); - else - cnote << "Getting work package..."; - Json::Value v = rpc.eth_getWork(); - h256 hh(v[0].asString()); - if (hh != current.headerHash) - { - current.headerHash = hh; - current.seedHash = h256(v[1].asString()); - current.boundary = h256(fromHex(v[2].asString()), h256::AlignRight); - cnote << "Got work package:" << current.headerHash << " < " << current.boundary; - f.setWork(current); - } - this_thread::sleep_for(chrono::milliseconds(_recheckPeriod)); - } - cnote << "Solution found; submitting [" << solution.nonce << "," << current.headerHash << "," << solution.mixHash << "] to" << _remote << "..."; - bool ok = rpc.eth_submitWork("0x" + toString(solution.nonce), "0x" + toString(current.headerHash), "0x" + toString(solution.mixHash)); - if (ok) - clog(HappyChannel) << "Submitted and accepted."; - else - clog(SadChannel) << "Not accepted."; - current.reset(); - } - catch (jsonrpc::JsonRpcException&) - { - for (auto i = 3; --i; this_thread::sleep_for(chrono::seconds(1))) - cerr << "JSON-RPC problem. Probably couldn't connect. Retrying in " << i << "... \r"; - cerr << endl; - } -#endif - exit(0); -} - int main(int argc, char** argv) { - // Init defaults - Defaults::get(); - - /// Operating mode. - OperationMode mode = OperationMode::Farm; - - /// Mining options - MinerType minerType = MinerType::CPU; - unsigned openclPlatform = 0; - unsigned openclDevice = 0; - unsigned miningThreads = UINT_MAX; - - /// DAG initialisation param. - unsigned initDAG = 0; - - /// Benchmarking params - bool phoneHome = true; - unsigned benchmarkWarmup = 3; - unsigned benchmarkTrial = 3; - unsigned benchmarkTrials = 5; - - /// Farm params - string farmURL = "http://127.0.0.1:8080"; - unsigned farmRecheckPeriod = 500; + MinerCLI m(MinerCLI::OperationMode::Farm); for (int i = 1; i < argc; ++i) { string arg = argv[i]; - if ((arg == "-F" || arg == "--farm") && i + 1 < argc) - { - mode = OperationMode::Farm; - farmURL = argv[++i]; - } - else if (arg == "--farm-recheck" && i + 1 < argc) - try { - farmRecheckPeriod = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--opencl-platform" && i + 1 < argc) - try { - openclPlatform = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--opencl-device" && i + 1 < argc) - try { - openclDevice = stol(argv[++i]); - miningThreads = 1; - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--phone-home" && i + 1 < argc) - { - string m = argv[++i]; - if (isTrue(m)) - phoneHome = true; - else if (isFalse(m)) - phoneHome = false; - else - { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; - } - } - else if (arg == "--benchmark-warmup" && i + 1 < argc) - try { - benchmarkWarmup = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--benchmark-trial" && i + 1 < argc) - try { - benchmarkTrial = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--benchmark-trials" && i + 1 < argc) - try { - benchmarkTrials = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "-C" || arg == "--cpu") - minerType = MinerType::CPU; - else if (arg == "-G" || arg == "--opencl") - minerType = MinerType::GPU; - else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc) - { - string m = boost::to_lower_copy(string(argv[++i])); - mode = OperationMode::DAGInit; - try - { - initDAG = stol(m); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; - } - } - else if ((arg == "-w" || arg == "--check-pow") && i + 4 < argc) - { - string m; - try - { - BlockInfo bi; - m = boost::to_lower_copy(string(argv[++i])); - h256 powHash(m); - m = boost::to_lower_copy(string(argv[++i])); - h256 seedHash; - if (m.size() == 64 || m.size() == 66) - seedHash = h256(m); - else - seedHash = EthashAux::seedHash(stol(m)); - m = boost::to_lower_copy(string(argv[++i])); - bi.difficulty = u256(m); - auto boundary = bi.boundary(); - m = boost::to_lower_copy(string(argv[++i])); - bi.nonce = h64(m); - auto r = EthashAux::eval((uint64_t)bi.number, powHash, bi.nonce); - bool valid = r.value < boundary; - cout << (valid ? "VALID :-)" : "INVALID :-(") << endl; - cout << r.value << (valid ? " < " : " >= ") << boundary << endl; - cout << " where " << boundary << " = 2^256 / " << bi.difficulty << endl; - cout << " and " << r.value << " = ethash(" << powHash << ", " << bi.nonce << ")" << endl; - cout << " with seed as " << seedHash << endl; - if (valid) - cout << "(mixHash = " << r.mixHash << ")" << endl; - cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light((uint64_t)bi.number)->data()) << endl; - exit(0); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; - } - } - else if (arg == "-M" || arg == "--benchmark") - mode = OperationMode::Benchmark; - else if ((arg == "-t" || arg == "--mining-threads") && i + 1 < argc) - { - try { - miningThreads = stol(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - } + if (m.interpretOption(i, argc, argv)) + {} else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) g_logVerbosity = atoi(argv[++i]); else if (arg == "-h" || arg == "--help") @@ -461,23 +80,7 @@ int main(int argc, char** argv) } } - if (minerType == MinerType::CPU) - ProofOfWork::CPUMiner::setNumInstances(miningThreads); - else if (minerType == MinerType::GPU) - { - ProofOfWork::GPUMiner::setDefaultPlatform(openclPlatform); - ProofOfWork::GPUMiner::setDefaultDevice(openclDevice); - ProofOfWork::GPUMiner::setNumInstances(miningThreads); - } - - if (mode == OperationMode::DAGInit) - doInitDAG(initDAG); - - if (mode == OperationMode::Benchmark) - doBenchmark(minerType, phoneHome, benchmarkWarmup, benchmarkTrial, benchmarkTrials); - - if (mode == OperationMode::Farm) - doFarm(minerType, farmURL, farmRecheckPeriod); + m.execute(); return 0; } diff --git a/evmjit/libevmjit-cpp/Env.cpp b/evmjit/libevmjit-cpp/Env.cpp index a5a60f48c..d1f239f9f 100644 --- a/evmjit/libevmjit-cpp/Env.cpp +++ b/evmjit/libevmjit-cpp/Env.cpp @@ -1,6 +1,6 @@ #pragma GCC diagnostic ignored "-Wconversion" -#include +#include #include #include #include diff --git a/evmjit/libevmjit-cpp/JitVM.cpp b/evmjit/libevmjit-cpp/JitVM.cpp index 95cf95769..5193168a4 100644 --- a/evmjit/libevmjit-cpp/JitVM.cpp +++ b/evmjit/libevmjit-cpp/JitVM.cpp @@ -4,7 +4,7 @@ #include "JitVM.h" #include -#include +#include #include #include #include diff --git a/exp/main.cpp b/exp/main.cpp index 2bd0a741e..47efe576a 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -34,6 +34,9 @@ #include #include #include +#include +#include +/* #include #include #include @@ -41,31 +44,56 @@ #include #include #include -#include #include #include #include -#include +#include +#include #include #include -#include #include #include #include #include #include #include -#include +#include */ using namespace std; using namespace dev; -using namespace dev::eth; +/*using namespace dev::eth; using namespace dev::p2p; using namespace dev::shh; namespace js = json_spirit; namespace fs = boost::filesystem; - +*/ #if 1 +int main() +{ + cdebug << "EXP"; + vector data; + for (unsigned i = 0; i < 10000; ++i) + data.push_back(rlp(i)); + + h256 ret; + DEV_TIMED(triedb) + { + MemoryDB mdb; + GenericTrieDB t(&mdb); + t.init(); + unsigned i = 0; + for (auto const& d: data) + t.insert(rlp(i++), d); + ret = t.root(); + } + cdebug << ret; + DEV_TIMED(hash256) + ret = orderedTrieRoot(data); + cdebug << ret; +} + +#elif 0 + int main() { KeyManager keyman; diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index 06950cbee..cb9b94de8 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -28,7 +28,7 @@ using namespace dev; namespace dev { -char const* Version = "0.9.18"; +char const* Version = "0.9.23"; const u256 UndefinedU256 = ~(u256)0; diff --git a/libdevcore/Common.h b/libdevcore/Common.h index 41f1b1d49..ac4d89103 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -86,8 +86,9 @@ extern const u256 UndefinedU256; // Map types. using StringMap = std::map; +using BytesMap = std::map; using u256Map = std::map; -using HexMap = std::map; +using HexMap = std::map; // Hash types. using StringHashMap = std::unordered_map; @@ -199,12 +200,12 @@ private: #define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__) #endif -#define DEV_TIMED_IF(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false) -#define DEV_TIMED_SCOPE_IF(S) ::dev::TimerHelper __eth_t(S, MS) +#define DEV_TIMED_ABOVE(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false) +#define DEV_TIMED_SCOPE_ABOVE(S, MS) ::dev::TimerHelper __eth_t(S, MS) #if WIN32 -#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__FUNCSIG__, MS) +#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__FUNCSIG__, MS) #else -#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__PRETTY_FUNCTION__, MS) +#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__PRETTY_FUNCTION__, MS) #endif enum class WithExisting: int diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp index 6cad29952..f8d8c172f 100644 --- a/libdevcore/CommonData.cpp +++ b/libdevcore/CommonData.cpp @@ -115,7 +115,7 @@ bytes dev::fromHex(std::string const& _s, WhenError _throw) return ret; } -bytes dev::asNibbles(std::string const& _s) +bytes dev::asNibbles(bytesConstRef const& _s) { std::vector ret; ret.reserve(_s.size() * 2); diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index 6c1f34667..702f1f808 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -95,7 +95,7 @@ inline bytes asBytes(std::string const& _b) /// Converts a string into the big-endian base-16 stream of integers (NOT ASCII). /// @example asNibbles("A")[0] == 4 && asNibbles("A")[1] == 1 -bytes asNibbles(std::string const& _s); +bytes asNibbles(bytesConstRef const& _s); // Big-endian to/from host endian conversion functions. diff --git a/libdevcore/CommonIO.cpp b/libdevcore/CommonIO.cpp index 80ad7ecf9..9538ca55f 100644 --- a/libdevcore/CommonIO.cpp +++ b/libdevcore/CommonIO.cpp @@ -24,6 +24,12 @@ #include #include #include "Exceptions.h" +#include +#ifdef _WIN32 +#include +#else +#include +#endif using namespace std; using namespace dev; @@ -122,10 +128,47 @@ std::string dev::getPassword(std::string const& _prompt) { #if WIN32 cout << _prompt << flush; + // Get current Console input flags + HANDLE hStdin; + DWORD fdwSaveOldMode; + if ((hStdin = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("GetStdHandle")); + if (!GetConsoleMode(hStdin, &fdwSaveOldMode)) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("GetConsoleMode")); + // Set console flags to no echo + if (!SetConsoleMode(hStdin, fdwSaveOldMode & (~ENABLE_ECHO_INPUT))) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("SetConsoleMode")); + // Read the string std::string ret; std::getline(cin, ret); + // Restore old input mode + if (!SetConsoleMode(hStdin, fdwSaveOldMode)) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("SetConsoleMode")); return ret; #else - return getpass(_prompt.c_str()); + struct termios oflags; + struct termios nflags; + char password[256]; + + // disable echo in the terminal + tcgetattr(fileno(stdin), &oflags); + nflags = oflags; + nflags.c_lflag &= ~ECHO; + nflags.c_lflag |= ECHONL; + + if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr")); + + printf("%s", _prompt.c_str()); + if (!fgets(password, sizeof(password), stdin)) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("fgets")); + password[strlen(password) - 1] = 0; + + // restore terminal + if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("tcsetattr")); + + + return password; #endif } diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index 36c624a71..025568efa 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -54,6 +54,7 @@ struct FileError: virtual Exception {}; struct Overflow: virtual Exception {}; struct InterfaceNotSupported: virtual Exception { public: InterfaceNotSupported(std::string _f): Exception("Interface " + _f + " not supported.") {} }; struct FailedInvariant: virtual Exception {}; +struct ExternalFunctionFailure: virtual Exception { public: ExternalFunctionFailure(std::string _f): Exception("Function " + _f + "() failed.") {} }; // error information to be added to exceptions using errinfo_invalidSymbol = boost::error_info; diff --git a/libdevcrypto/FileSystem.cpp b/libdevcore/FileSystem.cpp similarity index 85% rename from libdevcrypto/FileSystem.cpp rename to libdevcore/FileSystem.cpp index ed054553d..dfda891f5 100644 --- a/libdevcrypto/FileSystem.cpp +++ b/libdevcore/FileSystem.cpp @@ -22,11 +22,16 @@ */ #include "FileSystem.h" -#include -#include +#include "Common.h" +#include "Log.h" -#ifdef _WIN32 +#if defined(_WIN32) #include +#elif defined(__APPLE__) +#include +#include +#include +#include #endif #include using namespace std; @@ -51,16 +56,20 @@ std::string dev::getDataDir(std::string _prefix) #else boost::filesystem::path dataDirPath; char const* homeDir = getenv("HOME"); +#if defined(__APPLE__) + if (!homeDir || strlen(homeDir) == 0) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + homeDir = pwd->pw_dir; + } +#endif + if (!homeDir || strlen(homeDir) == 0) dataDirPath = boost::filesystem::path("/"); else dataDirPath = boost::filesystem::path(homeDir); -#if defined(__APPLE__) && defined(__MACH__) - // This eventually needs to be put in proper wrapper (to support sandboxing) - return (dataDirPath / "Library/Application Support/Ethereum").string(); -#else return (dataDirPath / ("." + _prefix)).string(); #endif -#endif } diff --git a/libdevcrypto/FileSystem.h b/libdevcore/FileSystem.h similarity index 100% rename from libdevcrypto/FileSystem.h rename to libdevcore/FileSystem.h diff --git a/libdevcore/Hash.cpp b/libdevcore/Hash.cpp new file mode 100644 index 000000000..c6b917b90 --- /dev/null +++ b/libdevcore/Hash.cpp @@ -0,0 +1,440 @@ +/* + 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 Hash.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "Hash.h" +#include +#include +#include +#include "picosha2.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +h256 sha256(bytesConstRef _input) +{ + h256 ret; + picosha2::hash256(_input.begin(), _input.end(), ret.data(), ret.data() + 32); + return ret; +} + +namespace rmd160 +{ + +/********************************************************************\ + * + * FILE: rmd160.h + * FILE: rmd160.c + * + * CONTENTS: Header file for a sample C-implementation of the + * RIPEMD-160 hash-function. + * TARGET: any computer with an ANSI C compiler + * + * AUTHOR: Antoon Bosselaers, ESAT-COSIC + * DATE: 1 March 1996 + * VERSION: 1.0 + * + * Copyright (c) Katholieke Universiteit Leuven + * 1996, All Rights Reserved + * + \********************************************************************/ + +// Adapted into "header-only" format by Gav Wood. + +/* macro definitions */ + +#define RMDsize 160 + +/* collect four bytes into one word: */ +#define BYTES_TO_DWORD(strptr) \ +(((uint32_t) *((strptr)+3) << 24) | \ +((uint32_t) *((strptr)+2) << 16) | \ +((uint32_t) *((strptr)+1) << 8) | \ +((uint32_t) *(strptr))) + +/* ROL(x, n) cyclically rotates x over n bits to the left */ +/* x must be of an unsigned 32 bits type and 0 <= n < 32. */ +#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* the five basic functions F(), G() and H() */ +#define F(x, y, z) ((x) ^ (y) ^ (z)) +#define G(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define H(x, y, z) (((x) | ~(y)) ^ (z)) +#define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define J(x, y, z) ((x) ^ ((y) | ~(z))) + +/* the ten basic operations FF() through III() */ +#define FF(a, b, c, d, e, x, s) {\ +(a) += F((b), (c), (d)) + (x);\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define GG(a, b, c, d, e, x, s) {\ +(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define HH(a, b, c, d, e, x, s) {\ +(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define II(a, b, c, d, e, x, s) {\ +(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define JJ(a, b, c, d, e, x, s) {\ +(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define FFF(a, b, c, d, e, x, s) {\ +(a) += F((b), (c), (d)) + (x);\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define GGG(a, b, c, d, e, x, s) {\ +(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define HHH(a, b, c, d, e, x, s) {\ +(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define III(a, b, c, d, e, x, s) {\ +(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} +#define JJJ(a, b, c, d, e, x, s) {\ +(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ +(a) = ROL((a), (s)) + (e);\ +(c) = ROL((c), 10);\ +} + +void MDinit(uint32_t *MDbuf) +{ + MDbuf[0] = 0x67452301UL; + MDbuf[1] = 0xefcdab89UL; + MDbuf[2] = 0x98badcfeUL; + MDbuf[3] = 0x10325476UL; + MDbuf[4] = 0xc3d2e1f0UL; + + return; +} + +/********************************************************************/ + +void MDcompress(uint32_t *MDbuf, uint32_t *X) +{ + uint32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2], + dd = MDbuf[3], ee = MDbuf[4]; + uint32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2], + ddd = MDbuf[3], eee = MDbuf[4]; + + /* round 1 */ + FF(aa, bb, cc, dd, ee, X[ 0], 11); + FF(ee, aa, bb, cc, dd, X[ 1], 14); + FF(dd, ee, aa, bb, cc, X[ 2], 15); + FF(cc, dd, ee, aa, bb, X[ 3], 12); + FF(bb, cc, dd, ee, aa, X[ 4], 5); + FF(aa, bb, cc, dd, ee, X[ 5], 8); + FF(ee, aa, bb, cc, dd, X[ 6], 7); + FF(dd, ee, aa, bb, cc, X[ 7], 9); + FF(cc, dd, ee, aa, bb, X[ 8], 11); + FF(bb, cc, dd, ee, aa, X[ 9], 13); + FF(aa, bb, cc, dd, ee, X[10], 14); + FF(ee, aa, bb, cc, dd, X[11], 15); + FF(dd, ee, aa, bb, cc, X[12], 6); + FF(cc, dd, ee, aa, bb, X[13], 7); + FF(bb, cc, dd, ee, aa, X[14], 9); + FF(aa, bb, cc, dd, ee, X[15], 8); + + /* round 2 */ + GG(ee, aa, bb, cc, dd, X[ 7], 7); + GG(dd, ee, aa, bb, cc, X[ 4], 6); + GG(cc, dd, ee, aa, bb, X[13], 8); + GG(bb, cc, dd, ee, aa, X[ 1], 13); + GG(aa, bb, cc, dd, ee, X[10], 11); + GG(ee, aa, bb, cc, dd, X[ 6], 9); + GG(dd, ee, aa, bb, cc, X[15], 7); + GG(cc, dd, ee, aa, bb, X[ 3], 15); + GG(bb, cc, dd, ee, aa, X[12], 7); + GG(aa, bb, cc, dd, ee, X[ 0], 12); + GG(ee, aa, bb, cc, dd, X[ 9], 15); + GG(dd, ee, aa, bb, cc, X[ 5], 9); + GG(cc, dd, ee, aa, bb, X[ 2], 11); + GG(bb, cc, dd, ee, aa, X[14], 7); + GG(aa, bb, cc, dd, ee, X[11], 13); + GG(ee, aa, bb, cc, dd, X[ 8], 12); + + /* round 3 */ + HH(dd, ee, aa, bb, cc, X[ 3], 11); + HH(cc, dd, ee, aa, bb, X[10], 13); + HH(bb, cc, dd, ee, aa, X[14], 6); + HH(aa, bb, cc, dd, ee, X[ 4], 7); + HH(ee, aa, bb, cc, dd, X[ 9], 14); + HH(dd, ee, aa, bb, cc, X[15], 9); + HH(cc, dd, ee, aa, bb, X[ 8], 13); + HH(bb, cc, dd, ee, aa, X[ 1], 15); + HH(aa, bb, cc, dd, ee, X[ 2], 14); + HH(ee, aa, bb, cc, dd, X[ 7], 8); + HH(dd, ee, aa, bb, cc, X[ 0], 13); + HH(cc, dd, ee, aa, bb, X[ 6], 6); + HH(bb, cc, dd, ee, aa, X[13], 5); + HH(aa, bb, cc, dd, ee, X[11], 12); + HH(ee, aa, bb, cc, dd, X[ 5], 7); + HH(dd, ee, aa, bb, cc, X[12], 5); + + /* round 4 */ + II(cc, dd, ee, aa, bb, X[ 1], 11); + II(bb, cc, dd, ee, aa, X[ 9], 12); + II(aa, bb, cc, dd, ee, X[11], 14); + II(ee, aa, bb, cc, dd, X[10], 15); + II(dd, ee, aa, bb, cc, X[ 0], 14); + II(cc, dd, ee, aa, bb, X[ 8], 15); + II(bb, cc, dd, ee, aa, X[12], 9); + II(aa, bb, cc, dd, ee, X[ 4], 8); + II(ee, aa, bb, cc, dd, X[13], 9); + II(dd, ee, aa, bb, cc, X[ 3], 14); + II(cc, dd, ee, aa, bb, X[ 7], 5); + II(bb, cc, dd, ee, aa, X[15], 6); + II(aa, bb, cc, dd, ee, X[14], 8); + II(ee, aa, bb, cc, dd, X[ 5], 6); + II(dd, ee, aa, bb, cc, X[ 6], 5); + II(cc, dd, ee, aa, bb, X[ 2], 12); + + /* round 5 */ + JJ(bb, cc, dd, ee, aa, X[ 4], 9); + JJ(aa, bb, cc, dd, ee, X[ 0], 15); + JJ(ee, aa, bb, cc, dd, X[ 5], 5); + JJ(dd, ee, aa, bb, cc, X[ 9], 11); + JJ(cc, dd, ee, aa, bb, X[ 7], 6); + JJ(bb, cc, dd, ee, aa, X[12], 8); + JJ(aa, bb, cc, dd, ee, X[ 2], 13); + JJ(ee, aa, bb, cc, dd, X[10], 12); + JJ(dd, ee, aa, bb, cc, X[14], 5); + JJ(cc, dd, ee, aa, bb, X[ 1], 12); + JJ(bb, cc, dd, ee, aa, X[ 3], 13); + JJ(aa, bb, cc, dd, ee, X[ 8], 14); + JJ(ee, aa, bb, cc, dd, X[11], 11); + JJ(dd, ee, aa, bb, cc, X[ 6], 8); + JJ(cc, dd, ee, aa, bb, X[15], 5); + JJ(bb, cc, dd, ee, aa, X[13], 6); + + /* parallel round 1 */ + JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); + JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); + JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); + JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); + JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); + JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); + JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); + JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); + JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); + JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); + JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); + + /* parallel round 2 */ + III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); + III(ddd, eee, aaa, bbb, ccc, X[11], 13); + III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); + III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); + III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); + III(eee, aaa, bbb, ccc, ddd, X[13], 8); + III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); + III(ccc, ddd, eee, aaa, bbb, X[10], 11); + III(bbb, ccc, ddd, eee, aaa, X[14], 7); + III(aaa, bbb, ccc, ddd, eee, X[15], 7); + III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); + III(ddd, eee, aaa, bbb, ccc, X[12], 7); + III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); + III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); + III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); + III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); + + /* parallel round 3 */ + HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); + HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); + HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); + HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); + HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); + HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); + HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); + HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); + HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); + HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); + HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); + HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); + HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); + HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); + HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); + HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); + + /* parallel round 4 */ + GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); + GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); + GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); + GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); + GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); + GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); + GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); + GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); + GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); + GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); + GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); + GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); + GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); + GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); + GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); + GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); + + /* parallel round 5 */ + FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); + FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); + FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); + FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); + FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); + FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); + FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); + FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); + FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); + FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); + FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); + FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); + FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); + FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); + FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); + + /* combine results */ + ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */ + MDbuf[1] = MDbuf[2] + dd + eee; + MDbuf[2] = MDbuf[3] + ee + aaa; + MDbuf[3] = MDbuf[4] + aa + bbb; + MDbuf[4] = MDbuf[0] + bb + ccc; + MDbuf[0] = ddd; + + return; +} + +void MDfinish(uint32_t *MDbuf, byte const *strptr, uint32_t lswlen, uint32_t mswlen) +{ + unsigned int i; /* counter */ + uint32_t X[16]; /* message words */ + + memset(X, 0, 16*sizeof(uint32_t)); + + /* put bytes from strptr into X */ + for (i=0; i<(lswlen&63); i++) { + /* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */ + X[i>>2] ^= (uint32_t) *strptr++ << (8 * (i&3)); + } + + /* append the bit m_n == 1 */ + X[(lswlen>>2)&15] ^= (uint32_t)1 << (8*(lswlen&3) + 7); + + if ((lswlen & 63) > 55) { + /* length goes to next block */ + MDcompress(MDbuf, X); + memset(X, 0, 16*sizeof(uint32_t)); + } + + /* append length in bits*/ + X[14] = lswlen << 3; + X[15] = (lswlen >> 29) | (mswlen << 3); + MDcompress(MDbuf, X); + + return; +} + +#undef ROL +#undef F +#undef G +#undef H +#undef I +#undef J +#undef FF +#undef GG +#undef HH +#undef II +#undef JJ +#undef FFF +#undef GGG +#undef HHH +#undef III +#undef JJJ + +} + +/* + * @returns RMD(_input) + */ +h160 ripemd160(bytesConstRef _input) +{ + h160 hashcode; + uint32_t buffer[RMDsize / 32]; // contains (A, B, C, D(, E)) + uint32_t current[16]; // current 16-word chunk + + // initialize + rmd160::MDinit(buffer); + byte const* message = _input.data(); + uint32_t remaining = _input.size(); // # of bytes not yet processed + + // process message in 16x 4-byte chunks + for (; remaining >= 64; remaining -= 64) + { + for (unsigned i = 0; i < 16; i++) + { + current[i] = BYTES_TO_DWORD(message); + message += 4; + } + rmd160::MDcompress(buffer, current); + } + // length mod 64 bytes left + + // finish: + rmd160::MDfinish(buffer, message, _input.size(), 0); + + for (unsigned i = 0; i < RMDsize / 8; i += 4) + { + hashcode[i] = buffer[i >> 2]; // implicit cast to byte + hashcode[i + 1] = (buffer[i >> 2] >> 8); //extracts the 8 least + hashcode[i + 2] = (buffer[i >> 2] >> 16); // significant bits. + hashcode[i + 3] = (buffer[i >> 2] >> 24); + } + + return hashcode; +} + +#undef BYTES_TO_DWORD +#undef RMDsize + +} diff --git a/test/libdevcrypto/TrieHash.h b/libdevcore/Hash.h similarity index 78% rename from test/libdevcrypto/TrieHash.h rename to libdevcore/Hash.h index be1d84480..7c5fcd67a 100644 --- a/test/libdevcrypto/TrieHash.h +++ b/libdevcore/Hash.h @@ -14,21 +14,25 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file TrieHash.h +/** @file Hash.h * @author Gav Wood * @date 2014 + * + * The FixedHash fixed-size "hash" container type. */ #pragma once -#include +#include #include +#include +#include "SHA3.h" namespace dev { -bytes rlp256(StringMap const& _s); -h256 hash256(StringMap const& _s); -h256 hash256(u256Map const& _s); +h256 sha256(bytesConstRef _input); + +h160 ripemd160(bytesConstRef _input); } diff --git a/libdevcrypto/MemoryDB.cpp b/libdevcore/MemoryDB.cpp similarity index 84% rename from libdevcrypto/MemoryDB.cpp rename to libdevcore/MemoryDB.cpp index 4b08db083..2cf56475b 100644 --- a/libdevcrypto/MemoryDB.cpp +++ b/libdevcore/MemoryDB.cpp @@ -32,6 +32,7 @@ const char* DBWarn::name() { return "TDB"; } std::unordered_map MemoryDB::get() const { + ReadGuard l(x_this); std::unordered_map ret; for (auto const& i: m_main) if (!m_enforceRefs || i.second.second > 0) @@ -39,21 +40,34 @@ std::unordered_map MemoryDB::get() const return ret; } +MemoryDB& MemoryDB::operator=(MemoryDB const& _c) +{ + if (this == &_c) + return *this; + ReadGuard l(_c.x_this); + WriteGuard l2(x_this); + m_main = _c.m_main; + m_aux = _c.m_aux; + return *this; +} + std::string MemoryDB::lookup(h256 const& _h) const { + ReadGuard l(x_this); auto it = m_main.find(_h); if (it != m_main.end()) { if (!m_enforceRefs || it->second.second > 0) return it->second.first; -// else if (m_enforceRefs && m_refCount.count(it->first) && !m_refCount.at(it->first)) -// cnote << "Lookup required for value with no refs. Let's hope it's in the DB." << _h; + else + cwarn << "Lookup required for value with refcount == 0. This is probably a critical trie issue" << _h; } return std::string(); } bool MemoryDB::exists(h256 const& _h) const { + ReadGuard l(x_this); auto it = m_main.find(_h); if (it != m_main.end() && (!m_enforceRefs || it->second.second > 0)) return true; @@ -62,6 +76,7 @@ bool MemoryDB::exists(h256 const& _h) const void MemoryDB::insert(h256 const& _h, bytesConstRef _v) { + WriteGuard l(x_this); auto it = m_main.find(_h); if (it != m_main.end()) { @@ -77,34 +92,34 @@ void MemoryDB::insert(h256 const& _h, bytesConstRef _v) bool MemoryDB::kill(h256 const& _h) { + ReadGuard l(x_this); if (m_main.count(_h)) { if (m_main[_h].second > 0) + { m_main[_h].second--; + return true; + } #if ETH_PARANOIA else { // If we get to this point, then there was probably a node in the level DB which we need to remove and which we have previously // used as part of the memory-based MemoryDB. Nothing to be worried about *as long as the node exists in the DB*. dbdebug << "NOKILL-WAS" << _h; - return false; } dbdebug << "KILL" << _h << "=>" << m_main[_h].second; - return true; } else { dbdebug << "NOKILL" << _h; - return false; - } -#else - } - return true; #endif + } + return false; } void MemoryDB::purge() { + WriteGuard l(x_this); for (auto it = m_main.begin(); it != m_main.end(); ) if (it->second.second) ++it; @@ -114,6 +129,7 @@ void MemoryDB::purge() h256Hash MemoryDB::keys() const { + ReadGuard l(x_this); h256Hash ret; for (auto const& i: m_main) if (i.second.second) diff --git a/libdevcrypto/MemoryDB.h b/libdevcore/MemoryDB.h similarity index 80% rename from libdevcrypto/MemoryDB.h rename to libdevcore/MemoryDB.h index 3169d8fbc..169682815 100644 --- a/libdevcrypto/MemoryDB.h +++ b/libdevcore/MemoryDB.h @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,9 @@ class MemoryDB public: MemoryDB() {} + MemoryDB(MemoryDB const& _c) { operator=(_c); } + + MemoryDB& operator=(MemoryDB const& _c); void clear() { m_main.clear(); } // WARNING !!!! didn't originally clear m_refCount!!! std::unordered_map get() const; @@ -53,13 +57,14 @@ public: bool kill(h256 const& _h); void purge(); - bytes lookupAux(h256 const& _h) const { try { return m_aux.at(_h).first; } catch (...) { return bytes(); } } - void removeAux(h256 const& _h) { m_aux[_h].second = false; } - void insertAux(h256 const& _h, bytesConstRef _v) { m_aux[_h] = make_pair(_v.toBytes(), true); } + bytes lookupAux(h256 const& _h) const { ReadGuard l(x_this); auto it = m_aux.find(_h); if (it != m_aux.end() && (!m_enforceRefs || it->second.second)) return it->second.first; return bytes(); } + void removeAux(h256 const& _h) { WriteGuard l(x_this); m_aux[_h].second = false; } + void insertAux(h256 const& _h, bytesConstRef _v) { WriteGuard l(x_this); m_aux[_h] = make_pair(_v.toBytes(), true); } h256Hash keys() const; protected: + mutable SharedMutex x_this; std::unordered_map> m_main; std::unordered_map> m_aux; diff --git a/libdevcore/SHA3.cpp b/libdevcore/SHA3.cpp new file mode 100644 index 000000000..880f23d6e --- /dev/null +++ b/libdevcore/SHA3.cpp @@ -0,0 +1,223 @@ +/* + 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 SHA3.cpp + * @author Gav Wood + * @date 2014 + */ + +#include "SHA3.h" +#include +#include +#include +#include +#include +#include "picosha2.h" +using namespace std; +using namespace dev; + +namespace dev +{ + +h256 EmptySHA3 = sha3(bytesConstRef()); +h256 EmptyListSHA3 = sha3(rlpList()); + +namespace keccak +{ + +/** libkeccak-tiny + * + * A single-file implementation of SHA-3 and SHAKE. + * + * Implementor: David Leon Gil + * License: CC0, attribution kindly requested. Blame taken too, + * but not liability. + */ + +#define decshake(bits) \ + int shake##bits(uint8_t*, size_t, const uint8_t*, size_t); + +#define decsha3(bits) \ + int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t); + +decshake(128) +decshake(256) +decsha3(224) +decsha3(256) +decsha3(384) +decsha3(512) + +/******** The Keccak-f[1600] permutation ********/ + +/*** Constants. ***/ +static const uint8_t rho[24] = \ + { 1, 3, 6, 10, 15, 21, + 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, + 62, 18, 39, 61, 20, 44}; +static const uint8_t pi[24] = \ + {10, 7, 11, 17, 18, 3, + 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, + 20, 14, 22, 9, 6, 1}; +static const uint64_t RC[24] = \ + {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, + 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, + 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; + +/*** Helper macros to unroll the permutation. ***/ +#define rol(x, s) (((x) << s) | ((x) >> (64 - s))) +#define REPEAT6(e) e e e e e e +#define REPEAT24(e) REPEAT6(e e e e) +#define REPEAT5(e) e e e e e +#define FOR5(v, s, e) \ + v = 0; \ + REPEAT5(e; v += s;) + +/*** Keccak-f[1600] ***/ +static inline void keccakf(void* state) { + uint64_t* a = (uint64_t*)state; + uint64_t b[5] = {0}; + uint64_t t = 0; + uint8_t x, y; + + for (int i = 0; i < 24; i++) { + // Theta + FOR5(x, 1, + b[x] = 0; + FOR5(y, 5, + b[x] ^= a[x + y]; )) + FOR5(x, 1, + FOR5(y, 5, + a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) + // Rho and pi + t = a[1]; + x = 0; + REPEAT24(b[0] = a[pi[x]]; + a[pi[x]] = rol(t, rho[x]); + t = b[0]; + x++; ) + // Chi + FOR5(y, + 5, + FOR5(x, 1, + b[x] = a[y + x];) + FOR5(x, 1, + a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) + // Iota + a[0] ^= RC[i]; + } +} + +/******** The FIPS202-defined functions. ********/ + +/*** Some helper macros. ***/ + +#define _(S) do { S } while (0) +#define FOR(i, ST, L, S) \ + _(for (size_t i = 0; i < L; i += ST) { S; }) +#define mkapply_ds(NAME, S) \ + static inline void NAME(uint8_t* dst, \ + const uint8_t* src, \ + size_t len) { \ + FOR(i, 1, len, S); \ + } +#define mkapply_sd(NAME, S) \ + static inline void NAME(const uint8_t* src, \ + uint8_t* dst, \ + size_t len) { \ + FOR(i, 1, len, S); \ + } + +mkapply_ds(xorin, dst[i] ^= src[i]) // xorin +mkapply_sd(setout, dst[i] = src[i]) // setout + +#define P keccakf +#define Plen 200 + +// Fold P*F over the full blocks of an input. +#define foldP(I, L, F) \ + while (L >= rate) { \ + F(a, I, rate); \ + P(a); \ + I += rate; \ + L -= rate; \ + } + +/** The sponge-based hash construction. **/ +static inline int hash(uint8_t* out, size_t outlen, + const uint8_t* in, size_t inlen, + size_t rate, uint8_t delim) { + if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { + return -1; + } + uint8_t a[Plen] = {0}; + // Absorb input. + foldP(in, inlen, xorin); + // Xor in the DS and pad frame. + a[inlen] ^= delim; + a[rate - 1] ^= 0x80; + // Xor in the last block. + xorin(a, in, inlen); + // Apply P + P(a); + // Squeeze output. + foldP(out, outlen, setout); + setout(a, out, outlen); + memset(a, 0, 200); + return 0; +} + +/*** Helper macros to define SHA3 and SHAKE instances. ***/ +#define defshake(bits) \ + int shake##bits(uint8_t* out, size_t outlen, \ + const uint8_t* in, size_t inlen) { \ + return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \ + } +#define defsha3(bits) \ + int sha3_##bits(uint8_t* out, size_t outlen, \ + const uint8_t* in, size_t inlen) { \ + if (outlen > (bits/8)) { \ + return -1; \ + } \ + return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ + } + +/*** FIPS202 SHAKE VOFs ***/ +defshake(128) +defshake(256) + +/*** FIPS202 SHA3 FOFs ***/ +defsha3(224) +defsha3(256) +defsha3(384) +defsha3(512) + +} + +h256 sha3(bytesConstRef _input) +{ + // FIXME: What with unaligned memory? + h256 ret; + keccak::sha3_256(ret.data(), 32, _input.data(), _input.size()); +// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size()); + return ret; +} + +} diff --git a/libdevcrypto/SHA3.h b/libdevcore/SHA3.h similarity index 66% rename from libdevcrypto/SHA3.h rename to libdevcore/SHA3.h index 66b8efe11..c3ef524fe 100644 --- a/libdevcrypto/SHA3.h +++ b/libdevcore/SHA3.h @@ -32,46 +32,29 @@ namespace dev // SHA-3 convenience routines. -/// Calculate SHA3-256 hash of the given input and load it into the given output. -void sha3(bytesConstRef _input, bytesRef _output); - -/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data. -std::string sha3(std::string const& _input, bool _isNibbles); - -/// Calculate SHA3-256 hash of the given input, returning as a byte array. -bytes sha3Bytes(bytesConstRef _input); - -/// Calculate SHA3-256 hash of the given input (presented as a binary string), returning as a byte array. -inline bytes sha3Bytes(std::string const& _input) { return sha3Bytes((std::string*)&_input); } - -/// Calculate SHA3-256 hash of the given input, returning as a byte array. -inline bytes sha3Bytes(bytes const& _input) { return sha3Bytes((bytes*)&_input); } - /// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash. h256 sha3(bytesConstRef _input); +/// Calculate SHA3-256 hash of the given input and load it into the given output. +inline void sha3(bytesConstRef _input, bytesRef _output) { sha3(_input).ref().populate(_output); } + /// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash. -inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_input)); } +inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef(&_input)); } /// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash. inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); } - -/// Calculate SHA3-256 MAC -void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output); /// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash. template inline h256 sha3(FixedHash const& _input) { return sha3(_input.ref()); } -extern h256 EmptySHA3; - -extern h256 EmptyListSHA3; - -// Other crypto convenience routines +/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data. +inline std::string sha3(std::string const& _input, bool _isNibbles) { return asString((_isNibbles ? sha3(fromHex(_input)) : sha3(bytesConstRef(&_input))).asBytes()); } -bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef()); +/// Calculate SHA3-256 MAC +inline void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) { sha3(_secret.toBytes() + _plain.toBytes()).ref().populate(_output); } -void sha256(bytesConstRef _input, bytesRef _output); +extern h256 EmptySHA3; -void ripemd160(bytesConstRef _input, bytesRef _output); +extern h256 EmptyListSHA3; } diff --git a/libdevcrypto/TrieCommon.cpp b/libdevcore/TrieCommon.cpp similarity index 100% rename from libdevcrypto/TrieCommon.cpp rename to libdevcore/TrieCommon.cpp diff --git a/libdevcrypto/TrieCommon.h b/libdevcore/TrieCommon.h similarity index 100% rename from libdevcrypto/TrieCommon.h rename to libdevcore/TrieCommon.h diff --git a/libdevcrypto/TrieDB.cpp b/libdevcore/TrieDB.cpp similarity index 95% rename from libdevcrypto/TrieDB.cpp rename to libdevcore/TrieDB.cpp index 6f84a3e29..719bd74ad 100644 --- a/libdevcrypto/TrieDB.cpp +++ b/libdevcore/TrieDB.cpp @@ -25,6 +25,6 @@ using namespace std; using namespace dev; h256 const dev::c_shaNull = sha3(rlp("")); -h256 const dev::EmptyTrie = c_shaNull; +h256 const dev::EmptyTrie = sha3(rlp("")); const char* TrieDBChannel::name() { return "-T-"; } diff --git a/libdevcrypto/TrieDB.h b/libdevcore/TrieDB.h similarity index 90% rename from libdevcrypto/TrieDB.h rename to libdevcore/TrieDB.h index ff2bcc589..f9d7bff5f 100644 --- a/libdevcrypto/TrieDB.h +++ b/libdevcore/TrieDB.h @@ -30,9 +30,8 @@ #include #include #include -#include +#include #include "MemoryDB.h" -#include "OverlayDB.h" #include "TrieCommon.h" namespace ldb = leveldb; @@ -79,7 +78,7 @@ public: void open(DB* _db) { m_db = _db; } void open(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { m_db = _db; setRoot(_root, _v); } - void init() { setRoot(insertNode(&RLPNull)); assert(node(m_root).size()); } + void init() { setRoot(forceInsertNode(&RLPNull)); assert(node(m_root).size()); } void setRoot(h256 const& _root, Verification _v = Verification::Normal) { @@ -88,11 +87,13 @@ public: { if (m_root == c_shaNull && !m_db->exists(m_root)) init(); - - /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/ + } + /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/ +#if ETH_DEBUG + if (_v == Verification::Normal) +#endif if (!node(m_root).size()) BOOST_THROW_EXCEPTION(RootNotFound()); - } } /// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node). @@ -218,6 +219,7 @@ public: bool operator!=(Node const& _c) const { return !operator==(_c); } }; + protected: std::vector m_trail; GenericTrieDB const* m_that; }; @@ -237,6 +239,7 @@ private: void mergeAtAux(RLPStream& _out, RLP const& _replace, NibbleSlice _key, bytesConstRef _value); bytes mergeAt(RLP const& _replace, NibbleSlice _k, bytesConstRef _v, bool _inLine = false); + bytes mergeAt(RLP const& _replace, h256 const& _replaceHash, NibbleSlice _k, bytesConstRef _v, bool _inLine = false); bool deleteAtAux(RLPStream& _out, RLP const& _replace, NibbleSlice _key); bytes deleteAt(RLP const& _replace, NibbleSlice _k); @@ -282,11 +285,18 @@ private: std::string deref(RLP const& _n) const; std::string node(h256 _h) const { return m_db->lookup(_h); } - void insertNode(h256 _h, bytesConstRef _v) { m_db->insert(_h, _v); } - void killNode(h256 _h) { m_db->kill(_h); } - h256 insertNode(bytesConstRef _v) { auto h = sha3(_v); insertNode(h, _v); return h; } - void killNode(RLP const& _d) { if (_d.data().size() >= 32) killNode(sha3(_d.data())); } + // These are low-level node insertion functions that just go straight through into the DB. + h256 forceInsertNode(bytesConstRef _v) { auto h = sha3(_v); forceInsertNode(h, _v); return h; } + void forceInsertNode(h256 _h, bytesConstRef _v) { m_db->insert(_h, _v); } + void forceKillNode(h256 _h) { m_db->kill(_h); } + + // This are semantically-aware node insertion functions that only kills when the node's + // data is < 32 bytes. It can safely be used when pruning the trie but won't work correctly + // for the special case of the root (which is always looked up via a hash). In that case, + // use forceKillNode(). + void killNode(RLP const& _d) { if (_d.data().size() >= 32) forceKillNode(sha3(_d.data())); } + void killNode(RLP const& _d, h256 const& _h) { if (_d.data().size() >= 32) forceKillNode(_h); } h256 m_root; DB* m_db = nullptr; @@ -401,46 +411,59 @@ public: iterator lower_bound(bytesConstRef) const { return iterator(); } }; -// Hashed & Basic -template -class FatGenericTrieDB: public GenericTrieDB +// Hashed & Hash-key mapping +template +class FatGenericTrieDB: private SpecificTrieDB, h256> { - using Super = GenericTrieDB; + using Super = SpecificTrieDB, h256>; public: - FatGenericTrieDB(DB* _db): Super(_db), m_secure(_db) {} - FatGenericTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal) { open(_db, _root, _v); } - - void open(DB* _db, h256 _root, Verification _v = Verification::Normal) { Super::open(_db); m_secure.open(_db); setRoot(_root, _v); } + using DB = _DB; + FatGenericTrieDB(DB* _db = nullptr): Super(_db) {} + FatGenericTrieDB(DB* _db, h256 _root, Verification _v = Verification::Normal): Super(_db, _root, _v) {} - void init() { Super::init(); m_secure.init(); syncRoot(); } + using Super::init; + using Super::isNull; + using Super::isEmpty; + using Super::root; + using Super::leftOvers; + using Super::check; + using Super::open; + using Super::setRoot; - void setRoot(h256 _root, Verification _v = Verification::Normal) + std::string at(bytesConstRef _key) const { return Super::at(sha3(_key)); } + bool contains(bytesConstRef _key) { return Super::contains(sha3(_key)); } + void insert(bytesConstRef _key, bytesConstRef _value) { - if (!m_secure.isNull()) - Super::db()->removeAux(m_secure.root()); - m_secure.setRoot(_root, _v); - auto rb = Super::db()->lookupAux(m_secure.root()); - auto r = h256(rb); - Super::setRoot(r, _v); + h256 hash = sha3(_key); + Super::insert(hash, _value); + Super::db()->insertAux(hash, _key); } - h256 root() const { return m_secure.root(); } - - void insert(bytesConstRef _key, bytesConstRef _value) { Super::insert(_key, _value); m_secure.insert(_key, _value); syncRoot(); } - void remove(bytesConstRef _key) { Super::remove(_key); m_secure.remove(_key); syncRoot(); } + void remove(bytesConstRef _key) { Super::remove(sha3(_key)); } - h256Hash leftOvers(std::ostream* = nullptr) const { return h256Hash{}; } - bool check(bool) const { return m_secure.check(false) && Super::check(false); } + //friend class iterator; -private: - void syncRoot() + class iterator : public GenericTrieDB<_DB>::iterator { - // Root changed. Need to record the mapping so we can determine on setRoot. - Super::db()->insertAux(m_secure.root(), Super::root().ref()); - } + public: + using Super = typename GenericTrieDB<_DB>::iterator; + + iterator() { } + iterator(FatGenericTrieDB const* _trie): Super(_trie) { } + + typename Super::value_type at() const + { + auto hashed = Super::at(); + m_key = static_cast(Super::m_that)->db()->lookupAux(h256(hashed.first)); + return std::make_pair(&m_key, std::move(hashed.second)); + } - HashedGenericTrieDB m_secure; + private: + mutable bytes m_key; + }; + iterator begin() const { return iterator(); } + iterator end() const { return iterator(); } }; template using TrieDB = SpecificTrieDB, KeyType>; @@ -737,14 +760,14 @@ template void GenericTrieDB::insert(bytesConstRef _key, bytesCons std::string rv = node(m_root); assert(rv.size()); - bytes b = mergeAt(RLP(rv), NibbleSlice(_key), _value); + bytes b = mergeAt(RLP(rv), m_root, NibbleSlice(_key), _value); // mergeAt won't attempt to delete the node if it's less than 32 bytes // However, we know it's the root node and thus always hashed. // So, if it's less than 32 (and thus should have been deleted but wasn't) then we delete it here. if (rv.size() < 32) - killNode(m_root); - m_root = insertNode(&b); + forceKillNode(m_root); + m_root = forceInsertNode(&b); } template std::string GenericTrieDB::at(bytesConstRef _key) const @@ -757,8 +780,9 @@ template std::string GenericTrieDB::atAux(RLP const& _here, Nibbl if (_here.isEmpty() || _here.isNull()) // not found. return std::string(); - assert(_here.isList() && (_here.itemCount() == 2 || _here.itemCount() == 17)); - if (_here.itemCount() == 2) + unsigned itemCount = _here.itemCount(); + assert(_here.isList() && (itemCount == 2 || itemCount == 17)); + if (itemCount == 2) { auto k = keyOf(_here); if (_key == k && isLeaf(_here)) @@ -784,6 +808,11 @@ template std::string GenericTrieDB::atAux(RLP const& _here, Nibbl } template bytes GenericTrieDB::mergeAt(RLP const& _orig, NibbleSlice _k, bytesConstRef _v, bool _inLine) +{ + return mergeAt(_orig, sha3(_orig.data()), _k, _v, _inLine); +} + +template bytes GenericTrieDB::mergeAt(RLP const& _orig, h256 const& _origHash, NibbleSlice _k, bytesConstRef _v, bool _inLine) { #if ETH_PARANOIA tdebug << "mergeAt " << _orig << _k << sha3(_orig.data()); @@ -797,8 +826,9 @@ template bytes GenericTrieDB::mergeAt(RLP const& _orig, NibbleSli if (_orig.isEmpty()) return place(_orig, _k, _v); - assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17)); - if (_orig.itemCount() == 2) + unsigned itemCount = _orig.itemCount(); + assert(_orig.isList() && (itemCount == 2 || itemCount == 17)); + if (itemCount == 2) { // pair... NibbleSlice k = keyOf(_orig); @@ -811,7 +841,7 @@ template bytes GenericTrieDB::mergeAt(RLP const& _orig, NibbleSli if (_k.contains(k) && !isLeaf(_orig)) { if (!_inLine) - killNode(_orig); + killNode(_orig, _origHash); RLPStream s(2); s.append(_orig[0]); mergeAtAux(s, _orig[1], _k.mid(k.size()), _v); @@ -843,7 +873,7 @@ template bytes GenericTrieDB::mergeAt(RLP const& _orig, NibbleSli // Kill the node. if (!_inLine) - killNode(_orig); + killNode(_orig, _origHash); // not exactly our node - delve to next level at the correct index. byte n = _k[0]; @@ -890,8 +920,8 @@ template void GenericTrieDB::remove(bytesConstRef _key) if (b.size()) { if (rv.size() < 32) - killNode(m_root); - m_root = insertNode(&b); + forceKillNode(m_root); + m_root = forceInsertNode(&b); } } @@ -1081,7 +1111,7 @@ template RLPStream& GenericTrieDB::streamNode(RLPStream& _s, byte if (_b.size() < 32) _s.appendRaw(_b); else - _s.append(insertNode(&_b)); + _s.append(forceInsertNode(&_b)); return _s; } @@ -1122,7 +1152,7 @@ template bytes GenericTrieDB::graft(RLP const& _orig) // remove second item from the trie after derefrencing it into s & n. auto lh = _orig[1].toHash(); s = node(lh); - killNode(lh); + forceKillNode(lh); n = RLP(s); } assert(n.itemCount() == 2); diff --git a/test/libdevcrypto/TrieHash.cpp b/libdevcore/TrieHash.cpp similarity index 85% rename from test/libdevcrypto/TrieHash.cpp rename to libdevcore/TrieHash.cpp index ccf12c162..cff3464b5 100644 --- a/test/libdevcrypto/TrieHash.cpp +++ b/libdevcore/TrieHash.cpp @@ -20,9 +20,9 @@ */ #include "TrieHash.h" - -#include -#include +#include +#include // @TODO replace ASAP! +#include #include using namespace std; using namespace dev; @@ -158,43 +158,40 @@ void hash256aux(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_i } } -h256 hash256(StringMap const& _s) +bytes rlp256(BytesMap const& _s) { // build patricia tree. if (_s.empty()) - return sha3(rlp("")); + return rlp(""); HexMap hexMap; for (auto i = _s.rbegin(); i != _s.rend(); ++i) - hexMap[asNibbles(i->first)] = i->second; + hexMap[asNibbles(bytesConstRef(&i->first))] = i->second; RLPStream s; hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s); - return sha3(s.out()); + return s.out(); } -bytes rlp256(StringMap const& _s) +h256 hash256(BytesMap const& _s) { - // build patricia tree. - if (_s.empty()) - return rlp(""); - HexMap hexMap; - for (auto i = _s.rbegin(); i != _s.rend(); ++i) - hexMap[asNibbles(i->first)] = i->second; - RLPStream s; - hash256aux(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s); - return s.out(); + return sha3(rlp256(_s)); } -h256 hash256(u256Map const& _s) +h256 orderedTrieRoot(std::vector const& _data) { - // build patricia tree. - if (_s.empty()) - return sha3(rlp("")); - HexMap hexMap; - for (auto i = _s.rbegin(); i != _s.rend(); ++i) - hexMap[asNibbles(toBigEndianString(i->first))] = asString(rlp(i->second)); - RLPStream s; - hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s); - return sha3(s.out()); + BytesMap m; + unsigned j = 0; + for (auto i: _data) + m[rlp(j++)] = i; + return hash256(m); +} + +h256 orderedTrieRoot(std::vector const& _data) +{ + BytesMap m; + unsigned j = 0; + for (auto i: _data) + m[rlp(j++)] = i.toBytes(); + return hash256(m); } } diff --git a/libdevcore/TrieHash.h b/libdevcore/TrieHash.h new file mode 100644 index 000000000..9649ef0c7 --- /dev/null +++ b/libdevcore/TrieHash.h @@ -0,0 +1,46 @@ +/* + 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 TrieHash.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include + +namespace dev +{ + +bytes rlp256(BytesMap const& _s); +h256 hash256(BytesMap const& _s); + +h256 orderedTrieRoot(std::vector const& _data); + +template inline h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue) +{ + BytesMap m; + for (unsigned i = 0; i < _itemCount; ++i) + m[_getKey(i)] = _getValue(i); + return hash256(m); +} + +h256 orderedTrieRoot(std::vector const& _data); +h256 orderedTrieRoot(std::vector const& _data); + +} diff --git a/libdevcore/Worker.cpp b/libdevcore/Worker.cpp index 7d790ccf6..ab19b2f74 100644 --- a/libdevcore/Worker.cpp +++ b/libdevcore/Worker.cpp @@ -65,15 +65,15 @@ void Worker::startWorking() m_state.exchange(ex); // cnote << "Waiting until not Stopped..."; - DEV_TIMED_IF(Worker stopping, 100) + DEV_TIMED_ABOVE(Worker stopping, 100) while (m_state == WorkerState::Stopped) this_thread::sleep_for(chrono::milliseconds(20)); } })); // cnote << "Spawning" << m_name; } - DEV_TIMED_IF(Start worker, 100) - while (m_state != WorkerState::Started) + DEV_TIMED_ABOVE(Start worker, 100) + while (m_state == WorkerState::Starting) this_thread::sleep_for(chrono::microseconds(20)); } @@ -85,7 +85,7 @@ void Worker::stopWorking() WorkerState ex = WorkerState::Started; m_state.compare_exchange_strong(ex, WorkerState::Stopping); - DEV_TIMED_IF(Stop worker, 100) + DEV_TIMED_ABOVE(Stop worker, 100) while (m_state != WorkerState::Stopped) this_thread::sleep_for(chrono::microseconds(20)); } @@ -99,7 +99,7 @@ void Worker::terminate() { m_state.exchange(WorkerState::Killing); - DEV_TIMED_IF(Terminate worker, 100) + DEV_TIMED_ABOVE(Terminate worker, 100) m_work->join(); m_work.reset(); diff --git a/libdevcore/picosha2.h b/libdevcore/picosha2.h new file mode 100644 index 000000000..44b6bee59 --- /dev/null +++ b/libdevcore/picosha2.h @@ -0,0 +1,360 @@ +/* +The MIT License (MIT) + +Copyright (C) 2014 okdshin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#ifndef PICOSHA2_H +#define PICOSHA2_H +//picosha2:20140213 +#include +#include +#include +#include +#include +#include +#include + +namespace picosha2 +{ + +namespace detail +{ + +inline uint8_t mask_8bit(uint8_t x){ + return x&0xff; +} + +inline uint32_t mask_32bit(uint32_t x){ + return x&0xffffffff; +} + +static const uint32_t add_constant[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +static const uint32_t initial_message_digest[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 +}; + +inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z){ + return (x&y)^((~x)&z); +} + +inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z){ + return (x&y)^(x&z)^(y&z); +} + +inline uint32_t rotr(uint32_t x, std::size_t n){ + assert(n < 32); + return mask_32bit((x>>n)|(x<<(32-n))); +} + +inline uint32_t bsig0(uint32_t x){ + return rotr(x, 2)^rotr(x, 13)^rotr(x, 22); +} + +inline uint32_t bsig1(uint32_t x){ + return rotr(x, 6)^rotr(x, 11)^rotr(x, 25); +} + +inline uint32_t shr(uint32_t x, std::size_t n){ + assert(n < 32); + return x >> n; +} + +inline uint32_t ssig0(uint32_t x){ + return rotr(x, 7)^rotr(x, 18)^shr(x, 3); +} + +inline uint32_t ssig1(uint32_t x){ + return rotr(x, 17)^rotr(x, 19)^shr(x, 10); +} + +template +void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last){ + (void)last; // FIXME: check this is valid + uint32_t w[64]; + std::fill(w, w+64, 0); + for(std::size_t i = 0; i < 16; ++i){ + w[i] = (static_cast(mask_8bit(*(first+i*4)))<<24) + |(static_cast(mask_8bit(*(first+i*4+1)))<<16) + |(static_cast(mask_8bit(*(first+i*4+2)))<<8) + |(static_cast(mask_8bit(*(first+i*4+3)))); + } + for(std::size_t i = 16; i < 64; ++i){ + w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]); + } + + uint32_t a = *message_digest; + uint32_t b = *(message_digest+1); + uint32_t c = *(message_digest+2); + uint32_t d = *(message_digest+3); + uint32_t e = *(message_digest+4); + uint32_t f = *(message_digest+5); + uint32_t g = *(message_digest+6); + uint32_t h = *(message_digest+7); + + for(std::size_t i = 0; i < 64; ++i){ + uint32_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i]; + uint32_t temp2 = bsig0(a)+maj(a,b,c); + h = g; + g = f; + f = e; + e = mask_32bit(d+temp1); + d = c; + c = b; + b = a; + a = mask_32bit(temp1+temp2); + } + *message_digest += a; + *(message_digest+1) += b; + *(message_digest+2) += c; + *(message_digest+3) += d; + *(message_digest+4) += e; + *(message_digest+5) += f; + *(message_digest+6) += g; + *(message_digest+7) += h; + for(std::size_t i = 0; i < 8; ++i){ + *(message_digest+i) = mask_32bit(*(message_digest+i)); + } +} + +}//namespace detail + +template +void output_hex(InIter first, InIter last, std::ostream& os){ + os.setf(std::ios::hex, std::ios::basefield); + while(first != last){ + os.width(2); + os.fill('0'); + os << static_cast(*first); + ++first; + } + os.setf(std::ios::dec, std::ios::basefield); +} + +template +void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){ + std::ostringstream oss; + output_hex(first, last, oss); + hex_str.assign(oss.str()); +} + +template +void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){ + bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str); +} + +template +std::string bytes_to_hex_string(InIter first, InIter last){ + std::string hex_str; + bytes_to_hex_string(first, last, hex_str); + return hex_str; +} + +template +std::string bytes_to_hex_string(const InContainer& bytes){ + std::string hex_str; + bytes_to_hex_string(bytes, hex_str); + return hex_str; +} + +class hash256_one_by_one { +public: + hash256_one_by_one(){ + init(); + } + + void init(){ + buffer_.clear(); + std::fill(data_length_digits_, data_length_digits_+4, 0); + std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_); + } + + template + void process(RaIter first, RaIter last){ + add_to_data_length(std::distance(first, last)); + std::copy(first, last, std::back_inserter(buffer_)); + std::size_t i = 0; + for(;i+64 <= buffer_.size(); i+=64){ + detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64); + } + buffer_.erase(buffer_.begin(), buffer_.begin()+i); + } + + void finish(){ + uint8_t temp[64]; + std::fill(temp, temp+64, 0); + std::size_t remains = buffer_.size(); + std::copy(buffer_.begin(), buffer_.end(), temp); + temp[remains] = 0x80; + + if(remains > 55){ + std::fill(temp+remains+1, temp+64, 0); + detail::hash256_block(h_, temp, temp+64); + std::fill(temp, temp+64-4, 0); + } + else { + std::fill(temp+remains+1, temp+64-4, 0); + } + + write_data_bit_length(&(temp[56])); + detail::hash256_block(h_, temp, temp+64); + } + + template + void get_hash_bytes(OutIter first, OutIter last)const{ + for(const uint32_t* iter = h_; iter != h_+8; ++iter){ + for(std::size_t i = 0; i < 4 && first != last; ++i){ + *(first++) = detail::mask_8bit(static_cast((*iter >> (24-8*i)))); + } + } + } + +private: + void add_to_data_length(uint32_t n) { + uint32_t carry = 0; + data_length_digits_[0] += n; + for(std::size_t i = 0; i < 4; ++i) { + data_length_digits_[i] += carry; + if(data_length_digits_[i] >= 65536u) { + data_length_digits_[i] -= 65536u; + carry = 1; + } + else { + break; + } + } + } + void write_data_bit_length(uint8_t* begin) { + uint32_t data_bit_length_digits[4]; + std::copy( + data_length_digits_, data_length_digits_+4, + data_bit_length_digits + ); + + // convert byte length to bit length (multiply 8 or shift 3 times left) + uint32_t carry = 0; + for(std::size_t i = 0; i < 4; ++i) { + uint32_t before_val = data_bit_length_digits[i]; + data_bit_length_digits[i] <<= 3; + data_bit_length_digits[i] |= carry; + data_bit_length_digits[i] &= 65535u; + carry = (before_val >> (16-3)) & 65535u; + } + + // write data_bit_length + for(int i = 3; i >= 0; --i) { + (*begin++) = static_cast(data_bit_length_digits[i] >> 8); + (*begin++) = static_cast(data_bit_length_digits[i]); + } + } + std::vector buffer_; + uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer) + uint32_t h_[8]; +}; + +inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){ + uint8_t hash[32]; + hasher.get_hash_bytes(hash, hash+32); + return bytes_to_hex_string(hash, hash+32, hex_str); +} + +inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){ + std::string hex_str; + get_hash_hex_string(hasher, hex_str); + return hex_str; +} + +template +void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){ + hash256_one_by_one hasher; + //hasher.init(); + hasher.process(first, last); + hasher.finish(); + hasher.get_hash_bytes(first2, last2); +} + +template +void hash256(RaIter first, RaIter last, OutContainer& dst){ + hash256(first, last, dst.begin(), dst.end()); +} + +template +void hash256(const RaContainer& src, OutIter first, OutIter last){ + hash256(src.begin(), src.end(), first, last); +} + +template +void hash256(const RaContainer& src, OutContainer& dst){ + hash256(src.begin(), src.end(), dst.begin(), dst.end()); +} + + +template +void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){ + uint8_t hashed[32]; + hash256(first, last, hashed, hashed+32); + std::ostringstream oss; + output_hex(hashed, hashed+32, oss); + hex_str.assign(oss.str()); +} + +template +std::string hash256_hex_string(RaIter first, RaIter last){ + std::string hex_str; + hash256_hex_string(first, last, hex_str); + return hex_str; +} + +inline void hash256_hex_string(const std::string& src, std::string& hex_str){ + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +void hash256_hex_string(const RaContainer& src, std::string& hex_str){ + hash256_hex_string(src.begin(), src.end(), hex_str); +} + +template +std::string hash256_hex_string(const RaContainer& src){ + return hash256_hex_string(src.begin(), src.end()); +} + +}//namespace picosha2 + +#endif //PICOSHA2_H diff --git a/libdevcrypto/AES.cpp b/libdevcrypto/AES.cpp index 56885ae36..e9edac0d3 100644 --- a/libdevcrypto/AES.cpp +++ b/libdevcrypto/AES.cpp @@ -19,9 +19,9 @@ * @date 2014 */ -#include "CryptoPP.h" #include "AES.h" - +#include +#include "CryptoPP.h" using namespace std; using namespace dev; using namespace dev::crypto; @@ -58,3 +58,31 @@ size_t Stream::streamOut(bytes&) return 0; } +bytes dev::aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt) +{ + bytes pw = asBytes(_password); + + if (!_salt.size()) + _salt = &pw; + + bytes target(64); + CryptoPP::PKCS5_PBKDF2_HMAC().DeriveKey(target.data(), target.size(), 0, pw.data(), pw.size(), _salt.data(), _salt.size(), _rounds); + + try + { + CryptoPP::AES::Decryption aesDecryption(target.data(), 16); + auto cipher = _ivCipher.cropped(16); + auto iv = _ivCipher.cropped(0, 16); + CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data()); + std::string decrypted; + CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted)); + stfDecryptor.Put(cipher.data(), cipher.size()); + stfDecryptor.MessageEnd(); + return asBytes(decrypted); + } + catch (exception const& e) + { + cerr << e.what() << endl; + return bytes(); + } +} diff --git a/libdevcrypto/AES.h b/libdevcrypto/AES.h index f0646eb85..32d1880dc 100644 --- a/libdevcrypto/AES.h +++ b/libdevcrypto/AES.h @@ -86,4 +86,7 @@ private: } } -} \ No newline at end of file + +bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef()); + +} diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index a5c176fe6..87e258573 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -26,8 +26,9 @@ #include #include #include -#include "SHA3.h" -#include "FileSystem.h" +#include +#include +#include "AES.h" #include "CryptoPP.h" using namespace std; using namespace dev; diff --git a/libdevcrypto/CryptoPP.h b/libdevcrypto/CryptoPP.h index 4991e3713..ca8a2e6b5 100644 --- a/libdevcrypto/CryptoPP.h +++ b/libdevcrypto/CryptoPP.h @@ -49,7 +49,7 @@ #include #pragma warning(pop) #pragma GCC diagnostic pop -#include "SHA3.h" +#include #include "Common.h" namespace dev diff --git a/libdevcrypto/ECDHE.cpp b/libdevcrypto/ECDHE.cpp index a00a92872..a5aaf3984 100644 --- a/libdevcrypto/ECDHE.cpp +++ b/libdevcrypto/ECDHE.cpp @@ -19,9 +19,9 @@ * @date 2014 */ -#include "SHA3.h" -#include "CryptoPP.h" #include "ECDHE.h" +#include +#include "CryptoPP.h" using namespace std; using namespace dev; diff --git a/libdevcrypto/OverlayDB.cpp b/libdevcrypto/OverlayDB.cpp index 87c8a0927..80c901635 100644 --- a/libdevcrypto/OverlayDB.cpp +++ b/libdevcrypto/OverlayDB.cpp @@ -19,6 +19,7 @@ * @date 2014 */ +#include #include #include #include @@ -29,42 +30,72 @@ using namespace dev; namespace dev { +h256 const EmptyTrie = sha3(rlp("")); + OverlayDB::~OverlayDB() { if (m_db.use_count() == 1 && m_db.get()) cnote << "Closing state DB"; } +class WriteBatchNoter: public ldb::WriteBatch::Handler +{ + virtual void Put(ldb::Slice const& _key, ldb::Slice const& _value) { cnote << "Put" << toHex(bytesConstRef(_key)) << "=>" << toHex(bytesConstRef(_value)); } + virtual void Delete(ldb::Slice const& _key) { cnote << "Delete" << toHex(bytesConstRef(_key)); } +}; + void OverlayDB::commit() { if (m_db) { ldb::WriteBatch batch; // cnote << "Committing nodes to disk DB:"; - for (auto const& i: m_main) + DEV_READ_GUARDED(x_this) { -// cnote << i.first << "#" << m_main[i.first].second; - if (i.second.second) - batch.Put(ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.first.data(), i.second.first.size())); + for (auto const& i: m_main) + { + if (i.second.second) + batch.Put(ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.first.data(), i.second.first.size())); +// cnote << i.first << "#" << m_main[i.first].second; + } + for (auto const& i: m_aux) + if (i.second.second) + { + bytes b = i.first.asBytes(); + b.push_back(255); // for aux + batch.Put(bytesConstRef(&b), bytesConstRef(&i.second.first)); + } } - for (auto const& i: m_aux) - if (i.second.second) + + for (unsigned i = 0; i < 10; ++i) + { + ldb::Status o = m_db->Write(m_writeOptions, &batch); + if (o.ok()) + break; + if (i == 9) { - bytes b = i.first.asBytes(); - b.push_back(255); // for aux - batch.Put(bytesConstRef(&b), bytesConstRef(&i.second.first)); + cwarn << "Fail writing to state database. Bombing out."; + exit(-1); } - m_db->Write(m_writeOptions, &batch); - m_aux.clear(); - m_main.clear(); + cwarn << "Error writing to state database: " << o.ToString(); + WriteBatchNoter n; + batch.Iterate(&n); + cwarn << "Sleeping for" << (i + 1) << "seconds, then retrying."; + this_thread::sleep_for(chrono::seconds(i + 1)); + } + DEV_WRITE_GUARDED(x_this) + { + m_aux.clear(); + m_main.clear(); + } } } -bytes OverlayDB::lookupAux(h256 _h) const +bytes OverlayDB::lookupAux(h256 const& _h) const { bytes ret = MemoryDB::lookupAux(_h); - if (!ret.empty()) - return ret; + if (!ret.empty() || !m_db) + return move(ret); std::string v; bytes b = _h.asBytes(); b.push_back(255); // for aux @@ -76,18 +107,19 @@ bytes OverlayDB::lookupAux(h256 _h) const void OverlayDB::rollback() { + WriteGuard l(x_this); m_main.clear(); } -std::string OverlayDB::lookup(h256 _h) const +std::string OverlayDB::lookup(h256 const& _h) const { std::string ret = MemoryDB::lookup(_h); if (ret.empty() && m_db) m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); - return ret; + return move(ret); } -bool OverlayDB::exists(h256 _h) const +bool OverlayDB::exists(h256 const& _h) const { if (MemoryDB::exists(_h)) return true; @@ -97,16 +129,20 @@ bool OverlayDB::exists(h256 _h) const return !ret.empty(); } -void OverlayDB::kill(h256 _h) +void OverlayDB::kill(h256 const& _h) { -#if ETH_PARANOIA +#if ETH_PARANOIA || 1 if (!MemoryDB::kill(_h)) { std::string ret; if (m_db) m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret); - if (ret.empty()) + // No point node ref decreasing for EmptyTrie since we never bother incrementing it in the first place for + // empty storage tries. + if (ret.empty() && _h != EmptyTrie) cnote << "Decreasing DB node ref count below zero with no DB node. Probably have a corrupt Trie." << _h; + + // TODO: for 1.1: ref-counted triedb. } #else MemoryDB::kill(_h); diff --git a/libdevcrypto/OverlayDB.h b/libdevcrypto/OverlayDB.h index 7f7736ac1..b37d2c11b 100644 --- a/libdevcrypto/OverlayDB.h +++ b/libdevcrypto/OverlayDB.h @@ -29,7 +29,7 @@ #include #include #include -#include "MemoryDB.h" +#include namespace ldb = leveldb; namespace dev @@ -46,11 +46,11 @@ public: void commit(); void rollback(); - std::string lookup(h256 _h) const; - bool exists(h256 _h) const; - void kill(h256 _h); + std::string lookup(h256 const& _h) const; + bool exists(h256 const& _h) const; + void kill(h256 const& _h); - bytes lookupAux(h256 _h) const; + bytes lookupAux(h256 const& _h) const; private: using MemoryDB::clear; diff --git a/libdevcrypto/SHA3.cpp b/libdevcrypto/SHA3.cpp deleted file mode 100644 index b7a47b745..000000000 --- a/libdevcrypto/SHA3.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - 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 SHA3.cpp - * @author Gav Wood - * @date 2014 - */ - -#include "SHA3.h" - -#include -#include "CryptoPP.h" -using namespace std; -using namespace dev; - -namespace dev -{ - -h256 EmptySHA3 = sha3(bytesConstRef()); -h256 EmptyListSHA3 = sha3(rlpList()); - -std::string sha3(std::string const& _input, bool _hex) -{ - if (!_hex) - { - string ret(32, '\0'); - sha3(bytesConstRef((byte const*)_input.data(), _input.size()), bytesRef((byte*)ret.data(), 32)); - return ret; - } - - uint8_t buf[32]; - sha3(bytesConstRef((byte const*)_input.data(), _input.size()), bytesRef((byte*)&(buf[0]), 32)); - std::string ret(64, '\0'); - for (unsigned int i = 0; i < 32; i++) - sprintf((char*)(ret.data())+i*2, "%02x", buf[i]); - return ret; -} - -void sha3(bytesConstRef _input, bytesRef _output) -{ - CryptoPP::SHA3_256 ctx; - ctx.Update((byte*)_input.data(), _input.size()); - assert(_output.size() >= 32); - ctx.Final(_output.data()); -} - -void ripemd160(bytesConstRef _input, bytesRef _output) -{ - CryptoPP::RIPEMD160 ctx; - ctx.Update((byte*)_input.data(), _input.size()); - assert(_output.size() >= 32); - ctx.Final(_output.data()); -} - -void sha256(bytesConstRef _input, bytesRef _output) -{ - CryptoPP::SHA256 ctx; - ctx.Update((byte*)_input.data(), _input.size()); - assert(_output.size() >= 32); - ctx.Final(_output.data()); -} - -bytes sha3Bytes(bytesConstRef _input) -{ - bytes ret(32); - sha3(_input, &ret); - return ret; -} - -h256 sha3(bytesConstRef _input) -{ - h256 ret; - sha3(_input, bytesRef(&ret[0], 32)); - return ret; -} - -void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) -{ - CryptoPP::SHA3_256 ctx; - assert(_secret.size() > 0); - ctx.Update((byte*)_secret.data(), _secret.size()); - ctx.Update((byte*)_plain.data(), _plain.size()); - assert(_output.size() >= 32); - ctx.Final(_output.data()); -} - -bytes aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt) -{ - bytes pw = asBytes(_password); - - if (!_salt.size()) - _salt = &pw; - - bytes target(64); - CryptoPP::PKCS5_PBKDF2_HMAC().DeriveKey(target.data(), target.size(), 0, pw.data(), pw.size(), _salt.data(), _salt.size(), _rounds); - - try - { - CryptoPP::AES::Decryption aesDecryption(target.data(), 16); - auto cipher = _ivCipher.cropped(16); - auto iv = _ivCipher.cropped(0, 16); - CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data()); - std::string decrypted; - CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted)); - stfDecryptor.Put(cipher.data(), cipher.size()); - stfDecryptor.MessageEnd(); - return asBytes(decrypted); - } - catch (exception const& e) - { - cerr << e.what() << endl; - return bytes(); - } -} - -} diff --git a/libdevcrypto/SecretStore.cpp b/libdevcrypto/SecretStore.cpp index 9be0b89e8..0416aa9f4 100644 --- a/libdevcrypto/SecretStore.cpp +++ b/libdevcrypto/SecretStore.cpp @@ -25,9 +25,9 @@ #include #include #include +#include +#include #include -#include "SHA3.h" -#include "FileSystem.h" using namespace std; using namespace dev; namespace js = json_spirit; diff --git a/libdevcrypto/SecretStore.h b/libdevcrypto/SecretStore.h index 1fb6adf4a..18c290c1f 100644 --- a/libdevcrypto/SecretStore.h +++ b/libdevcrypto/SecretStore.h @@ -24,8 +24,8 @@ #include #include #include +#include #include "Common.h" -#include "FileSystem.h" namespace dev { diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 79efbcb97..be17ba449 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -61,6 +61,11 @@ ethash_cl_miner::ethash_cl_miner() { } +ethash_cl_miner::~ethash_cl_miner() +{ + finish(); +} + std::string ethash_cl_miner::platform_info(unsigned _platformId, unsigned _deviceId) { std::vector platforms; @@ -201,14 +206,15 @@ bool ethash_cl_miner::init(uint8_t const* _dag, uint64_t _dagSize, unsigned work m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32); // compute dag on CPU - { + try { m_queue.enqueueWriteBuffer(m_dag, CL_TRUE, 0, _dagSize, _dag); - - // if this throws then it's because we probably need to subdivide the dag uploads for compatibility -// void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, _dagSize); - // memcpying 1GB: horrible... really. horrible. but necessary since we can't mmap *and* gpumap. -// _fillDAG(dag_ptr); -// m_queue.enqueueUnmapMemObject(m_dag, dag_ptr); + } + catch (...) + { + // didn't work. shitty driver. try allocating in CPU RAM and manually memcpying it. + void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, _dagSize); + memcpy(dag_ptr, _dag, _dagSize); + m_queue.enqueueUnmapMemObject(m_dag, dag_ptr); } // create mining buffers diff --git a/libethash-cl/ethash_cl_miner.h b/libethash-cl/ethash_cl_miner.h index 2fb192c3f..43bfa2336 100644 --- a/libethash-cl/ethash_cl_miner.h +++ b/libethash-cl/ethash_cl_miner.h @@ -30,6 +30,7 @@ public: public: ethash_cl_miner(); + ~ethash_cl_miner(); static unsigned get_num_platforms(); static unsigned get_num_devices(unsigned _platformId = 0); diff --git a/libethash/CMakeLists.txt b/libethash/CMakeLists.txt index a65621c3e..d6ae41569 100644 --- a/libethash/CMakeLists.txt +++ b/libethash/CMakeLists.txt @@ -42,3 +42,5 @@ add_library(${LIBRARY} ${FILES}) if (CRYPTOPP_FOUND) TARGET_LINK_LIBRARIES(${LIBRARY} ${CRYPTOPP_LIBRARIES}) endif() + +install( TARGETS ${LIBRARY} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) diff --git a/libethash/io_posix.c b/libethash/io_posix.c index 7f03d5482..c9a17d845 100644 --- a/libethash/io_posix.c +++ b/libethash/io_posix.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include FILE* ethash_fopen(char const* file_name, char const* mode) { @@ -89,6 +91,13 @@ bool ethash_get_default_dirname(char* strbuf, size_t buffsize) static const char dir_suffix[] = ".ethash/"; strbuf[0] = '\0'; char* home_dir = getenv("HOME"); + if (!home_dir || strlen(home_dir) == 0) + { + struct passwd* pwd = getpwuid(getuid()); + if (pwd) + home_dir = pwd->pw_dir; + } + size_t len = strlen(home_dir); if (!ethash_strncat(strbuf, buffsize, home_dir, len)) { return false; diff --git a/libethash/io_win32.c b/libethash/io_win32.c index 2e6c8deb8..34f1aaa77 100644 --- a/libethash/io_win32.c +++ b/libethash/io_win32.c @@ -87,9 +87,9 @@ bool ethash_file_size(FILE* f, size_t* ret_size) bool ethash_get_default_dirname(char* strbuf, size_t buffsize) { - static const char dir_suffix[] = "Appdata\\Ethash\\"; + static const char dir_suffix[] = "Ethash\\"; strbuf[0] = '\0'; - if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, (WCHAR*)strbuf))) { + if (!SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, (CHAR*)strbuf))) { return false; } if (!ethash_strncat(strbuf, buffsize, "\\", 1)) { diff --git a/libethcore/ABI.h b/libethcore/ABI.h index 7fca09c9a..09aca6754 100644 --- a/libethcore/ABI.h +++ b/libethcore/ABI.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace dev { diff --git a/libethcore/BlockInfo.cpp b/libethcore/BlockInfo.cpp index eb64593af..0e125b607 100644 --- a/libethcore/BlockInfo.cpp +++ b/libethcore/BlockInfo.cpp @@ -21,7 +21,8 @@ #include #include -#include +#include +#include #include #include #include "EthashAux.h" @@ -173,6 +174,9 @@ void BlockInfo::populateFromHeader(RLP const& _header, Strictness _s, h256 const void BlockInfo::populate(bytesConstRef _block, Strictness _s, h256 const& _h) { RLP root(_block); + if (!root.isList()) + BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block needs to be a list") << BadFieldError(0, _block.toString())); + RLP header = root[0]; if (!header.isList()) @@ -185,16 +189,6 @@ void BlockInfo::populate(bytesConstRef _block, Strictness _s, h256 const& _h) BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block uncles need to be a list") << BadFieldError(2, root[2].data().toString())); } -template h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue) -{ - MemoryDB db; - GenericTrieDB t(&db); - t.init(); - for (unsigned i = 0; i < _itemCount; ++i) - t.insert(_getKey(i), _getValue(i)); - return t.root(); -} - struct BlockInfoDiagnosticsChannel: public LogChannel { static const char* name() { return EthBlue "▧" EthWhite " ◌"; } static const int verbosity = 9; }; void BlockInfo::verifyInternals(bytesConstRef _block) const @@ -202,10 +196,36 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const RLP root(_block); auto txList = root[1]; - auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data(); }); + auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data().toBytes(); }); + clog(BlockInfoDiagnosticsChannel) << "Expected trie root:" << toString(expectedRoot); if (transactionsRoot != expectedRoot) + { + MemoryDB tm; + GenericTrieDB transactionsTrie(&tm); + transactionsTrie.init(); + + vector txs; + + for (unsigned i = 0; i < txList.itemCount(); ++i) + { + RLPStream k; + k << i; + + transactionsTrie.insert(&k.out(), txList[i].data()); + + txs.push_back(txList[i].data()); + cdebug << toHex(k.out()) << toHex(txList[i].data()); + } + cdebug << "trieRootOver" << expectedRoot; + cdebug << "orderedTrieRoot" << orderedTrieRoot(txs); + cdebug << "TrieDB" << transactionsTrie.root(); + cdebug << "Contents:"; + for (auto const& t: txs) + cdebug << toHex(t); + BOOST_THROW_EXCEPTION(InvalidTransactionsHash() << HashMismatchError(expectedRoot, transactionsRoot)); + } clog(BlockInfoDiagnosticsChannel) << "Expected uncle hash:" << toString(sha3(root[2].data())); if (sha3Uncles != sha3(root[2].data())) BOOST_THROW_EXCEPTION(InvalidUnclesHash()); @@ -228,7 +248,10 @@ u256 BlockInfo::selectGasLimit(BlockInfo const& _parent) const return c_genesisGasLimit; else // target minimum of 3141592 - return max(max(c_minGasLimit, 3141592), _parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor + 1 + (_parent.gasUsed * 6 / 5) / c_gasLimitBoundDivisor); + if (_parent.gasLimit < c_genesisGasLimit) + return min(c_genesisGasLimit, _parent.gasLimit + _parent.gasLimit / c_gasLimitBoundDivisor - 1); + else + return max(c_genesisGasLimit, _parent.gasLimit - _parent.gasLimit / c_gasLimitBoundDivisor + 1 + (_parent.gasUsed * 6 / 5) / c_gasLimitBoundDivisor); } u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 4dd626642..a527ad1f4 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -28,7 +28,7 @@ add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} ethash) target_link_libraries(${EXECUTABLE} devcrypto) -target_link_libraries(${EXECUTABLE} evmcore) +#target_link_libraries(${EXECUTABLE} evmcore) if (ETHASHCL) target_link_libraries(${EXECUTABLE} ethash-cl) diff --git a/libethcore/Common.cpp b/libethcore/Common.cpp index 2c7601dbc..56db647f3 100644 --- a/libethcore/Common.cpp +++ b/libethcore/Common.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "Exceptions.h" #include "ProofOfWork.h" using namespace std; @@ -36,11 +36,13 @@ namespace eth { const unsigned c_protocolVersion = 60; -const unsigned c_minorProtocolVersion = 2; -const unsigned c_databaseBaseVersion = 9; #if ETH_FATDB +const unsigned c_minorProtocolVersion = 3; +const unsigned c_databaseBaseVersion = 9; const unsigned c_databaseVersionModifier = 1; #else +const unsigned c_minorProtocolVersion = 2; +const unsigned c_databaseBaseVersion = 9; const unsigned c_databaseVersionModifier = 0; #endif diff --git a/libethcore/Common.h b/libethcore/Common.h index 8855bc3a7..2cb505905 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -100,9 +100,10 @@ struct ImportRequirements using value = unsigned; enum { - ValidNonce = 1, ///< Validate Nonce + ValidNonce = 1, ///< Validate nonce DontHave = 2, ///< Avoid old blocks - Default = ValidNonce | DontHave + CheckUncles = 4, ///< Check uncle nonces + Default = ValidNonce | DontHave | CheckUncles }; }; diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index db1a17b0a..228f03f8e 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #if ETH_ETHASHCL || !ETH_TRUE @@ -72,13 +72,19 @@ Ethash::WorkPackage Ethash::package(BlockInfo const& _bi) ret.boundary = _bi.boundary(); ret.headerHash = _bi.headerHash(WithoutNonce); ret.seedHash = _bi.seedHash(); - ret.blockNumber = (uint64_t) _bi.number; return ret; } -void Ethash::prep(BlockInfo const& _header) +void Ethash::ensurePrecomputed(unsigned _number) { - EthashAux::full(_header); + if (_number % ETHASH_EPOCH_LENGTH > ETHASH_EPOCH_LENGTH * 9 / 10) + // 90% of the way to the new epoch + EthashAux::computeFull(EthashAux::seedHash(_number + ETHASH_EPOCH_LENGTH), true); +} + +void Ethash::prep(BlockInfo const& _header, std::function const& _f) +{ + EthashAux::full(_header.seedHash(), true, _f); } bool Ethash::preVerify(BlockInfo const& _header) @@ -135,7 +141,10 @@ void Ethash::CPUMiner::workLoop() WorkPackage w = work(); - auto dag = EthashAux::full(w.blockNumber); + EthashAux::FullType dag; + while (!shouldStop() && !(dag = EthashAux::full(w.seedHash))) + this_thread::sleep_for(chrono::milliseconds(500)); + h256 boundary = w.boundary; unsigned hashCount = 1; for (; !shouldStop(); tryNonce++, hashCount++) @@ -144,8 +153,8 @@ void Ethash::CPUMiner::workLoop() h256 value = h256((uint8_t*)ðashReturn.result, h256::ConstructFromPointer); if (value <= boundary && submitProof(Solution{(Nonce)(u64)tryNonce, h256((uint8_t*)ðashReturn.mix_hash, h256::ConstructFromPointer)})) break; - if (!(hashCount % 1000)) - accumulateHashes(1000); + if (!(hashCount % 100)) + accumulateHashes(100); } } @@ -284,7 +293,7 @@ Ethash::GPUMiner::~GPUMiner() bool Ethash::GPUMiner::report(uint64_t _nonce) { Nonce n = (Nonce)(u64)_nonce; - Result r = EthashAux::eval(work().blockNumber, work().headerHash, n); + Result r = EthashAux::eval(work().seedHash, work().headerHash, n); if (r.value < work().boundary) return submitProof(Solution{n, r.mixHash}); return false; @@ -301,8 +310,10 @@ void Ethash::GPUMiner::workLoop() // take local copy of work since it may end up being overwritten by kickOff/pause. try { WorkPackage w = work(); + cnote << "workLoop" << !!m_miner << m_minerSeed << w.seedHash; if (!m_miner || m_minerSeed != w.seedHash) { + cnote << "Initialising miner..."; m_minerSeed = w.seedHash; delete m_miner; @@ -310,7 +321,19 @@ void Ethash::GPUMiner::workLoop() unsigned device = instances() > 1 ? index() : s_deviceId; - EthashAux::FullType dag = EthashAux::full(w.blockNumber); + EthashAux::FullType dag; + while (true) + { + if ((dag = EthashAux::full(w.seedHash, false))) + break; + if (shouldStop()) + { + delete m_miner; + return; + } + cnote << "Awaiting DAG"; + this_thread::sleep_for(chrono::milliseconds(500)); + } bytesConstRef dagData = dag->data(); m_miner->init(dagData.data(), dagData.size(), 32, s_platformId, device); } @@ -318,9 +341,9 @@ void Ethash::GPUMiner::workLoop() uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); m_miner->search(w.headerHash.data(), upper64OfBoundary, *m_hook); } - catch (...) + catch (cl::Error const& _e) { - cwarn << "Error GPU mining. GPU memory fragmentation?"; + cwarn << "Error GPU mining: " << _e.what() << "(" << _e.err() << ")"; } } diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h index 1fcab55de..86540678f 100644 --- a/libethcore/Ethash.h +++ b/libethcore/Ethash.h @@ -66,20 +66,19 @@ public: h256 boundary; h256 headerHash; ///< When h256() means "pause until notified a new work package is available". - h256 seedHash; /// LTODO: IS this needed now that we use the block number instead? - uint64_t blockNumber; + h256 seedHash; }; static const WorkPackage NullWorkPackage; static std::string name(); static unsigned revision(); - static void prep(BlockInfo const& _header); + static void prep(BlockInfo const& _header, std::function const& _f = std::function()); + static void ensurePrecomputed(unsigned _number); static bool verify(BlockInfo const& _header); static bool preVerify(BlockInfo const& _header); static WorkPackage package(BlockInfo const& _header); static void assignResult(Solution const& _r, BlockInfo& _header) { _header.nonce = _r.nonce; _header.mixHash = _r.mixHash; } - class CPUMiner: public Miner, Worker { @@ -120,7 +119,7 @@ public: static void setDefaultPlatform(unsigned _id) { s_platformId = _id; } static void setDefaultDevice(unsigned _id) { s_deviceId = _id; } static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, getNumDevices()); } - + protected: void kickOff() override; void pause() override; diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 210f70c78..a94c1237d 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -31,8 +31,8 @@ #include #include #include -#include -#include +#include +#include #include #include "BlockInfo.h" #include "Exceptions.h" @@ -41,6 +41,8 @@ using namespace chrono; using namespace dev; using namespace eth; +const char* DAGChannel::name() { return EthGreen "DAG"; } + EthashAux* dev::eth::EthashAux::s_this = nullptr; EthashAux::~EthashAux() @@ -76,29 +78,47 @@ h256 EthashAux::seedHash(unsigned _number) return get()->m_seedHashes[epoch]; } -void EthashAux::killCache(h256 const& _s) +uint64_t EthashAux::number(h256 const& _seedHash) { - RecursiveGuard l(x_this); - m_lights.erase(_s); + Guard l(get()->x_epochs); + unsigned epoch = 0; + auto epochIter = get()->m_epochs.find(_seedHash); + if (epochIter == get()->m_epochs.end()) + { + // cdebug << "Searching for seedHash " << _seedHash; + for (h256 h; h != _seedHash && epoch < 2048; ++epoch, h = sha3(h), get()->m_epochs[h] = epoch) {} + if (epoch == 2048) + { + std::ostringstream error; + error << "apparent block number for " << _seedHash << " is too high; max is " << (ETHASH_EPOCH_LENGTH * 2048); + throw std::invalid_argument(error.str()); + } + } + else + epoch = epochIter->second; + return epoch * ETHASH_EPOCH_LENGTH; } -EthashAux::LightType EthashAux::light(BlockInfo const& _header) +void EthashAux::killCache(h256 const& _s) { - return light((uint64_t)_header.number); + WriteGuard l(x_lights); + m_lights.erase(_s); } -EthashAux::LightType EthashAux::light(uint64_t _blockNumber) +EthashAux::LightType EthashAux::light(h256 const& _seedHash) { - RecursiveGuard l(get()->x_this); - h256 seedHash = EthashAux::seedHash(_blockNumber); - LightType ret = get()->m_lights[seedHash]; - return ret ? ret : (get()->m_lights[seedHash] = make_shared(_blockNumber)); + ReadGuard l(get()->x_lights); + LightType ret = get()->m_lights[_seedHash]; + return ret ? ret : (get()->m_lights[_seedHash] = make_shared(_seedHash)); } -EthashAux::LightAllocation::LightAllocation(uint64_t _blockNumber) +EthashAux::LightAllocation::LightAllocation(h256 const& _seedHash) { - light = ethash_light_new(_blockNumber); - size = ethash_get_cachesize(_blockNumber); + uint64_t blockNumber = EthashAux::number(_seedHash); + light = ethash_light_new(blockNumber); + if (!light) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("ethash_light_new()")); + size = ethash_get_cachesize(blockNumber); } EthashAux::LightAllocation::~LightAllocation() @@ -114,6 +134,8 @@ bytesConstRef EthashAux::LightAllocation::data() const EthashAux::FullAllocation::FullAllocation(ethash_light_t _light, ethash_callback_t _cb) { full = ethash_full_new(_light, _cb); + if (!full) + BOOST_THROW_EXCEPTION(ExternalFunctionFailure("ethash_full_new()")); } EthashAux::FullAllocation::~FullAllocation() @@ -126,32 +148,71 @@ bytesConstRef EthashAux::FullAllocation::data() const return bytesConstRef((byte const*)ethash_full_dag(full), size()); } -EthashAux::FullType EthashAux::full(BlockInfo const& _header) +static std::function s_dagCallback; +static int dagCallbackShim(unsigned _p) { - return full((uint64_t) _header.number); + clog(DAGChannel) << "Generating DAG file. Progress: " << toString(_p) << "%"; + return s_dagCallback ? s_dagCallback(_p) : 0; } -struct DAGChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; -const char* DAGChannel::name() { return EthGreen "DAG"; } -static int ethash_callback(unsigned int _progress) +EthashAux::FullType EthashAux::full(h256 const& _seedHash, bool _createIfMissing, function const& _f) { - clog(DAGChannel) << "Generating DAG file. Progress: " << toString(_progress) << "%"; - return 0; + FullType ret; + auto l = light(_seedHash); + + DEV_GUARDED(get()->x_fulls) + if ((ret = get()->m_fulls[_seedHash].lock())) + { + get()->m_lastUsedFull = ret; + return ret; + } + + if (_createIfMissing || computeFull(_seedHash, false) == 100) + { + s_dagCallback = _f; + cnote << "Loading from libethash..."; + ret = make_shared(l->light, dagCallbackShim); + cnote << "Done loading."; + + DEV_GUARDED(get()->x_fulls) + get()->m_fulls[_seedHash] = get()->m_lastUsedFull = ret; + } + + return ret; } -EthashAux::FullType EthashAux::full(uint64_t _blockNumber) +#define DEV_IF_THROWS(X) try { X; } catch (...) + +unsigned EthashAux::computeFull(h256 const& _seedHash, bool _createIfMissing) { - RecursiveGuard l(get()->x_this); - h256 seedHash = EthashAux::seedHash(_blockNumber); - FullType ret; - if ((ret = get()->m_fulls[seedHash].lock())) + Guard l(get()->x_fulls); + uint64_t blockNumber; + + DEV_IF_THROWS(blockNumber = EthashAux::number(_seedHash)) + { + return 0; + } + + if (FullType ret = get()->m_fulls[_seedHash].lock()) { get()->m_lastUsedFull = ret; - return ret; + return 100; } - ret = get()->m_lastUsedFull = make_shared(light(_blockNumber)->light, ethash_callback); - get()->m_fulls[seedHash] = ret; - return ret; + + if (_createIfMissing && (!get()->m_fullGenerator || !get()->m_fullGenerator->joinable())) + { + get()->m_fullProgress = 0; + get()->m_generatingFullNumber = blockNumber / ETHASH_EPOCH_LENGTH * ETHASH_EPOCH_LENGTH; + get()->m_fullGenerator = unique_ptr(new thread([=](){ + cnote << "Loading full DAG of seedhash: " << _seedHash; + get()->full(_seedHash, true, [](unsigned p){ get()->m_fullProgress = p; return 0; }); + cnote << "Full DAG loaded"; + get()->m_fullProgress = 0; + get()->m_generatingFullNumber = NotGenerating; + })); + } + + return (get()->m_generatingFullNumber == blockNumber) ? get()->m_fullProgress : 0; } Ethash::Result EthashAux::FullAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const @@ -172,13 +233,15 @@ Ethash::Result EthashAux::LightAllocation::compute(h256 const& _headerHash, Nonc Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce) { - return eval((uint64_t)_header.number, _header.headerHash(WithoutNonce), _nonce); + return eval(_header.seedHash(), _header.headerHash(WithoutNonce), _nonce); } -Ethash::Result EthashAux::eval(uint64_t _blockNumber, h256 const& _headerHash, Nonce const& _nonce) +Ethash::Result EthashAux::eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) { - h256 seedHash = EthashAux::seedHash(_blockNumber); - if (FullType dag = get()->m_fulls[seedHash].lock()) + if (FullType dag = get()->m_fulls[_seedHash].lock()) return dag->compute(_headerHash, _nonce); - return EthashAux::get()->light(_blockNumber)->compute(_headerHash, _nonce); + DEV_IF_THROWS(return EthashAux::get()->light(_seedHash)->compute(_headerHash, _nonce)) + { + return Ethash::Result{ ~h256(), h256() }; + } } diff --git a/libethcore/EthashAux.h b/libethcore/EthashAux.h index 48439a4b2..e6fed519f 100644 --- a/libethcore/EthashAux.h +++ b/libethcore/EthashAux.h @@ -19,13 +19,19 @@ * @date 2014 */ +#pragma once + +#include #include +#include #include "Ethash.h" namespace dev { -namespace eth{ +namespace eth +{ +struct DAGChannel: public LogChannel { static const char* name(); static const int verbosity = 1; }; class EthashAux { @@ -36,7 +42,7 @@ public: struct LightAllocation { - LightAllocation(uint64_t _blockNumber); + LightAllocation(h256 const& _seedHash); ~LightAllocation(); bytesConstRef data() const; Ethash::Result compute(h256 const& _headerHash, Nonce const& _nonce) const; @@ -58,29 +64,42 @@ public: using FullType = std::shared_ptr; static h256 seedHash(unsigned _number); + static uint64_t number(h256 const& _seedHash); static uint64_t cacheSize(BlockInfo const& _header); - static LightType light(BlockInfo const& _header); - static LightType light(uint64_t _blockNumber); - static FullType full(BlockInfo const& _header); - static FullType full(uint64_t _blockNumber); + static LightType light(h256 const& _seedHash); + + static const uint64_t NotGenerating = (uint64_t)-1; + /// Kicks off generation of DAG for @a _seedHash and @returns false or @returns true if ready. + static unsigned computeFull(h256 const& _seedHash, bool _createIfMissing = true); + /// Information on the generation progress. + static std::pair fullGeneratingProgress() { return std::make_pair(get()->m_generatingFullNumber, get()->m_fullProgress); } + /// Kicks off generation of DAG for @a _blocknumber and blocks until ready; @returns result or empty pointer if not existing and _createIfMissing is false. + static FullType full(h256 const& _seedHash, bool _createIfMissing = false, std::function const& _f = std::function()); static Ethash::Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); } static Ethash::Result eval(BlockInfo const& _header, Nonce const& _nonce); - static Ethash::Result eval(uint64_t _blockNumber, h256 const& _headerHash, Nonce const& _nonce); - + static Ethash::Result eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce); private: EthashAux() {} + /// Kicks off generation of DAG for @a _blocknumber and blocks until ready; @returns result. + void killCache(h256 const& _s); static EthashAux* s_this; - RecursiveMutex x_this; + SharedMutex x_lights; std::unordered_map> m_lights; + + Mutex x_fulls; + std::condition_variable m_fullsChanged; std::unordered_map> m_fulls; FullType m_lastUsedFull; + std::unique_ptr m_fullGenerator; + uint64_t m_generatingFullNumber = NotGenerating; + unsigned m_fullProgress; Mutex x_epochs; std::unordered_map m_epochs; diff --git a/libethereum/Farm.h b/libethcore/Farm.h similarity index 100% rename from libethereum/Farm.h rename to libethcore/Farm.h diff --git a/libethcore/ICAP.cpp b/libethcore/ICAP.cpp index 6fce19a62..158c297f8 100644 --- a/libethcore/ICAP.cpp +++ b/libethcore/ICAP.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "Exceptions.h" #include "ABI.h" using namespace std; diff --git a/libethcore/Miner.h b/libethcore/Miner.h index 3a68491ff..cede34475 100644 --- a/libethcore/Miner.h +++ b/libethcore/Miner.h @@ -107,12 +107,10 @@ public: } if (!!_work) { - boost::timer t; - pause(); - cdebug << "pause took" << t.elapsed(); - t.restart(); - kickOff(); - cdebug << "kickOff took" << t.elapsed(); + DEV_TIMED_ABOVE(pause, 250) + pause(); + DEV_TIMED_ABOVE(kickOff, 250) + kickOff(); } else if (!_work && !!old) pause(); diff --git a/libethereum/Account.h b/libethereum/Account.h index 660dc0a4c..87fc82b6c 100644 --- a/libethereum/Account.h +++ b/libethereum/Account.h @@ -23,8 +23,8 @@ #include #include -#include -#include +#include +#include namespace dev { diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index f13f83588..e23fde6b6 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -33,7 +33,7 @@ #include #include #include -#include +#include #include #include #include @@ -96,7 +96,7 @@ ldb::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub) #endif } -#if ETH_DEBUG +#if ETH_DEBUG&&0 static const chrono::system_clock::duration c_collectionDuration = chrono::seconds(15); static const unsigned c_collectionQueueSize = 2; static const unsigned c_maxCacheSize = 1024 * 1024 * 1; @@ -199,7 +199,7 @@ void BlockChain::close() #define IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} -void BlockChain::rebuild(std::string const& _path, std::function const& _progress) +void BlockChain::rebuild(std::string const& _path, std::function const& _progress, bool _prepPoW) { std::string path = _path.empty() ? Defaults::get()->m_dbPath : _path; @@ -252,7 +252,8 @@ void BlockChain::rebuild(std::string const& _path, std::function(h256(u256(d)), m_blockHashes, x_blockHashes, NullBlockHash, oldExtrasDB).value); BlockInfo bi(b); - ProofOfWork::prep(bi); + if (_prepPoW) + ProofOfWork::prep(bi); if (bi.parentHash != lastHash) { @@ -306,7 +307,7 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st { // _bq.tick(*this); - vector blocks; + vector> blocks; _bq.drain(blocks, _max); h256s fresh; @@ -316,7 +317,10 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st { try { - auto r = import(block, _stateDB); + // Nonce & uncle nonces already verified thread at this point. + ImportRoute r; + DEV_TIMED_ABOVE(Block import, 500) + r = import(block.first, block.second, _stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce & ~ImportRequirements::CheckUncles); fresh += r.first; dead += r.second; } @@ -325,14 +329,14 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st cwarn << "ODD: Import queue contains block with unknown parent." << LogTag::Error << boost::current_exception_diagnostic_information(); // NOTE: don't reimport since the queue should guarantee everything in the right order. // Can't continue - chain bad. - badBlocks.push_back(BlockInfo::headerHash(block)); + badBlocks.push_back(block.first.hash()); } catch (Exception const& _e) { cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!" << LogTag::Error << diagnostic_information(_e); // NOTE: don't reimport since the queue should guarantee everything in the right order. // Can't continue - chain bad. - badBlocks.push_back(BlockInfo::headerHash(block)); + badBlocks.push_back(block.first.hash()); } } return make_tuple(fresh, dead, _bq.doneDrain(badBlocks)); @@ -364,18 +368,6 @@ pair BlockChain::attemptImport(bytes const& _block, O ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, ImportRequirements::value _ir) { - //@tidy This is a behemoth of a method - could do to be split into a few smaller ones. - -#if ETH_TIMED_IMPORTS - boost::timer total; - double preliminaryChecks; - double enactment; - double collation; - double writing; - double checkBest; - boost::timer t; -#endif - // VERIFY: populates from the block and checks the block is internally coherent. BlockInfo bi; @@ -383,11 +375,6 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import try #endif { - RLP blockRLP(_block); - - if (!blockRLP.isList()) - BOOST_THROW_EXCEPTION(InvalidBlockFormat() << errinfo_comment("block header needs to be a list") << BadFieldError(0, blockRLP.data().toString())); - bi.populate(&_block); bi.verifyInternals(&_block); } @@ -400,29 +387,46 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import } #endif + return import(bi, _block, _db, _ir); +} + +ImportRoute BlockChain::import(BlockInfo const& _bi, bytes const& _block, OverlayDB const& _db, ImportRequirements::value _ir) +{ + //@tidy This is a behemoth of a method - could do to be split into a few smaller ones. + +#if ETH_TIMED_IMPORTS + boost::timer total; + double preliminaryChecks; + double enactment; + double collation; + double writing; + double checkBest; + boost::timer t; +#endif + // Check block doesn't already exist first! - if (isKnown(bi.hash()) && (_ir & ImportRequirements::DontHave)) + if (isKnown(_bi.hash()) && (_ir & ImportRequirements::DontHave)) { - clog(BlockChainNote) << bi.hash() << ": Not new."; + clog(BlockChainNote) << _bi.hash() << ": Not new."; BOOST_THROW_EXCEPTION(AlreadyHaveBlock()); } // Work out its number as the parent's number + 1 - if (!isKnown(bi.parentHash)) + if (!isKnown(_bi.parentHash)) { - clog(BlockChainNote) << bi.hash() << ": Unknown parent " << bi.parentHash; + clog(BlockChainNote) << _bi.hash() << ": Unknown parent " << _bi.parentHash; // We don't know the parent (yet) - discard for now. It'll get resent to us if we find out about its ancestry later on. BOOST_THROW_EXCEPTION(UnknownParent()); } - auto pd = details(bi.parentHash); + auto pd = details(_bi.parentHash); if (!pd) { auto pdata = pd.rlp(); clog(BlockChainDebug) << "Details is returning false despite block known:" << RLP(pdata); - auto parentBlock = block(bi.parentHash); - clog(BlockChainDebug) << "isKnown:" << isKnown(bi.parentHash); - clog(BlockChainDebug) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << bi.number; + auto parentBlock = block(_bi.parentHash); + clog(BlockChainDebug) << "isKnown:" << isKnown(_bi.parentHash); + clog(BlockChainDebug) << "last/number:" << m_lastBlockNumber << m_lastBlockHash << _bi.number; clog(BlockChainDebug) << "Block:" << BlockInfo(parentBlock); clog(BlockChainDebug) << "RLP:" << RLP(parentBlock); clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; @@ -430,14 +434,14 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import } // Check it's not crazy - if (bi.timestamp > (u256)time(0)) + if (_bi.timestamp > (u256)time(0)) { - clog(BlockChainChat) << bi.hash() << ": Future time " << bi.timestamp << " (now at " << time(0) << ")"; + clog(BlockChainChat) << _bi.hash() << ": Future time " << _bi.timestamp << " (now at " << time(0) << ")"; // Block has a timestamp in the future. This is no good. BOOST_THROW_EXCEPTION(FutureTime()); } - clog(BlockChainChat) << "Attempting import of " << bi.hash() << "..."; + clog(BlockChainChat) << "Attempting import of " << _bi.hash() << "..."; #if ETH_TIMED_IMPORTS preliminaryChecks = t.elapsed(); @@ -457,7 +461,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import // Check transactions are valid and that they result in a state equivalent to our state_root. // Get total difficulty increase and update state, checking it. State s(_db); - auto tdIncrease = s.enactOn(&_block, bi, *this, _ir); + auto tdIncrease = s.enactOn(&_block, _bi, *this, _ir); BlockLogBlooms blb; BlockReceipts br; @@ -466,7 +470,14 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import blb.blooms.push_back(s.receipt(i).bloom()); br.receipts.push_back(s.receipt(i)); } - s.cleanup(true); + try { + s.cleanup(true); + } + catch (BadRoot) + { + cwarn << "BadRoot error. Retrying import later."; + BOOST_THROW_EXCEPTION(FutureTime()); + } td = pd.totalDifficulty + tdIncrease; @@ -486,22 +497,22 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import // together with an "ensureCachedWithUpdatableLock(l)" method. // This is safe in practice since the caches don't get flushed nearly often enough to be // done here. - details(bi.parentHash); + details(_bi.parentHash); DEV_WRITE_GUARDED(x_details) - m_details[bi.parentHash].children.push_back(bi.hash()); + m_details[_bi.parentHash].children.push_back(_bi.hash()); #if ETH_TIMED_IMPORTS || !ETH_TRUE collation = t.elapsed(); t.restart(); #endif - blocksBatch.Put(toSlice(bi.hash()), (ldb::Slice)ref(_block)); + blocksBatch.Put(toSlice(_bi.hash()), (ldb::Slice)ref(_block)); DEV_READ_GUARDED(x_details) - extrasBatch.Put(toSlice(bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[bi.parentHash].rlp())); + extrasBatch.Put(toSlice(_bi.parentHash, ExtraDetails), (ldb::Slice)dev::ref(m_details[_bi.parentHash].rlp())); - extrasBatch.Put(toSlice(bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(BlockDetails((unsigned)pd.number + 1, td, bi.parentHash, {}).rlp())); - extrasBatch.Put(toSlice(bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp())); - extrasBatch.Put(toSlice(bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(br.rlp())); + extrasBatch.Put(toSlice(_bi.hash(), ExtraDetails), (ldb::Slice)dev::ref(BlockDetails((unsigned)pd.number + 1, td, _bi.parentHash, {}).rlp())); + extrasBatch.Put(toSlice(_bi.hash(), ExtraLogBlooms), (ldb::Slice)dev::ref(blb.rlp())); + extrasBatch.Put(toSlice(_bi.hash(), ExtraReceipts), (ldb::Slice)dev::ref(br.rlp())); #if ETH_TIMED_IMPORTS || !ETH_TRUE writing = t.elapsed(); @@ -519,20 +530,20 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import { clog(BlockChainWarn) << " Malformed block: " << diagnostic_information(_e); _e << errinfo_comment("Malformed block "); - clog(BlockChainWarn) << "Block: " << bi.hash(); - clog(BlockChainWarn) << bi; - clog(BlockChainWarn) << "Block parent: " << bi.parentHash; - clog(BlockChainWarn) << BlockInfo(block(bi.parentHash)); + clog(BlockChainWarn) << "Block: " << _bi.hash(); + clog(BlockChainWarn) << _bi; + clog(BlockChainWarn) << "Block parent: " << _bi.parentHash; + clog(BlockChainWarn) << BlockInfo(block(_bi.parentHash)); throw; } #endif StructuredLogger::chainReceivedNewBlock( - bi.headerHash(WithoutNonce).abridged(), - bi.nonce.abridged(), + _bi.headerHash(WithoutNonce).abridged(), + _bi.nonce.abridged(), currentHash().abridged(), "", // TODO: remote id ?? - bi.parentHash.abridged() + _bi.parentHash.abridged() ); // cnote << "Parent " << bi.parentHash << " has " << details(bi.parentHash).children.size() << " children."; @@ -545,8 +556,8 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import // don't include bi.hash() in treeRoute, since it's not yet in details DB... // just tack it on afterwards. unsigned commonIndex; - tie(route, common, commonIndex) = treeRoute(last, bi.parentHash); - route.push_back(bi.hash()); + tie(route, common, commonIndex) = treeRoute(last, _bi.parentHash); + route.push_back(_bi.hash()); // Most of the time these two will be equal - only when we're doing a chain revert will they not be if (common != last) @@ -558,8 +569,8 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import for (auto i = route.rbegin(); i != route.rend() && *i != common; ++i) { BlockInfo tbi; - if (*i == bi.hash()) - tbi = bi; + if (*i == _bi.hash()) + tbi = _bi; else tbi = BlockInfo(block(*i)); @@ -586,7 +597,7 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import h256s newTransactionAddresses; { bytes blockBytes; - RLP blockRLP(*i == bi.hash() ? _block : (blockBytes = block(*i))); + RLP blockRLP(*i == _bi.hash() ? _block : (blockBytes = block(*i))); TransactionAddress ta; ta.blockHash = tbi.hash(); for (ta.index = 0; ta.index < blockRLP[1].itemCount(); ++ta.index) @@ -602,17 +613,17 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import // FINALLY! change our best hash. { - newLastBlockHash = bi.hash(); - newLastBlockNumber = (unsigned)bi.number; + newLastBlockHash = _bi.hash(); + newLastBlockNumber = (unsigned)_bi.number; } - clog(BlockChainNote) << " Imported and best" << td << " (#" << bi.number << "). Has" << (details(bi.parentHash).children.size() - 1) << "siblings. Route:" << route; + clog(BlockChainNote) << " Imported and best" << td << " (#" << _bi.number << "). Has" << (details(_bi.parentHash).children.size() - 1) << "siblings. Route:" << route; StructuredLogger::chainNewHead( - bi.headerHash(WithoutNonce).abridged(), - bi.nonce.abridged(), + _bi.headerHash(WithoutNonce).abridged(), + _bi.nonce.abridged(), currentHash().abridged(), - bi.parentHash.abridged() + _bi.parentHash.abridged() ); } else @@ -623,21 +634,21 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import m_blocksDB->Write(m_writeOptions, &blocksBatch); m_extrasDB->Write(m_writeOptions, &extrasBatch); - if (isKnown(bi.hash()) && !details(bi.hash())) + if (isKnown(_bi.hash()) && !details(_bi.hash())) { clog(BlockChainDebug) << "Known block just inserted has no details."; - clog(BlockChainDebug) << "Block:" << bi; + clog(BlockChainDebug) << "Block:" << _bi; clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; exit(-1); } try { - State canary(_db, *this, bi.hash()); + State canary(_db, *this, _bi.hash(), ImportRequirements::DontHave); } catch (...) { clog(BlockChainDebug) << "Failed to initialise State object form imported block."; - clog(BlockChainDebug) << "Block:" << bi; + clog(BlockChainDebug) << "Block:" << _bi; clog(BlockChainDebug) << "DATABASE CORRUPTION: CRITICAL FAILURE"; exit(-1); } @@ -974,14 +985,15 @@ vector BlockChain::withBlockBloom(LogBloom const& _b, unsigned _earlie return ret; } -h256Hash BlockChain::allUnclesFrom(h256 const& _parent) const +h256Hash BlockChain::allKinFrom(h256 const& _parent, unsigned _generations) const { // Get all uncles cited given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5). - h256Hash ret; h256 p = _parent; - for (unsigned i = 0; i < 6 && p != m_genesisHash; ++i, p = details(p).parent) + h256Hash ret = { p }; + // p and (details(p).parent: i == 5) is likely to be overkill, but can't hurt to be cautious. + for (unsigned i = 0; i < _generations && p != m_genesisHash; ++i, p = details(p).parent) { - ret.insert(p); // TODO: check: should this be details(p).parent? + ret.insert(details(p).parent); auto b = block(p); for (auto i: RLP(b)[2]) ret.insert(sha3(i.data())); diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index e77369534..a67ec9a9c 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -120,6 +120,7 @@ public: /// Import block into disk-backed DB /// @returns the block hashes of any blocks that came into/went out of the canonical block chain. ImportRoute import(bytes const& _block, OverlayDB const& _stateDB, ImportRequirements::value _ir = ImportRequirements::Default); + ImportRoute import(BlockInfo const& _bi, bytes const& _block, OverlayDB const& _stateDB, ImportRequirements::value _ir = ImportRequirements::Default); /// Returns true if the given block is known (though not necessarily a part of the canon chain). bool isKnown(h256 const& _hash) const; @@ -203,14 +204,14 @@ public: /// Get the hash of the genesis block. Thread-safe. h256 genesisHash() const { return m_genesisHash; } - /// Get all blocks not allowed as uncles given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + 5). - /// @returns set including the header-hash of every parent (including @a _parent) up to and including generation +5 + /// Get all blocks not allowed as uncles given a parent (i.e. featured as uncles/main in parent, parent + 1, ... parent + @a _generations). + /// @returns set including the header-hash of every parent (including @a _parent) up to and including generation + @a _generations /// togther with all their quoted uncles. - h256Hash allUnclesFrom(h256 const& _parent) const; + h256Hash allKinFrom(h256 const& _parent, unsigned _generations) const; /// Run through database and verify all blocks by reevaluating. /// Will call _progress with the progress in this operation first param done, second total. - void rebuild(std::string const& _path, ProgressCallback const& _progress = std::function()); + void rebuild(std::string const& _path, ProgressCallback const& _progress = std::function(), bool _prepPoW = false); /** @returns a tuple of: * - an vector of hashes of all blocks between @a _from and @a _to, all blocks are ordered first by a number of diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp index 43d2b4cb8..2af95d00c 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -20,7 +20,7 @@ */ #include "BlockQueue.h" - +#include #include #include #include @@ -35,6 +35,108 @@ const char* BlockQueueChannel::name() { return EthOrange "[]>"; } const char* BlockQueueChannel::name() { return EthOrange "▣┅▶"; } #endif + +BlockQueue::BlockQueue() +{ + // Allow some room for other activity + unsigned verifierThreads = std::max(thread::hardware_concurrency(), 3U) - 2U; + for (unsigned i = 0; i < verifierThreads; ++i) + m_verifiers.emplace_back([=](){ + setThreadName("verifier" + toString(i)); + this->verifierBody(); + }); +} + +BlockQueue::~BlockQueue() +{ + m_deleting = true; + m_moreToVerify.notify_all(); + for (auto& i: m_verifiers) + i.join(); +} + +void BlockQueue::verifierBody() +{ + while (!m_deleting) + { + std::pair work; + + { + unique_lock l(m_verification); + m_moreToVerify.wait(l, [&](){ return !m_unverified.empty() || m_deleting; }); + if (m_deleting) + return; + swap(work, m_unverified.front()); + m_unverified.pop_front(); + BlockInfo bi; + bi.mixHash = work.first; + m_verifying.push_back(make_pair(bi, bytes())); + } + + std::pair res; + swap(work.second, res.second); + try { + res.first.populate(res.second, CheckEverything, work.first); + res.first.verifyInternals(&res.second); + RLP r(&res.second); + for (auto const& uncle: r[2]) + BlockInfo().populateFromHeader(RLP(uncle.data()), CheckEverything); + } + catch (...) + { + // bad block. + { + // has to be this order as that's how invariants() assumes. + WriteGuard l2(m_lock); + unique_lock l(m_verification); + m_readySet.erase(work.first); + m_knownBad.insert(work.first); + } + + unique_lock l(m_verification); + for (auto it = m_verifying.begin(); it != m_verifying.end(); ++it) + if (it->first.mixHash == work.first) + { + m_verifying.erase(it); + goto OK1; + } + cwarn << "GAA BlockQueue corrupt: job cancelled but cannot be found in m_verifying queue."; + OK1:; + continue; + } + + bool ready = false; + { + unique_lock l(m_verification); + if (m_verifying.front().first.mixHash == work.first) + { + // we're next! + m_verifying.pop_front(); + m_verified.push_back(move(res)); + while (m_verifying.size() && !m_verifying.front().second.empty()) + { + m_verified.push_back(move(m_verifying.front())); + m_verifying.pop_front(); + } + ready = true; + } + else + { + for (auto& i: m_verifying) + if (i.first.mixHash == work.first) + { + i = move(res); + goto OK; + } + cwarn << "GAA BlockQueue corrupt: job finished but cannot be found in m_verifying queue."; + OK:; + } + } + if (ready) + m_onReady(); + } +} + ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, bool _isOurs) { // Check if we already know this block. @@ -110,11 +212,13 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo { // If valid, append to blocks. cblockq << "OK - ready for chain insertion."; - m_ready.push_back(make_pair(h, _block.toBytes())); + DEV_GUARDED(m_verification) + m_unverified.push_back(make_pair(h, _block.toBytes())); + m_moreToVerify.notify_one(); m_readySet.insert(h); noteReady_WITH_LOCK(h); - m_onReady(); + return ImportResult::Success; } } @@ -127,18 +231,19 @@ bool BlockQueue::doneDrain(h256s const& _bad) m_drainingSet.clear(); if (_bad.size()) { - vector> old; - swap(m_ready, old); + vector> old; + DEV_GUARDED(m_verification) + swap(m_verified, old); for (auto& b: old) { - BlockInfo bi(b.second); - if (m_knownBad.count(bi.parentHash)) + if (m_knownBad.count(b.first.parentHash)) { - m_knownBad.insert(b.first); - m_readySet.erase(b.first); + m_knownBad.insert(b.first.hash()); + m_readySet.erase(b.first.hash()); } else - m_ready.push_back(std::move(b)); + DEV_GUARDED(m_verification) + m_verified.push_back(std::move(b)); } } m_knownBad += _bad; @@ -197,62 +302,73 @@ QueueStatus BlockQueue::blockStatus(h256 const& _h) const QueueStatus::Unknown; } -void BlockQueue::drain(std::vector& o_out, unsigned _max) +void BlockQueue::drain(std::vector>& o_out, unsigned _max) { WriteGuard l(m_lock); DEV_INVARIANT_CHECK; if (m_drainingSet.empty()) { - o_out.resize(min(_max, m_ready.size())); - for (unsigned i = 0; i < o_out.size(); ++i) - swap(o_out[i], m_ready[i].second); - m_ready.erase(m_ready.begin(), advanced(m_ready.begin(), o_out.size())); + DEV_GUARDED(m_verification) + { + o_out.resize(min(_max, m_verified.size())); + for (unsigned i = 0; i < o_out.size(); ++i) + swap(o_out[i], m_verified[i]); + m_verified.erase(m_verified.begin(), advanced(m_verified.begin(), o_out.size())); + } for (auto const& bs: o_out) { // TODO: @optimise use map rather than vector & set. - auto h = BlockInfo::headerHash(bs); + auto h = bs.first.hash(); m_drainingSet.insert(h); m_readySet.erase(h); } -// swap(o_out, m_ready); -// swap(m_drainingSet, m_readySet); } } bool BlockQueue::invariants() const { - return m_readySet.size() == m_ready.size(); + Guard l(m_verification); + return m_readySet.size() == m_verified.size() + m_unverified.size() + m_verifying.size(); } void BlockQueue::noteReady_WITH_LOCK(h256 const& _good) { DEV_INVARIANT_CHECK; list goodQueue(1, _good); + bool notify = false; while (!goodQueue.empty()) { auto r = m_unknown.equal_range(goodQueue.front()); goodQueue.pop_front(); for (auto it = r.first; it != r.second; ++it) { - m_ready.push_back(it->second); + DEV_GUARDED(m_verification) + m_unverified.push_back(it->second); auto newReady = it->second.first; m_unknownSet.erase(newReady); m_readySet.insert(newReady); goodQueue.push_back(newReady); + notify = true; } m_unknown.erase(r.first, r.second); } + if (notify) + m_moreToVerify.notify_all(); } void BlockQueue::retryAllUnknown() { + WriteGuard l(m_lock); DEV_INVARIANT_CHECK; for (auto it = m_unknown.begin(); it != m_unknown.end(); ++it) { - m_ready.push_back(it->second); + DEV_GUARDED(m_verification) + m_unverified.push_back(it->second); auto newReady = it->second.first; m_unknownSet.erase(newReady); m_readySet.insert(newReady); + m_moreToVerify.notify_one(); } m_unknown.clear(); + m_moreToVerify.notify_all(); } diff --git a/libethereum/BlockQueue.h b/libethereum/BlockQueue.h index a4e44b390..d0437739d 100644 --- a/libethereum/BlockQueue.h +++ b/libethereum/BlockQueue.h @@ -21,12 +21,16 @@ #pragma once +#include +#include +#include #include #include #include #include #include #include +#include namespace dev { @@ -41,7 +45,9 @@ struct BlockQueueChannel: public LogChannel { static const char* name(); static struct BlockQueueStatus { - size_t ready; + size_t verified; + size_t verifying; + size_t unverified; size_t future; size_t unknown; size_t bad; @@ -64,6 +70,9 @@ enum class QueueStatus class BlockQueue: HasInvariants { public: + BlockQueue(); + ~BlockQueue(); + /// Import a block into the queue. ImportResult import(bytesConstRef _tx, BlockChain const& _bc, bool _isOurs = false); @@ -72,7 +81,7 @@ public: /// Grabs at most @a _max of the blocks that are ready, giving them in the correct order for insertion into the chain. /// Don't forget to call doneDrain() once you're done importing. - void drain(std::vector& o_out, unsigned _max); + void drain(std::vector>& o_out, unsigned _max); /// Must be called after a drain() call. Notes that the drained blocks have been imported into the blockchain, so we can forget about them. /// @returns true iff there are additional blocks ready to be processed. @@ -85,16 +94,16 @@ public: void retryAllUnknown(); /// Get information on the items queued. - std::pair items() const { ReadGuard l(m_lock); return std::make_pair(m_ready.size(), m_unknown.size()); } + std::pair items() const { ReadGuard l(m_lock); return std::make_pair(m_readySet.size(), m_unknownSet.size()); } /// Clear everything. - void clear() { WriteGuard l(m_lock); DEV_INVARIANT_CHECK; m_readySet.clear(); m_drainingSet.clear(); m_ready.clear(); m_unknownSet.clear(); m_unknown.clear(); m_future.clear(); } + void clear() { WriteGuard l(m_lock); DEV_INVARIANT_CHECK; Guard l2(m_verification); m_readySet.clear(); m_drainingSet.clear(); m_verified.clear(); m_unverified.clear(); m_unknownSet.clear(); m_unknown.clear(); m_future.clear(); } /// Return first block with an unknown parent. h256 firstUnknown() const { ReadGuard l(m_lock); return m_unknownSet.size() ? *m_unknownSet.begin() : h256(); } /// Get some infomration on the current status. - BlockQueueStatus status() const { ReadGuard l(m_lock); return BlockQueueStatus{m_ready.size(), m_future.size(), m_unknown.size(), m_knownBad.size()}; } + BlockQueueStatus status() const { ReadGuard l(m_lock); Guard l2(m_verification); return BlockQueueStatus{m_verified.size(), m_verifying.size(), m_unverified.size(), m_future.size(), m_unknown.size(), m_knownBad.size()}; } /// Get some infomration on the given block's status regarding us. QueueStatus blockStatus(h256 const& _h) const; @@ -106,15 +115,25 @@ private: bool invariants() const override; - mutable boost::shared_mutex m_lock; ///< General lock. + void verifierBody(); + + mutable boost::shared_mutex m_lock; ///< General lock for the sets, m_future and m_unknown. h256Hash m_drainingSet; ///< All blocks being imported. - h256Hash m_readySet; ///< All blocks ready for chain-import. - std::vector> m_ready; ///< List of blocks, in correct order, ready for chain-import. + h256Hash m_readySet; ///< All blocks ready for chain import. h256Hash m_unknownSet; ///< Set of all blocks whose parents are not ready/in-chain. std::unordered_multimap> m_unknown; ///< For blocks that have an unknown parent; we map their parent hash to the block stuff, and insert once the block appears. h256Hash m_knownBad; ///< Set of blocks that we know will never be valid. std::multimap> m_future; ///< Set of blocks that are not yet valid. Ordered by timestamp Signal m_onReady; ///< Called when a subsequent call to import blocks will return a non-empty container. Be nice and exit fast. + + mutable Mutex m_verification; ///< Mutex that allows writing to m_verified, m_verifying and m_unverified. + std::condition_variable m_moreToVerify; ///< Signaled when m_unverified has a new entry. + std::vector> m_verified; ///< List of blocks, in correct order, verified and ready for chain-import. + std::deque> m_verifying; ///< List of blocks being verified; as long as the second component (bytes) is empty, it's not finished. + std::deque> m_unverified; ///< List of blocks, in correct order, ready for verification. + + std::vector m_verifiers; ///< Threads who only verify. + bool m_deleting = false; ///< Exit condition for verifiers. }; } diff --git a/libethereum/CachedAddressState.cpp b/libethereum/CachedAddressState.cpp index a25017793..757aef466 100644 --- a/libethereum/CachedAddressState.cpp +++ b/libethereum/CachedAddressState.cpp @@ -21,8 +21,9 @@ #include "CachedAddressState.h" +#include #include -#include +#include #include "Account.h" using namespace std; using namespace dev; @@ -57,8 +58,8 @@ std::unordered_map CachedAddressState::storage() const if (m_r) { SecureTrieDB memdb(const_cast(m_o), m_r[2].toHash()); // promise we won't alter the overlay! :) -// for (auto const& j: memdb) -// ret[j.first] = RLP(j.second).toInt(); + for (auto const& j: memdb) + ret[j.first] = RLP(j.second).toInt(); } if (m_s) for (auto const& j: m_s->storageOverlay()) diff --git a/libethereum/CanonBlockChain.cpp b/libethereum/CanonBlockChain.cpp index f1de7292b..5dd7dc2ce 100644 --- a/libethereum/CanonBlockChain.cpp +++ b/libethereum/CanonBlockChain.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index a43c98aa2..e372e611a 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -164,7 +164,7 @@ const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; } #endif Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): - Worker("eth"), + Worker("eth", 0), m_vc(_dbPath), m_bc(_dbPath, max(m_vc.action(), _forceAction), [](unsigned d, unsigned t){ cerr << "REVISING BLOCKCHAIN: Processed " << d << " of " << t << "...\r"; }), m_gp(new TrivialGasPricer), @@ -172,6 +172,7 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _for m_preMine(m_stateDB, BaseState::CanonGenesis), m_postMine(m_stateDB) { + m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30); m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue); m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue); m_farm.onSolutionFound([=](ProofOfWork::Solution const& s){ return this->submitWork(s); }); @@ -197,6 +198,7 @@ Client::Client(p2p::Host* _extNet, std::shared_ptr _gp, std::string c m_preMine(m_stateDB), m_postMine(m_stateDB) { + m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30); m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue); m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue); m_farm.onSolutionFound([=](ProofOfWork::Solution const& s){ return this->submitWork(s); }); @@ -453,21 +455,28 @@ ProofOfWork::WorkPackage Client::getWork() { // lock the work so a later submission isn't invalidated by processing a transaction elsewhere. // this will be reset as soon as a new block arrives, allowing more transactions to be processed. + bool oldShould = shouldServeWork(); m_lastGetWork = chrono::system_clock::now(); - m_remoteWorking = true; + + // if this request has made us bother to serve work, prep it now. + if (!oldShould && shouldServeWork()) + onPostStateChanged(); + else + // otherwise, set this to true so that it gets prepped next time. + m_remoteWorking = true; return ProofOfWork::package(m_miningInfo); } bool Client::submitWork(ProofOfWork::Solution const& _solution) { bytes newBlock; - DEV_TIMED(working) DEV_WRITE_GUARDED(x_working) + DEV_WRITE_GUARDED(x_working) if (!m_working.completeMine(_solution)) return false; DEV_READ_GUARDED(x_working) { - DEV_TIMED(post) DEV_WRITE_GUARDED(x_postMine) + DEV_WRITE_GUARDED(x_postMine) m_postMine = m_working; newBlock = m_working.blockData(); } @@ -484,7 +493,7 @@ void Client::syncBlockQueue() cwork << "BQ ==> CHAIN ==> STATE"; { - tie(ir.first, ir.second, m_syncBlockQueue) = m_bc.sync(m_bq, m_stateDB, 100); + tie(ir.first, ir.second, m_syncBlockQueue) = m_bc.sync(m_bq, m_stateDB, rand() % 90 + 10); if (ir.first.empty()) return; } @@ -499,14 +508,14 @@ void Client::syncTransactionQueue() h256Hash changeds; TransactionReceipts newPendingReceipts; - DEV_TIMED(working) DEV_WRITE_GUARDED(x_working) + DEV_WRITE_GUARDED(x_working) tie(newPendingReceipts, m_syncTransactionQueue) = m_working.sync(m_bc, m_tq, *m_gp); if (newPendingReceipts.empty()) return; DEV_READ_GUARDED(x_working) - DEV_TIMED(post) DEV_WRITE_GUARDED(x_postMine) + DEV_WRITE_GUARDED(x_postMine) m_postMine = m_working; DEV_READ_GUARDED(x_postMine) @@ -574,7 +583,7 @@ void Client::onChainChanged(ImportRoute const& _ir) DEV_WRITE_GUARDED(x_preMine) m_preMine = newPreMine; - DEV_TIMED(working) DEV_WRITE_GUARDED(x_working) + DEV_WRITE_GUARDED(x_working) m_working = newPreMine; DEV_READ_GUARDED(x_postMine) for (auto const& t: m_postMine.pending()) @@ -584,7 +593,7 @@ void Client::onChainChanged(ImportRoute const& _ir) if (ir != ImportResult::Success) onTransactionQueueReady(); } - DEV_READ_GUARDED(x_working) DEV_TIMED(post) DEV_WRITE_GUARDED(x_postMine) + DEV_READ_GUARDED(x_working) DEV_WRITE_GUARDED(x_postMine) m_postMine = m_working; changeds.insert(PendingChangedFilter); @@ -606,18 +615,22 @@ bool Client::remoteActive() const void Client::onPostStateChanged() { - cnote << "Post state changed: Restarting mining..."; - if (isMining() || remoteActive()) + cnote << "Post state changed"; + + if (m_bq.items().first == 0 && (isMining() || remoteActive())) { - DEV_TIMED(working) DEV_WRITE_GUARDED(x_working) + cnote << "Restarting mining..."; + DEV_WRITE_GUARDED(x_working) m_working.commitToMine(m_bc); DEV_READ_GUARDED(x_working) { - DEV_TIMED(post) DEV_WRITE_GUARDED(x_postMine) + DEV_WRITE_GUARDED(x_postMine) m_postMine = m_working; m_miningInfo = m_postMine.info(); } m_farm.setWork(m_miningInfo); + + Ethash::ensurePrecomputed(m_bc.number()); } m_remoteWorking = false; } @@ -635,7 +648,7 @@ void Client::noteChanged(h256Hash const& _filters) { Guard l(x_filtersWatches); if (_filters.size()) - filtersStreamOut(cnote << "noteChanged:", _filters); + filtersStreamOut(cwatch << "noteChanged:", _filters); // accrue all changes left in each filter into the watches. for (auto& w: m_watches) if (_filters.count(w.second.id)) diff --git a/libethereum/Client.h b/libethereum/Client.h index 674556a6e..c77cb6034 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -37,12 +37,12 @@ #include #include #include +#include #include #include "CanonBlockChain.h" #include "TransactionQueue.h" #include "State.h" #include "CommonNet.h" -#include "Farm.h" #include "ClientBase.h" namespace dev @@ -274,6 +274,9 @@ private: /// Ticks various system-level objects. void tick(); + /// @returns true only if it's worth bothering to prep the mining block. + bool shouldServeWork() const { return m_bq.items().first == 0 && (isMining() || remoteActive()); } + VersionChecker m_vc; ///< Dummy object to check & update the protocol version. CanonBlockChain m_bc; ///< Maintains block database. BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported). @@ -289,7 +292,7 @@ private: BlockInfo m_miningInfo; ///< The header we're attempting to mine on (derived from m_postMine). bool remoteActive() const; ///< Is there an active and valid remote worker? bool m_remoteWorking = false; ///< Has the remote worker recently been reset? - std::chrono::system_clock::time_point m_lastGetWork = std::chrono::system_clock::time_point::min(); ///< Is there an active and valid remote worker? + std::chrono::system_clock::time_point m_lastGetWork; ///< Is there an active and valid remote worker? std::weak_ptr m_host; ///< Our Ethereum Host. Don't do anything if we can't lock. diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index cfa271cf6..8dc666bb5 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -57,7 +57,7 @@ void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, b m_tq.import(t.rlp()); StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged()); - cnote << "New transaction " << t; + cnote << "New transaction " << t << "(maxNonce for sender" << a << "is" << m_tq.maxNonce(a) << ")"; } Address ClientBase::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 235a6f540..2b271b1df 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -84,11 +84,11 @@ public: using Interface::submitTransaction; /// Makes the given call. Nothing is recorded into the state. - virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override; + virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override; using Interface::call; /// Makes the given create. Nothing is recorded into the state. - virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override; + virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override; using Interface::create; using Interface::balanceAt; diff --git a/libethereum/Defaults.cpp b/libethereum/Defaults.cpp index febe53d84..b839bbb5c 100644 --- a/libethereum/Defaults.cpp +++ b/libethereum/Defaults.cpp @@ -21,7 +21,7 @@ #include "Defaults.h" -#include +#include using namespace std; using namespace dev; using namespace dev::eth; diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 72ee1854d..d62d6716f 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -83,7 +83,7 @@ void EthereumHost::noteNeedsSyncing(EthereumPeer* _who) _who->attemptSync(); } -void EthereumHost::changeSyncer(EthereumPeer* _syncer) +void EthereumHost::changeSyncer(EthereumPeer* _syncer, bool _needHelp) { if (_syncer) clog(NetAllDetail) << "Changing syncer to" << _syncer->session()->socketId(); @@ -93,9 +93,10 @@ void EthereumHost::changeSyncer(EthereumPeer* _syncer) m_syncer = _syncer; if (isSyncing()) { - if (_syncer->m_asking == Asking::Blocks) + if (_needHelp && _syncer->m_asking == Asking::Blocks) for (auto j: peerSessions()) { + clog(NetNote) << "Getting help with downloading blocks"; auto e = j.first->cap().get(); if (e != _syncer && e->m_asking == Asking::Nothing) e->transition(Asking::Blocks); diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index d53c3cc79..95c7f147a 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -108,7 +108,7 @@ private: virtual void onStarting() { startWorking(); } virtual void onStopping() { stopWorking(); } - void changeSyncer(EthereumPeer* _ignore); + void changeSyncer(EthereumPeer* _ignore, bool _needHelp = true); BlockChain const& m_chain; TransactionQueue& m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index 85bdf33e9..b3846757c 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -74,7 +74,7 @@ string toString(Asking _a) return "?"; } -void EthereumPeer::transition(Asking _a, bool _force) +void EthereumPeer::transition(Asking _a, bool _force, bool _needHelp) { clog(NetMessageSummary) << "Transition!" << ::toString(_a) << "from" << ::toString(m_asking) << ", " << (isSyncing() ? "syncing" : "holding") << (needsSyncing() ? "& needed" : ""); @@ -151,7 +151,7 @@ void EthereumPeer::transition(Asking _a, bool _force) if (m_asking == Asking::Nothing || m_asking == Asking::Hashes || m_asking == Asking::Blocks) { // Looks like it's the best yet for total difficulty. Set to download. - setAsking(Asking::Blocks, isSyncing()); // will kick off other peers to help if available. + setAsking(Asking::Blocks, isSyncing(), _needHelp); // will kick off other peers to help if available. auto blocks = m_sub.nextFetch(c_maxBlocksAsk); if (blocks.size()) { @@ -200,13 +200,13 @@ void EthereumPeer::transition(Asking _a, bool _force) clog(NetWarn) << "Invalid state transition:" << ::toString(_a) << "from" << ::toString(m_asking) << ", " << (isSyncing() ? "syncing" : "holding") << (needsSyncing() ? "& needed" : ""); } -void EthereumPeer::setAsking(Asking _a, bool _isSyncing) +void EthereumPeer::setAsking(Asking _a, bool _isSyncing, bool _needHelp) { bool changedAsking = (m_asking != _a); m_asking = _a; if (_isSyncing != (host()->m_syncer == this) || (_isSyncing && changedAsking)) - host()->changeSyncer(_isSyncing ? this : nullptr); + host()->changeSyncer(_isSyncing ? this : nullptr, _needHelp); if (!_isSyncing) { @@ -599,9 +599,10 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) clog(NetMessageSummary) << knowns << "knowns," << unknowns << "unknowns"; if (unknowns > 0) { + clog(NetNote) << "Not syncing and new block hash discovered: syncing without help."; host()->m_man.resetToChain(m_syncingNeededBlocks); - host()->changeSyncer(this); - transition(Asking::Blocks); + host()->changeSyncer(this, false); + transition(Asking::Blocks, false, false); // TODO: transaction(Asking::NewBlocks, false) } return true; } diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h index 54f7ad829..ae2289102 100644 --- a/libethereum/EthereumPeer.h +++ b/libethereum/EthereumPeer.h @@ -77,7 +77,7 @@ private: virtual bool interpret(unsigned _id, RLP const& _r); /// Transition state in a particular direction. - void transition(Asking _wantState, bool _force = false); + void transition(Asking _wantState, bool _force = false, bool _needHelp = true); /// Attempt to begin syncing with this peer; first check the peer has a more difficlult chain to download, then start asking for hashes, then move to blocks. void attemptSync(); @@ -89,7 +89,7 @@ private: void clearKnownTransactions() { std::lock_guard l(x_knownTransactions); m_knownTransactions.clear(); } /// Update our asking state. - void setAsking(Asking _g, bool _isSyncing); + void setAsking(Asking _g, bool _isSyncing, bool _needHelp = true); /// Update our syncing requirements state. void setNeedsSyncing(h256 _latestHash, u256 _td); diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index ecfdd7721..0bf8bdbb5 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -160,6 +160,42 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen return !m_ext; } +bool Executive::call(CallParameters const& _p, u256 const& _gasPrice, Address const& _origin) +{ + m_isCreation = false; +// cnote << "Transferring" << formatBalance(_value) << "to receiver."; + auto it = !(_p.codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_p.codeAddress) : precompiled().end(); + if (it != precompiled().end()) + { + bigint g = it->second.gas(_p.data); + if (_p.gas < g) + { + m_gas = 0; + m_excepted = TransactionException::OutOfGasBase; + // Bail from exception. + return true; // true actually means "all finished - nothing more to be done regarding go(). + } + else + { + m_gas = (u256)(_p.gas - g); + m_precompiledOut = it->second.exec(_p.data); + m_out = &m_precompiledOut; + } + } + else if (m_s.addressHasCode(_p.codeAddress)) + { + m_vm = VMFactory::create(); + bytes const& c = m_s.code(_p.codeAddress); + m_ext = make_shared(m_s, m_lastHashes, _p.receiveAddress, _p.senderAddress, _origin, _p.value, _gasPrice, _p.data, &c, m_depth); + } + else + m_gas = _p.gas; + + m_s.transferBalance(_p.senderAddress, _p.receiveAddress, _p.value); + + return !m_ext; +} + bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin) { m_isCreation = true; @@ -244,6 +280,9 @@ bool Executive::go(OnOpFunc const& _onOp) m_gas = 0; m_excepted = toTransactionException(_e); m_ext->revert(); + + if (m_isCreation) + m_newAddress = Address(); } catch (Exception const& _e) { diff --git a/libethereum/Executive.h b/libethereum/Executive.h index 6057659fa..6f72d0966 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -95,6 +95,7 @@ public: /// Set up the executive for evaluating a bare CALL (message call) operation. /// @returns false iff go() must be called (and thus a VM execution in required). bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress); + bool call(CallParameters const& _cp, u256 const& _gasPrice, Address const& _origin); /// Finalise an operation through accruing the substate into the parent context. void accrueSubState(SubState& _parentContext); @@ -137,7 +138,7 @@ private: Transaction m_t; ///< The original transaction. Set by setup(). LogEntries m_logs; ///< The log entries created by this transaction. Set by finalize(). - bigint m_gasRequired; + bigint m_gasRequired; ///< Gas required during execution of the transaction. bigint m_gasCost; bigint m_totalCost; }; diff --git a/libethereum/ExtVM.cpp b/libethereum/ExtVM.cpp index 650200059..488d8e4b7 100644 --- a/libethereum/ExtVM.cpp +++ b/libethereum/ExtVM.cpp @@ -26,16 +26,16 @@ using namespace std; using namespace dev; 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) +bool ExtVM::call(CallParameters& _p) { Executive e(m_s, lastHashes, depth + 1); - if (!e.call(_receiveAddress, _codeAddressOverride, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin)) + if (!e.call(_p, gasPrice, origin)) { - e.go(_onOp); + e.go(_p.onOp); e.accrueSubState(sub); } - io_gas = e.gas(); - e.out().copyTo(_out); + _p.gas = e.gas(); + e.out().copyTo(_p.out); return !e.excepted(); } diff --git a/libethereum/ExtVM.h b/libethereum/ExtVM.h index 1a2d180dd..babff4edf 100644 --- a/libethereum/ExtVM.h +++ b/libethereum/ExtVM.h @@ -58,7 +58,7 @@ public: virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final; /// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller. - virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final; + virtual bool call(CallParameters& _params) override final; /// Read address's balance. virtual u256 balance(Address _a) override final { return m_s.balance(_a); } diff --git a/libethereum/Farm.cpp b/libethereum/Farm.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/libethereum/KeyManager.cpp b/libethereum/KeyManager.cpp index 11b2cb2a6..8c3fd28c3 100644 --- a/libethereum/KeyManager.cpp +++ b/libethereum/KeyManager.cpp @@ -61,12 +61,17 @@ bool KeyManager::load(std::string const& _pass) if (version == 1) { for (auto const& i: s[1]) + { m_keyInfo[m_addrLookup[(Address)i[0]] = (h128)i[1]] = KeyInfo((h256)i[2], (std::string)i[3]); + cdebug << toString((Address)i[0]) << toString((h128)i[1]) << toString((h256)i[2]) << (std::string)i[3]; + } + for (auto const& i: s[2]) m_passwordInfo[(h256)i[0]] = (std::string)i[1]; m_password = (string)s[3]; } m_cachedPasswords[hashPassword(m_password)] = m_password; + m_cachedPasswords[hashPassword(defaultPassword())] = defaultPassword(); return true; } catch (...) { @@ -210,4 +215,6 @@ void KeyManager::write(h128 const& _key, std::string const& _keysFile) const writeFile(_keysFile, encryptSymNoAuth(_key, h128(), &s.out())); m_key = _key; + m_cachedPasswords[hashPassword(defaultPassword())] = defaultPassword(); + } diff --git a/libethereum/KeyManager.h b/libethereum/KeyManager.h index 38e8d8853..0a83fcc00 100644 --- a/libethereum/KeyManager.h +++ b/libethereum/KeyManager.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include namespace dev { @@ -75,10 +75,11 @@ public: Address address(h128 const& _uuid) const; h128 import(Secret const& _s, std::string const& _info, std::string const& _pass, std::string const& _passInfo); - h128 import(Secret const& _s, std::string const& _info) { return import(_s, _info, m_password, std::string()); } + h128 import(Secret const& _s, std::string const& _info) { return import(_s, _info, defaultPassword(), std::string()); } SecretStore& store() { return m_store; } void importExisting(h128 const& _uuid, std::string const& _info, std::string const& _pass, std::string const& _passInfo); + void importExisting(h128 const& _uuid, std::string const& _info) { importExisting(_uuid, _info, defaultPassword(), std::string()); } Secret secret(Address const& _address, std::function const& _pass = DontKnowThrow) const; Secret secret(h128 const& _uuid, std::function const& _pass = DontKnowThrow) const; @@ -87,6 +88,7 @@ public: void kill(Address const& _a); private: + std::string defaultPassword() const { return asString(m_key.ref()); } h256 hashPassword(std::string const& _pass) const; // Only use if previously loaded ok. @@ -103,7 +105,11 @@ private: // Passwords that we're storing. mutable std::unordered_map m_cachedPasswords; - // The default password for keys in the keystore - protected by the master password. + // DEPRECATED. + // Used to be the default password for keys in the keystore, stored in the keys file. + // Now the default password is based off the key of the keys file directly, so this is redundant + // except for the fact that people have existing keys stored with it. Leave for now until/unless + // we have an upgrade strategy. std::string m_password; SecretStore m_store; diff --git a/libethereum/LogFilter.cpp b/libethereum/LogFilter.cpp index ab9848d59..21ba9d3ef 100644 --- a/libethereum/LogFilter.cpp +++ b/libethereum/LogFilter.cpp @@ -21,7 +21,7 @@ #include "LogFilter.h" -#include +#include #include "State.h" using namespace std; using namespace dev; diff --git a/libethereum/Precompiled.cpp b/libethereum/Precompiled.cpp index cdcb4a46a..0e80949fe 100644 --- a/libethereum/Precompiled.cpp +++ b/libethereum/Precompiled.cpp @@ -21,7 +21,9 @@ #include "Precompiled.h" -#include +#include +#include +#include #include #include #include @@ -61,19 +63,12 @@ static bytes ecrecoverCode(bytesConstRef _in) static bytes sha256Code(bytesConstRef _in) { - bytes ret(32); - sha256(_in, &ret); - return ret; + return sha256(_in).asBytes(); } static bytes ripemd160Code(bytesConstRef _in) { - bytes ret(32); - ripemd160(_in, &ret); - // leaves the 20-byte hash left-aligned. we want it right-aligned: - memmove(ret.data() + 12, ret.data(), 20); - memset(ret.data(), 0, 12); - return ret; + return h256(ripemd160(_in), h256::AlignRight).asBytes(); } static bytes identityCode(bytesConstRef _in) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 50e4b26ab..c753f57ea 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,7 @@ OverlayDB State::openDB(std::string _path, WithExisting _we) boost::filesystem::remove_all(_path + "/state"); ldb::Options o; + o.max_open_files = 256; o.create_if_missing = true; ldb::DB* db = nullptr; ldb::DB::Open(o, _path + "/state", &db); @@ -113,7 +115,7 @@ State::State(OverlayDB const& _db, BaseState _bs, Address _coinbaseAddress): paranoia("end of normal construction.", true); } -State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h): +State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h, ImportRequirements::value _ir): m_db(_db), m_state(&m_db), m_blockReward(c_blockReward) @@ -135,18 +137,18 @@ State::State(OverlayDB const& _db, BlockChain const& _bc, h256 _h): // 1. Start at parent's end state (state root). BlockInfo bip; bip.populate(_bc.block(bi.parentHash)); - sync(_bc, bi.parentHash, bip); + sync(_bc, bi.parentHash, bip, _ir); // 2. Enact the block's transactions onto this state. m_ourAddress = bi.coinbaseAddress; - enact(&b, _bc); + enact(&b, _bc, _ir); } else { // Genesis required: // We know there are no transactions, so just populate directly. m_state.init(); - sync(_bc, _h, bi); + sync(_bc, _h, bi, _ir); } } @@ -515,10 +517,10 @@ pair State::sync(BlockChain const& _bc, TransactionQu cnote << i.first << "Dropping old transaction (nonce too low)"; _tq.drop(i.first); } - else if (got > req + 5) + else if (got > req + _tq.waiting(i.second.sender())) { // too new - cnote << i.first << "Dropping new transaction (> 5 nonces ahead)"; + cnote << i.first << "Dropping new transaction (too many nonces ahead)"; _tq.drop(i.first); } else @@ -533,7 +535,12 @@ pair State::sync(BlockChain const& _bc, TransactionQu _tq.drop(i.first); } else - _tq.setFuture(i); + { + // Temporarily no gas left in current block. + // OPTIMISE: could note this and then we don't evaluate until a block that does have the gas left. + // for now, just leave alone. +// _tq.setFuture(i); + } } catch (Exception const& _e) { @@ -591,34 +598,33 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement LastHashes lh = _bc.lastHashes((unsigned)m_previousBlock.number); RLP rlp(_block); + vector receipts; + // All ok with the block generally. Play back the transactions now... unsigned i = 0; for (auto const& tr: rlp[1]) { - RLPStream k; - k << i; - - transactionsTrie.insert(&k.out(), tr.data()); execute(lh, Transaction(tr.data(), CheckTransaction::Everything)); - - RLPStream receiptrlp; - m_receipts.back().streamRLP(receiptrlp); - receiptsTrie.insert(&k.out(), &receiptrlp.out()); + RLPStream receiptRLP; + m_receipts.back().streamRLP(receiptRLP); + receipts.push_back(receiptRLP.out()); ++i; } - if (receiptsTrie.root() != m_currentBlock.receiptsRoot) + auto receiptsRoot = orderedTrieRoot(receipts); + + if (receiptsRoot != m_currentBlock.receiptsRoot) { cwarn << "Bad receipts state root."; - cwarn << "Expected: " << toString(receiptsTrie.root()) << " received: " << toString(m_currentBlock.receiptsRoot); + cwarn << "Expected: " << toString(receiptsRoot) << " received: " << toString(m_currentBlock.receiptsRoot); cwarn << "Block:" << toHex(_block); cwarn << "Block RLP:" << rlp; - cwarn << "Calculated: " << receiptsTrie.root(); + cwarn << "Calculated: " << receiptsRoot; for (unsigned j = 0; j < i; ++j) { RLPStream k; k << j; - auto b = asBytes(receiptsTrie.at(&k.out())); + auto b = receipts[j]; cwarn << j << ": "; cwarn << "RLP: " << RLP(b); cwarn << "Hex: " << toHex(b); @@ -650,25 +656,23 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, ImportRequirement if (rlp[2].itemCount() > 2) BOOST_THROW_EXCEPTION(TooManyUncles()); - unordered_set nonces = { m_currentBlock.nonce }; vector rewarded; - h256Hash knownUncles = _bc.allUnclesFrom(m_currentBlock.parentHash); + h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash, 6); + excluded.insert(m_currentBlock.hash()); for (auto const& i: rlp[2]) { - if (knownUncles.count(sha3(i.data()))) - BOOST_THROW_EXCEPTION(UncleInChain() << errinfo_comment("Uncle in block already mentioned") << errinfo_data(toString(knownUncles)) << errinfo_hash256(sha3(i.data())) ); - - BlockInfo uncle = BlockInfo::fromHeader(i.data()); - if (nonces.count(uncle.nonce)) - BOOST_THROW_EXCEPTION(DuplicateUncleNonce()); + auto h = sha3(i.data()); + if (excluded.count(h)) + BOOST_THROW_EXCEPTION(UncleInChain() << errinfo_comment("Uncle in block already mentioned") << errinfo_data(toString(excluded)) << errinfo_hash256(sha3(i.data()))); + excluded.insert(h); + BlockInfo uncle = BlockInfo::fromHeader(i.data(), (_ir & ImportRequirements::CheckUncles) ? CheckEverything : IgnoreNonce, h); BlockInfo uncleParent(_bc.block(uncle.parentHash)); if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 7) BOOST_THROW_EXCEPTION(UncleTooOld()); uncle.verifyParent(uncleParent); - nonces.insert(uncle.nonce); // tdIncrease += uncle.difficulty; rewarded.push_back(uncle); } @@ -707,11 +711,21 @@ void State::cleanup(bool _fullCommit) { if (_fullCommit) { - paranoia("immediately before database commit", true); // Commit the new trie to disk. clog(StateTrace) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot << "=" << rootHash() << "=" << toHex(asBytes(m_db.lookup(rootHash()))); + + try { + EnforceRefs er(m_db, true); + rootHash(); + } + catch (BadRoot const&) + { + clog(StateChat) << "Trie corrupt! :-("; + throw; + } + m_db.commit(); clog(StateTrace) << "Committed: stateRoot" << m_currentBlock.stateRoot << "=" << rootHash() << "=" << toHex(asBytes(m_db.lookup(rootHash()))); @@ -807,14 +821,14 @@ void State::commitToMine(BlockChain const& _bc) { // Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations. // cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl; - h256Hash knownUncles = _bc.allUnclesFrom(m_currentBlock.parentHash); + h256Hash excluded = _bc.allKinFrom(m_currentBlock.parentHash, 6); auto p = m_previousBlock.parentHash; for (unsigned gen = 0; gen < 6 && p != _bc.genesisHash() && unclesCount < 2; ++gen, p = _bc.details(p).parent) { auto us = _bc.details(p).children; assert(us.size() >= 1); // must be at least 1 child of our grandparent - it's our own parent! for (auto const& u: us) - if (!knownUncles.count(u)) // ignore any uncles/mainline blocks that we know about. + if (!excluded.count(u)) // ignore any uncles/mainline blocks that we know about. { BlockInfo ubi(_bc.block(u)); ubi.streamRLP(unclesData, WithNonce); @@ -826,13 +840,8 @@ void State::commitToMine(BlockChain const& _bc) } } - MemoryDB tm; - GenericTrieDB transactionsTrie(&tm); - transactionsTrie.init(); - - MemoryDB rm; - GenericTrieDB receiptsTrie(&rm); - receiptsTrie.init(); + BytesMap transactionsMap; + BytesMap receiptsMap; RLPStream txs; txs.appendList(m_transactions.size()); @@ -844,11 +853,11 @@ void State::commitToMine(BlockChain const& _bc) RLPStream receiptrlp; m_receipts[i].streamRLP(receiptrlp); - receiptsTrie.insert(&k.out(), &receiptrlp.out()); + receiptsMap.insert(std::make_pair(k.out(), receiptrlp.out())); RLPStream txrlp; m_transactions[i].streamRLP(txrlp); - transactionsTrie.insert(&k.out(), &txrlp.out()); + transactionsMap.insert(std::make_pair(k.out(), txrlp.out())); txs.appendRaw(txrlp.out()); } @@ -857,8 +866,8 @@ void State::commitToMine(BlockChain const& _bc) RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); - m_currentBlock.transactionsRoot = transactionsTrie.root(); - m_currentBlock.receiptsRoot = receiptsTrie.root(); + m_currentBlock.transactionsRoot = hash256(transactionsMap); + m_currentBlock.receiptsRoot = hash256(receiptsMap); m_currentBlock.logBloom = logBloom(); m_currentBlock.sha3Uncles = sha3(m_currentUncles); diff --git a/libethereum/State.h b/libethereum/State.h index a11812c6f..f46d0e222 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -25,7 +25,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -118,7 +119,7 @@ public: explicit State(OverlayDB const& _db, BaseState _bs = BaseState::PreExisting, Address _coinbaseAddress = Address()); /// Construct state object from arbitrary point in blockchain. - State(OverlayDB const& _db, BlockChain const& _bc, h256 _hash); + State(OverlayDB const& _db, BlockChain const& _bc, h256 _hash, ImportRequirements::value _ir = ImportRequirements::Default); /// Copy state object. State(State const& _s); diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 78852b7b8..09d6cd54c 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -22,7 +22,7 @@ #pragma once #include -#include +#include #include #include namespace dev diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 5aca67a29..e488805d9 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -35,15 +35,26 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallb // Check if we already know this transaction. h256 h = sha3(_transactionRLP); + Transaction t; + ImportResult ir; + { UpgradableGuard l(m_lock); - auto ir = check_WITH_LOCK(h, _ik); + ir = check_WITH_LOCK(h, _ik); if (ir != ImportResult::Success) return ir; - Transaction t(_transactionRLP, CheckTransaction::Everything); - UpgradeGuard ul(l); - return manageImport_WITH_LOCK(h, t, _cb); + try { + t = Transaction(_transactionRLP, CheckTransaction::Everything); + UpgradeGuard ul(l); + ir = manageImport_WITH_LOCK(h, t, _cb); + } + catch (...) { + return ImportResult::Malformed; + } + } +// cdebug << "import-END: Nonce of" << t.sender() << "now" << maxNonce(t.sender()); + return ir; } ImportResult TransactionQueue::check_WITH_LOCK(h256 const& _h, IfDropped _ik) @@ -62,15 +73,33 @@ ImportResult TransactionQueue::import(Transaction const& _transaction, ImportCal // Check if we already know this transaction. h256 h = _transaction.sha3(WithSignature); - UpgradableGuard l(m_lock); - // TODO: keep old transactions around and check in State for nonce validity +// cdebug << "import-BEGIN: Nonce of sender" << maxNonce(_transaction.sender()); + ImportResult ret; + { + UpgradableGuard l(m_lock); + // TODO: keep old transactions around and check in State for nonce validity - auto ir = check_WITH_LOCK(h, _ik); - if (ir != ImportResult::Success) - return ir; + auto ir = check_WITH_LOCK(h, _ik); + if (ir != ImportResult::Success) + return ir; - UpgradeGuard ul(l); - return manageImport_WITH_LOCK(h, _transaction, _cb); + { + UpgradeGuard ul(l); + ret = manageImport_WITH_LOCK(h, _transaction, _cb); + } + } +// cdebug << "import-END: Nonce of" << _transaction.sender() << "now" << maxNonce(_transaction.sender()); + return ret; +} + +std::unordered_map TransactionQueue::transactions() const +{ + ReadGuard l(m_lock); + auto ret = m_current; + for (auto const& i: m_future) + if (i.second.nonce() < maxNonce_WITH_LOCK(i.second.sender())) + ret.insert(i); + return ret; } ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction, ImportCallback const& _cb) @@ -105,62 +134,100 @@ ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transactio u256 TransactionQueue::maxNonce(Address const& _a) const { - cdebug << "txQ::maxNonce" << _a; +// cdebug << "txQ::maxNonce" << _a; ReadGuard l(m_lock); + return maxNonce_WITH_LOCK(_a); +} + +u256 TransactionQueue::maxNonce_WITH_LOCK(Address const& _a) const +{ u256 ret = 0; auto r = m_senders.equal_range(_a); for (auto it = r.first; it != r.second; ++it) - { - cdebug << it->first << "1+" << m_current.at(it->second).nonce(); - DEV_IGNORE_EXCEPTIONS(ret = max(ret, m_current.at(it->second).nonce() + 1)); - } + if (m_current.count(it->second)) + { +// cdebug << it->first << "1+" << m_current.at(it->second).nonce(); + ret = max(ret, m_current.at(it->second).nonce() + 1); + } + else if (m_future.count(it->second)) + { +// cdebug << it->first << "1+" << m_future.at(it->second).nonce(); + ret = max(ret, m_future.at(it->second).nonce() + 1); + } + else + { + cwarn << "ERRROR!!!!! m_senders references non-current transaction"; + cwarn << "Sender" << it->first << "has transaction" << it->second; + cwarn << "Count of m_current for" << it->second << "is" << m_current.count(it->second); + } return ret; } void TransactionQueue::insertCurrent_WITH_LOCK(std::pair const& _p) { - cdebug << "txQ::insertCurrent" << _p.first << _p.second.sender() << _p.second.nonce(); +// cdebug << "txQ::insertCurrent" << _p.first << _p.second.sender() << _p.second.nonce(); m_senders.insert(make_pair(_p.second.sender(), _p.first)); + if (m_current.count(_p.first)) + cwarn << "Transaction hash" << _p.first << "already in current?!"; m_current.insert(_p); } -bool TransactionQueue::removeCurrent_WITH_LOCK(h256 const& _txHash) +bool TransactionQueue::remove_WITH_LOCK(h256 const& _txHash) { - cdebug << "txQ::removeCurrent" << _txHash; - if (m_current.count(_txHash)) +// cdebug << "txQ::remove" << _txHash; + for (std::unordered_map* pool: { &m_current, &m_future }) { - auto r = m_senders.equal_range(m_current[_txHash].sender()); - for (auto it = r.first; it != r.second; ++it) - if (it->second == _txHash) - { - cdebug << "=> sender" << it->first; - m_senders.erase(it); - break; - } - cdebug << "=> nonce" << m_current[_txHash].nonce(); - m_current.erase(_txHash); - return true; + auto pit = pool->find(_txHash); + if (pit != pool->end()) + { + auto r = m_senders.equal_range(pit->second.sender()); + for (auto i = r.first; i != r.second; ++i) + if (i->second == _txHash) + { + m_senders.erase(i); + break; + } +// cdebug << "=> nonce" << pit->second.nonce(); + pool->erase(pit); + return true; + } } return false; } +unsigned TransactionQueue::waiting(Address const& _a) const +{ + auto it = m_senders.equal_range(_a); + unsigned ret = 0; + for (auto i = it.first; i != it.second; ++i, ++ret) {} + return ret; +} + void TransactionQueue::setFuture(std::pair const& _t) { +// cdebug << "txQ::setFuture" << _t.first; WriteGuard l(m_lock); if (m_current.count(_t.first)) { - m_unknown.insert(make_pair(_t.second.sender(), _t)); + m_future.insert(_t); m_current.erase(_t.first); } } void TransactionQueue::noteGood(std::pair const& _t) { +// cdebug << "txQ::noteGood" << _t.first; WriteGuard l(m_lock); - auto r = m_unknown.equal_range(_t.second.sender()); + auto r = m_senders.equal_range(_t.second.sender()); for (auto it = r.first; it != r.second; ++it) - m_current.insert(it->second); - m_unknown.erase(r.first, r.second); + { + auto fit = m_future.find(it->second); + if (fit != m_future.end()) + { + m_current.insert(*fit); + m_future.erase(fit); + } + } } void TransactionQueue::drop(h256 const& _txHash) @@ -174,13 +241,5 @@ void TransactionQueue::drop(h256 const& _txHash) m_dropped.insert(_txHash); m_known.erase(_txHash); - if (!removeCurrent_WITH_LOCK(_txHash)) - { - for (auto i = m_unknown.begin(); i != m_unknown.end(); ++i) - if (i->second.first == _txHash) - { - m_unknown.erase(i); - break; - } - } + remove_WITH_LOCK(_txHash); } diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index 50fcea574..a07efb848 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -55,14 +55,15 @@ public: void drop(h256 const& _txHash); - std::unordered_map transactions() const { ReadGuard l(m_lock); return m_current; } - std::pair items() const { ReadGuard l(m_lock); return std::make_pair(m_current.size(), m_unknown.size()); } + unsigned waiting(Address const& _a) const; + std::unordered_map transactions() const; + std::pair items() const { ReadGuard l(m_lock); return std::make_pair(m_current.size(), m_future.size()); } u256 maxNonce(Address const& _a) const; void setFuture(std::pair const& _t); void noteGood(std::pair const& _t); - void clear() { WriteGuard l(m_lock); m_known.clear(); m_current.clear(); m_unknown.clear(); } + void clear() { WriteGuard l(m_lock); m_senders.clear(); m_known.clear(); m_current.clear(); m_future.clear(); } template Handler onReady(T const& _t) { return m_onReady.add(_t); } private: @@ -70,15 +71,16 @@ private: ImportResult manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction, ImportCallback const& _cb); void insertCurrent_WITH_LOCK(std::pair const& _p); - bool removeCurrent_WITH_LOCK(h256 const& _txHash); + bool remove_WITH_LOCK(h256 const& _txHash); + u256 maxNonce_WITH_LOCK(Address const& _a) const; mutable SharedMutex m_lock; ///< General lock. h256Hash m_known; ///< Hashes of transactions in both sets. + std::unordered_multimap m_senders; ///< Mapping from the sender address to the transaction hash; useful for determining the nonce of a given sender. std::unordered_map m_current; ///< Map of SHA3(tx) to tx. - std::unordered_multimap> m_unknown; ///< For transactions that have a future nonce; we map their sender address to the tx stuff, and insert once the sender has a valid TX. + std::unordered_map m_future; ///< For transactions that have a future nonce; we re-insert into current once the sender has a valid TX. std::unordered_map> m_callbacks; ///< Called once. h256Hash m_dropped; ///< Transactions that have previously been dropped. - std::multimap m_senders; ///< Mapping from the sender address to the transaction hash; useful for determining the nonce of a given sender. Signal m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast. }; diff --git a/libethereum/Utility.cpp b/libethereum/Utility.cpp index 7b0a961b2..adfea4a51 100644 --- a/libethereum/Utility.cpp +++ b/libethereum/Utility.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include using namespace std; using namespace dev; using namespace dev::eth; diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index 4bbdb36ac..6b35094bb 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -108,6 +108,18 @@ using LastHashes = std::vector; using OnOpFunc = std::function; +struct CallParameters +{ + Address senderAddress; + Address codeAddress; + Address receiveAddress; + u256 gas; + u256 value; + bytesConstRef data; + bytesRef out; + OnOpFunc onOp; +}; + /** * @brief Interface and null implementation of the class for specifying VM externalities. */ @@ -153,7 +165,7 @@ public: virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); } /// Make a new message call. - virtual bool call(Address, u256, bytesConstRef, u256&, bytesRef, OnOpFunc const&, Address, Address) { return false; } + virtual bool call(CallParameters&) { return false; } /// Revert any changes made (by any of the other calls). virtual void log(h256s&& _topics, bytesConstRef _data) { sub.logs.push_back(LogEntry(myAddress, std::move(_topics), _data.toBytes())); } diff --git a/libevm/SmartVM.cpp b/libevm/SmartVM.cpp index 7343bd7a2..d37abc1bf 100644 --- a/libevm/SmartVM.cpp +++ b/libevm/SmartVM.cpp @@ -21,7 +21,7 @@ #include "SmartVM.h" #include #include -#include +#include #include #include #include "VMFactory.h" diff --git a/libevm/VM.cpp b/libevm/VM.cpp index 695b556dd..f1bfc1f8a 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -53,6 +53,8 @@ bytesConstRef VM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint6 m_stack.reserve((unsigned)c_stackLimit); + unique_ptr callParams; + static const array c_metrics = metrics(); auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; }; @@ -613,13 +615,16 @@ bytesConstRef VM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint6 case Instruction::CALL: case Instruction::CALLCODE: { - u256 gas = m_stack.back(); + if (!callParams) + callParams.reset(new CallParameters); + + callParams->gas = m_stack.back(); if (m_stack[m_stack.size() - 3] > 0) - gas += c_callStipend; + callParams->gas += c_callStipend; m_stack.pop_back(); - Address receiveAddress = asAddress(m_stack.back()); + callParams->receiveAddress = asAddress(m_stack.back()); m_stack.pop_back(); - u256 value = m_stack.back(); + callParams->value = m_stack.back(); m_stack.pop_back(); unsigned inOff = (unsigned)m_stack.back(); @@ -631,12 +636,19 @@ bytesConstRef VM::go(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp, uint6 unsigned outSize = (unsigned)m_stack.back(); m_stack.pop_back(); - if (_ext.balance(_ext.myAddress) >= value && _ext.depth < 1024) - m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, {}, receiveAddress)); + if (_ext.balance(_ext.myAddress) >= callParams->value && _ext.depth < 1024) + { + callParams->onOp = _onOp; + callParams->senderAddress = _ext.myAddress; + callParams->codeAddress = inst == Instruction::CALL ? callParams->receiveAddress : callParams->senderAddress; + callParams->data = bytesConstRef(m_temp.data() + inOff, inSize); + callParams->out = bytesRef(m_temp.data() + outOff, outSize); + m_stack.push_back(_ext.call(*callParams)); + } else m_stack.push_back(0); - io_gas += gas; + io_gas += callParams->gas; break; } case Instruction::RETURN: diff --git a/libevm/VM.h b/libevm/VM.h index 8a641b1b8..99f608227 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include #include "VMFace.h" diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp index 9530ded49..6f38b0f42 100644 --- a/libevmasm/Assembly.cpp +++ b/libevmasm/Assembly.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include using namespace std; using namespace dev; @@ -120,13 +121,13 @@ ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap con _out << " " << instructionInfo(i.instruction()).name << "\t" << i.getJumpTypeAsString(); break; case Push: - _out << " PUSH " << i.data(); + _out << " PUSH " << hex << i.data(); break; case PushString: _out << " PUSH \"" << m_strings.at((h256)i.data()) << "\""; break; case PushTag: - _out << " PUSH [tag" << i.data() << "]"; + _out << " PUSH [tag" << dec << i.data() << "]"; break; case PushSub: _out << " PUSH [$" << h256(i.data()).abridged() << "]"; @@ -138,7 +139,7 @@ ostream& Assembly::streamAsm(ostream& _out, string const& _prefix, StringMap con _out << " PUSHSIZE"; break; case Tag: - _out << "tag" << i.data() << ": " << endl << _prefix << " JUMPDEST"; + _out << "tag" << dec << i.data() << ": " << endl << _prefix << " JUMPDEST"; break; case PushData: _out << " PUSH [" << hex << (unsigned)i.data() << "]"; @@ -207,7 +208,7 @@ Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes break; case PushTag: collection.append( - createJsonValue("PUSH [tag]", i.getLocation().start, i.getLocation().end, toStringInHex(i.data()))); + createJsonValue("PUSH [tag]", i.getLocation().start, i.getLocation().end, string(i.data()))); break; case PushSub: collection.append( @@ -222,19 +223,13 @@ Json::Value Assembly::streamAsmJson(ostream& _out, StringMap const& _sourceCodes createJsonValue("PUSHSIZE", i.getLocation().start, i.getLocation().end)); break; case Tag: - { collection.append( createJsonValue("tag", i.getLocation().start, i.getLocation().end, string(i.data()))); collection.append( createJsonValue("JUMDEST", i.getLocation().start, i.getLocation().end)); - } break; case PushData: - { - Json::Value pushData; - pushData["name"] = "PUSH hex"; - collection.append(createJsonValue("PUSH hex", i.getLocation().start, i.getLocation().end, toStringInHex(i.data()))); - } + collection.append(createJsonValue("PUSH data", i.getLocation().start, i.getLocation().end, toStringInHex(i.data()))); break; default: BOOST_THROW_EXCEPTION(InvalidOpcode()); @@ -311,54 +306,54 @@ Assembly& Assembly::optimise(bool _enable) copt << toString(*this); count = 0; - //@todo CFG interface should be a generator, that returns an item and a pointer to a - // knownstate, which has to replace the current state if it is not null. - // Feed these items to the CSE, but also store them and replace the stored version - // if the items generated by the CSE are shorter. (or even use less gas?) - copt << "Performing control flow analysis..."; + copt << "Performing optimisation..."; { ControlFlowGraph cfg(m_items); - AssemblyItems optItems; + AssemblyItems optimisedItems; for (BasicBlock const& block: cfg.optimisedBlocks()) - copy(m_items.begin() + block.begin, m_items.begin() + block.end, - back_inserter(optItems)); - if (optItems.size() < m_items.size()) { - copt << "Old size: " << m_items.size() << ", new size: " << optItems.size(); - m_items = move(optItems); - count++; + assertThrow(!!block.startState, OptimizerException, ""); + CommonSubexpressionEliminator eliminator(*block.startState); + auto iter = m_items.begin() + block.begin; + auto const end = m_items.begin() + block.end; + while (iter < end) + { + auto orig = iter; + iter = eliminator.feedItems(iter, end); + bool shouldReplace = false; + AssemblyItems optimisedChunk; + try + { + optimisedChunk = eliminator.getOptimizedItems(); + shouldReplace = (optimisedChunk.size() < size_t(iter - orig)); + } + catch (StackTooDeepException const&) + { + // This might happen if the opcode reconstruction is not as efficient + // as the hand-crafted code. + } + + if (shouldReplace) + { + copt << "Old size: " << (iter - orig) << ", new size: " << optimisedChunk.size(); + count++; + optimisedItems += optimisedChunk; + } + else + copy(orig, iter, back_inserter(optimisedItems)); + } } - } - copt << "Performing common subexpression elimination..."; - for (auto iter = m_items.begin(); iter != m_items.end();) - { - //@todo use only a single state / expression classes instance. - KnownState state(make_shared()); - CommonSubexpressionEliminator eliminator(state); - auto orig = iter; - iter = eliminator.feedItems(iter, m_items.end()); - AssemblyItems optItems; - bool shouldReplace = false; - try - { - optItems = eliminator.getOptimizedItems(); - shouldReplace = (optItems.size() < size_t(iter - orig)); - } - catch (StackTooDeepException const&) + if (optimisedItems.size() < m_items.size()) { - // This might happen if the opcode reconstruction is not as efficient - // as the hand-crafted code. + m_items = move(optimisedItems); + count++; } - if (shouldReplace) - { - copt << "Old size: " << (iter - orig) << ", new size: " << optItems.size(); + // This only modifies PushTags, we have to run again to actually remove code. + BlockDeduplicator dedup(m_items); + if (dedup.deduplicate()) count++; - for (auto moveIter = optItems.begin(); moveIter != optItems.end(); ++orig, ++moveIter) - *orig = move(*moveIter); - iter = m_items.erase(orig, iter); - } } } @@ -461,7 +456,8 @@ bytes Assembly::assemble() const for (auto const& i: tagRef) { bytesRef r(ret.data() + i.first, bytesPerTag); - toBigEndian(tagPos[i.second], r); + //@todo in the failure case, we could use the position of the invalid jumpdest + toBigEndian(i.second < tagPos.size() ? tagPos[i.second] : (1 << (8 * bytesPerTag)) - 1, r); } if (!m_data.empty()) diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h index 6f2a65de9..b3012a7ea 100644 --- a/libevmasm/AssemblyItem.h +++ b/libevmasm/AssemblyItem.h @@ -68,6 +68,8 @@ public: /// @returns true iff the type and data of the items are equal. bool operator==(AssemblyItem const& _other) const { return m_type == _other.m_type && m_data == _other.m_data; } bool operator!=(AssemblyItem const& _other) const { return !operator==(_other); } + /// Less-than operator compatible with operator==. + bool operator<(AssemblyItem const& _other) const { return std::tie(m_type, m_data) < std::tie(_other.m_type, _other.m_data); } /// @returns an upper bound for the number of bytes required by this item, assuming that /// the value of a jump tag takes @a _addressLength bytes. diff --git a/libevmasm/BlockDeduplicator.cpp b/libevmasm/BlockDeduplicator.cpp new file mode 100644 index 000000000..eadbe1b40 --- /dev/null +++ b/libevmasm/BlockDeduplicator.cpp @@ -0,0 +1,91 @@ +/* + 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 BlockDeduplicator.cpp + * @author Christian + * @date 2015 + * Unifies basic blocks that share content. + */ + +#include +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::eth; + + +bool BlockDeduplicator::deduplicate() +{ + // Compares indices based on the suffix that starts there, ignoring tags and stopping at + // opcodes that stop the control flow. + function comparator = [&](size_t _i, size_t _j) + { + if (_i == _j) + return false; + + BlockIterator first(m_items.begin() + _i, m_items.end()); + BlockIterator second(m_items.begin() + _j, m_items.end()); + BlockIterator end(m_items.end(), m_items.end()); + + if (first != end && (*first).type() == Tag) + ++first; + if (second != end && (*second).type() == Tag) + ++second; + + return std::lexicographical_compare(first, end, second, end); + }; + + set> blocksSeen(comparator); + map tagReplacement; + for (size_t i = 0; i < m_items.size(); ++i) + { + if (m_items.at(i).type() != Tag) + continue; + auto it = blocksSeen.find(i); + if (it == blocksSeen.end()) + blocksSeen.insert(i); + else + tagReplacement[m_items.at(i).data()] = m_items.at(*it).data(); + } + + bool ret = false; + for (AssemblyItem& item: m_items) + if (item.type() == PushTag && tagReplacement.count(item.data())) + { + ret = true; + item.setData(tagReplacement.at(item.data())); + } + return ret; +} + +BlockDeduplicator::BlockIterator& BlockDeduplicator::BlockIterator::operator++() +{ + if (it == end) + return *this; + if (SemanticInformation::altersControlFlow(*it) && *it != AssemblyItem(eth::Instruction::JUMPI)) + it = end; + else + { + ++it; + while (it != end && it->type() == Tag) + ++it; + } + return *this; +} diff --git a/libevmasm/BlockDeduplicator.h b/libevmasm/BlockDeduplicator.h new file mode 100644 index 000000000..8a82a1ed7 --- /dev/null +++ b/libevmasm/BlockDeduplicator.h @@ -0,0 +1,69 @@ +/* + 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 BlockDeduplicator.h + * @author Christian + * @date 2015 + * Unifies basic blocks that share content. + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +class AssemblyItem; +using AssemblyItems = std::vector; + +/** + * Optimizer class to be used to unify blocks that share content. + * Modifies the passed vector in place. + */ +class BlockDeduplicator +{ +public: + BlockDeduplicator(AssemblyItems& _items): m_items(_items) {} + /// @returns true if something was changed + bool deduplicate(); + +private: + /// Iterator that skips tags skips to the end if (all branches of) the control + /// flow does not continue to the next instruction. + struct BlockIterator: std::iterator + { + public: + BlockIterator(AssemblyItems::const_iterator _it, AssemblyItems::const_iterator _end): + it(_it), end(_end) { } + BlockIterator& operator++(); + bool operator==(BlockIterator const& _other) const { return it == _other.it; } + bool operator!=(BlockIterator const& _other) const { return it != _other.it; } + AssemblyItem const& operator*() const { return *it; } + AssemblyItems::const_iterator it; + AssemblyItems::const_iterator end; + }; + + AssemblyItems& m_items; +}; + +} +} diff --git a/libevmasm/CommonSubexpressionEliminator.cpp b/libevmasm/CommonSubexpressionEliminator.cpp index 4b85eba40..b2fa73116 100644 --- a/libevmasm/CommonSubexpressionEliminator.cpp +++ b/libevmasm/CommonSubexpressionEliminator.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -45,16 +45,22 @@ vector CommonSubexpressionEliminator::getOptimizedItems() for (int height = minHeight; height <= m_state.stackHeight(); ++height) targetStackContents[height] = m_state.stackElement(height, SourceLocation()); - // Debug info: - //stream(cout, initialStackContents, targetStackContents); - AssemblyItems items = CSECodeGenerator(m_state.expressionClasses(), m_storeOperations).generateCode( m_initialState.stackHeight(), initialStackContents, targetStackContents ); if (m_breakingItem) + { items.push_back(*m_breakingItem); + m_state.feedItem(*m_breakingItem); + } + + // cleanup + m_initialState = m_state; + m_breakingItem = nullptr; + m_storeOperations.clear(); + return items; } @@ -113,16 +119,14 @@ AssemblyItems CSECodeGenerator::generateCode( { m_stackHeight = _initialStackHeight; m_stack = _initialStack; + m_targetStack = _targetStackContents; for (auto const& item: m_stack) - if (!m_classPositions.count(item.second)) - m_classPositions[item.second] = item.first; - - // @todo: provide information about the positions of copies of class elements + m_classPositions[item.second].insert(item.first); // generate the dependency graph starting from final storage and memory writes and target stack contents for (auto const& p: m_storeOperations) addDependencies(p.second.back().expression); - for (auto const& targetItem: _targetStackContents) + for (auto const& targetItem: m_targetStack) { m_finalClasses.insert(targetItem.second); addDependencies(targetItem.second); @@ -141,13 +145,18 @@ AssemblyItems CSECodeGenerator::generateCode( generateClassElement(seqAndId.second, true); // generate the target stack elements - for (auto const& targetItem: _targetStackContents) + for (auto const& targetItem: m_targetStack) { - int position = generateClassElement(targetItem.second); - assertThrow(position != c_invalidPosition, OptimizerException, ""); - if (position == targetItem.first) + if (m_stack.count(targetItem.first) && m_stack.at(targetItem.first) == targetItem.second) + continue; // already there + generateClassElement(targetItem.second); + assertThrow(!m_classPositions[targetItem.second].empty(), OptimizerException, ""); + if (m_classPositions[targetItem.second].count(targetItem.first)) continue; - SourceLocation const& location = m_expressionClasses.representative(targetItem.second).item->getLocation(); + SourceLocation location; + if (m_expressionClasses.representative(targetItem.second).item) + location = m_expressionClasses.representative(targetItem.second).item->getLocation(); + int position = classElementPosition(targetItem.second); if (position < targetItem.first) // it is already at its target, we need another copy appendDup(position, location); @@ -164,21 +173,24 @@ AssemblyItems CSECodeGenerator::generateCode( // check validity int finalHeight = 0; - if (!_targetStackContents.empty()) + if (!m_targetStack.empty()) // have target stack, so its height should be the final height - finalHeight = (--_targetStackContents.end())->first; + finalHeight = (--m_targetStack.end())->first; else if (!_initialStack.empty()) // no target stack, only erase the initial stack finalHeight = _initialStack.begin()->first - 1; else // neither initial no target stack, no change in height - finalHeight = 0; + finalHeight = _initialStackHeight; assertThrow(finalHeight == m_stackHeight, OptimizerException, "Incorrect final stack height."); + return m_generatedItems; } void CSECodeGenerator::addDependencies(Id _c) { + if (m_classPositions.count(_c)) + return; // it is already on the stack if (m_neededBy.count(_c)) return; // we already computed the dependencies for _c ExpressionClasses::Expression expr = m_expressionClasses.representative(_c); @@ -187,7 +199,7 @@ void CSECodeGenerator::addDependencies(Id _c) addDependencies(argument); m_neededBy.insert(make_pair(argument, _c)); } - if (expr.item->type() == Operation && ( + if (expr.item && expr.item->type() == Operation && ( expr.item->instruction() == Instruction::SLOAD || expr.item->instruction() == Instruction::MLOAD || expr.item->instruction() == Instruction::SHA3 @@ -254,19 +266,23 @@ void CSECodeGenerator::addDependencies(Id _c) } } -int CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) +void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) { + for (auto it: m_classPositions) + for (auto p: it.second) + if (p > m_stackHeight) + assertThrow(false, OptimizerException, ""); // do some cleanup removeStackTopIfPossible(); if (m_classPositions.count(_c)) { assertThrow( - m_classPositions[_c] != c_invalidPosition, + !m_classPositions[_c].empty(), OptimizerException, "Element already removed but still needed." ); - return m_classPositions[_c]; + return; } ExpressionClasses::Expression const& expr = m_expressionClasses.representative(_c); assertThrow( @@ -274,6 +290,7 @@ int CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) OptimizerException, "Sequence constrained operation requested out of sequence." ); + assertThrow(expr.item, OptimizerException, "Non-generated expression without item."); vector const& arguments = expr.arguments; for (Id arg: boost::adaptors::reverse(arguments)) generateClassElement(arg); @@ -339,16 +356,16 @@ int CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) m_generatedItems.back() == AssemblyItem(Instruction::SWAP1)) // this will not append a swap but remove the one that is already there appendOrRemoveSwap(m_stackHeight - 1, location); - for (auto arg: arguments) - if (canBeRemoved(arg, _c)) - m_classPositions[arg] = c_invalidPosition; for (size_t i = 0; i < arguments.size(); ++i) + { + m_classPositions[m_stack[m_stackHeight - i]].erase(m_stackHeight - i); m_stack.erase(m_stackHeight - i); + } appendItem(*expr.item); if (expr.item->type() != Operation || instructionInfo(expr.item->instruction()).ret == 1) { m_stack[m_stackHeight] = _c; - return m_classPositions[_c] = m_stackHeight; + m_classPositions[_c].insert(m_stackHeight); } else { @@ -357,31 +374,39 @@ int CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced) OptimizerException, "Invalid number of return values." ); - return m_classPositions[_c] = c_invalidPosition; + m_classPositions[_c]; // ensure it is created to mark the expression as generated } } int CSECodeGenerator::classElementPosition(Id _id) const { assertThrow( - m_classPositions.count(_id) && m_classPositions.at(_id) != c_invalidPosition, + m_classPositions.count(_id) && !m_classPositions.at(_id).empty(), OptimizerException, "Element requested but is not present." ); - return m_classPositions.at(_id); + return *max_element(m_classPositions.at(_id).begin(), m_classPositions.at(_id).end()); } -bool CSECodeGenerator::canBeRemoved(Id _element, Id _result) +bool CSECodeGenerator::canBeRemoved(Id _element, Id _result, int _fromPosition) { - // Returns false if _element is finally needed or is needed by a class that has not been - // computed yet. Note that m_classPositions also includes classes that were deleted in the meantime. - if (m_finalClasses.count(_element)) - return false; + // Default for _fromPosition is the canonical position of the element. + if (_fromPosition == c_invalidPosition) + _fromPosition = classElementPosition(_element); - auto range = m_neededBy.equal_range(_element); - for (auto it = range.first; it != range.second; ++it) - if (it->second != _result && !m_classPositions.count(it->second)) - return false; + bool haveCopy = m_classPositions.at(_element).size() > 1; + if (m_finalClasses.count(_element)) + // It is part of the target stack. It can be removed if it is a copy that is not in the target position. + return haveCopy && (!m_targetStack.count(_fromPosition) || m_targetStack[_fromPosition] != _element); + else if (!haveCopy) + { + // Can be removed unless it is needed by a class that has not been computed yet. + // Note that m_classPositions also includes classes that were deleted in the meantime. + auto range = m_neededBy.equal_range(_element); + for (auto it = range.first; it != range.second; ++it) + if (it->second != _result && !m_classPositions.count(it->second)) + return false; + } return true; } @@ -391,11 +416,11 @@ bool CSECodeGenerator::removeStackTopIfPossible() return false; assertThrow(m_stack.count(m_stackHeight) > 0, OptimizerException, ""); Id top = m_stack[m_stackHeight]; - if (!canBeRemoved(top)) + if (!canBeRemoved(top, Id(-1), m_stackHeight)) return false; - m_generatedItems.push_back(AssemblyItem(Instruction::POP)); + m_classPositions[m_stack[m_stackHeight]].erase(m_stackHeight); m_stack.erase(m_stackHeight); - m_stackHeight--; + appendItem(AssemblyItem(Instruction::POP)); return true; } @@ -407,6 +432,7 @@ void CSECodeGenerator::appendDup(int _fromPosition, SourceLocation const& _locat assertThrow(1 <= instructionNum, OptimizerException, "Invalid stack access."); appendItem(AssemblyItem(dupInstruction(instructionNum), _location)); m_stack[m_stackHeight] = m_stack[_fromPosition]; + m_classPositions[m_stack[m_stackHeight]].insert(m_stackHeight); } void CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, SourceLocation const& _location) @@ -418,13 +444,15 @@ void CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, SourceLocation cons assertThrow(instructionNum <= 16, StackTooDeepException, "Stack too deep."); assertThrow(1 <= instructionNum, OptimizerException, "Invalid stack access."); appendItem(AssemblyItem(swapInstruction(instructionNum), _location)); - // The value of a class can be present in multiple locations on the stack. We only update the - // "canonical" one that is tracked by m_classPositions - if (m_classPositions[m_stack[m_stackHeight]] == m_stackHeight) - m_classPositions[m_stack[m_stackHeight]] = _fromPosition; - if (m_classPositions[m_stack[_fromPosition]] == _fromPosition) - m_classPositions[m_stack[_fromPosition]] = m_stackHeight; - swap(m_stack[m_stackHeight], m_stack[_fromPosition]); + + if (m_stack[m_stackHeight] != m_stack[_fromPosition]) + { + m_classPositions[m_stack[m_stackHeight]].erase(m_stackHeight); + m_classPositions[m_stack[m_stackHeight]].insert(_fromPosition); + m_classPositions[m_stack[_fromPosition]].erase(_fromPosition); + m_classPositions[m_stack[_fromPosition]].insert(m_stackHeight); + swap(m_stack[m_stackHeight], m_stack[_fromPosition]); + } if (m_generatedItems.size() >= 2 && SemanticInformation::isSwapInstruction(m_generatedItems.back()) && *(m_generatedItems.end() - 2) == m_generatedItems.back()) diff --git a/libevmasm/CommonSubexpressionEliminator.h b/libevmasm/CommonSubexpressionEliminator.h index 6e1ba40b3..a35e31d90 100644 --- a/libevmasm/CommonSubexpressionEliminator.h +++ b/libevmasm/CommonSubexpressionEliminator.h @@ -71,13 +71,6 @@ public: /// @returns the resulting items after optimization. AssemblyItems getOptimizedItems(); - /// Streams debugging information to @a _out. - std::ostream& stream( - std::ostream& _out, - std::map _initialStack = std::map(), - std::map _targetStack = std::map() - ) const; - private: /// Feeds the item into the system for analysis. void feedItem(AssemblyItem const& _item, bool _copyItem = false); @@ -126,16 +119,15 @@ private: void addDependencies(Id _c); /// Produce code that generates the given element if it is not yet present. - /// @returns the stack position of the element or c_invalidPosition if it does not actually - /// generate a value on the stack. /// @param _allowSequenced indicates that sequence-constrained operations are allowed - int generateClassElement(Id _c, bool _allowSequenced = false); + void generateClassElement(Id _c, bool _allowSequenced = false); /// @returns the position of the representative of the given id on the stack. /// @note throws an exception if it is not on the stack. int classElementPosition(Id _id) const; - /// @returns true if @a _element can be removed - in general or, if given, while computing @a _result. - bool canBeRemoved(Id _element, Id _result = Id(-1)); + /// @returns true if the copy of @a _element can be removed from stack position _fromPosition + /// - in general or, if given, while computing @a _result. + bool canBeRemoved(Id _element, Id _result = Id(-1), int _fromPosition = c_invalidPosition); /// Appends code to remove the topmost stack element if it can be removed. bool removeStackTopIfPossible(); @@ -157,8 +149,8 @@ private: std::multimap m_neededBy; /// Current content of the stack. std::map m_stack; - /// Current positions of equivalence classes, equal to c_invalidPosition if already deleted. - std::map m_classPositions; + /// Current positions of equivalence classes, equal to the empty set if already deleted. + std::map> m_classPositions; /// The actual eqivalence class items and how to compute them. ExpressionClasses& m_expressionClasses; @@ -167,6 +159,7 @@ private: std::map, StoreOperations> m_storeOperations; /// The set of equivalence classes that should be present on the stack at the end. std::set m_finalClasses; + std::map m_targetStack; }; template @@ -175,6 +168,7 @@ _AssemblyItemIterator CommonSubexpressionEliminator::feedItems( _AssemblyItemIterator _end ) { + assertThrow(!m_breakingItem, OptimizerException, "Invalid use of CommonSubexpressionEliminator."); for (; _iterator != _end && !SemanticInformation::breaksCSEAnalysisBlock(*_iterator); ++_iterator) feedItem(*_iterator); if (_iterator != _end) diff --git a/libevmasm/ControlFlowGraph.cpp b/libevmasm/ControlFlowGraph.cpp index 2e28317a3..3566bdb17 100644 --- a/libevmasm/ControlFlowGraph.cpp +++ b/libevmasm/ControlFlowGraph.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -142,7 +143,7 @@ void ControlFlowGraph::removeUnusedBlocks() BasicBlock const& block = m_blocks.at(blocksToProcess.back()); blocksToProcess.pop_back(); for (BlockId tag: block.pushedTags) - if (!neededBlocks.count(tag)) + if (!neededBlocks.count(tag) && m_blocks.count(tag)) { neededBlocks.insert(tag); blocksToProcess.push_back(tag); @@ -191,12 +192,12 @@ void ControlFlowGraph::setPrevLinks() if (push.type() != PushTag) continue; BlockId nextId(push.data()); - if (m_blocks.at(nextId).prev) + if (m_blocks.count(nextId) && m_blocks.at(nextId).prev) continue; bool hasLoop = false; - for (BlockId id = nextId; id && !hasLoop; id = m_blocks.at(id).next) + for (BlockId id = nextId; id && m_blocks.count(id) && !hasLoop; id = m_blocks.at(id).next) hasLoop = (id == blockId); - if (hasLoop) + if (hasLoop || !m_blocks.count(nextId)) continue; m_blocks[nextId].prev = blockId; @@ -217,7 +218,6 @@ void ControlFlowGraph::gatherKnowledge() // @todo actually we know that memory is filled with zeros at the beginning, // we could make use of that. KnownStatePointer emptyState = make_shared(); - ExpressionClasses& expr = emptyState->expressionClasses(); bool unknownJumpEncountered = false; vector> workQueue({make_pair(BlockId::initial(), emptyState->copy())}); @@ -225,6 +225,8 @@ void ControlFlowGraph::gatherKnowledge() { //@todo we might have to do something like incrementing the sequence number for each JUMPDEST assertThrow(!!workQueue.back().first, OptimizerException, ""); + if (!m_blocks.count(workQueue.back().first)) + continue; // too bad, we do not know the tag, probably an invalid jump BasicBlock& block = m_blocks.at(workQueue.back().first); KnownStatePointer state = workQueue.back().second; workQueue.pop_back(); @@ -236,8 +238,6 @@ void ControlFlowGraph::gatherKnowledge() } block.startState = state->copy(); - //@todo we might know the return address for the first pass, but not anymore for the second, - // -> store knowledge about tags as a union. // Feed all items except for the final jump yet because it will erase the target tag. unsigned pc = block.begin; @@ -252,22 +252,29 @@ void ControlFlowGraph::gatherKnowledge() assertThrow(block.begin <= pc && pc == block.end - 1, OptimizerException, ""); //@todo in the case of JUMPI, add knowledge about the condition to the state // (for both values of the condition) - BlockId nextBlock = expressionClassToBlockId( - state->stackElement(state->stackHeight(), SourceLocation()), - expr + set tags = state->tagsInExpression( + state->stackElement(state->stackHeight(), SourceLocation()) ); state->feedItem(m_items.at(pc++)); - if (nextBlock) - workQueue.push_back(make_pair(nextBlock, state->copy())); - else if (!unknownJumpEncountered) + + if (tags.empty() || std::any_of(tags.begin(), tags.end(), [&](u256 const& _tag) + { + return !m_blocks.count(BlockId(_tag)); + })) { - // We do not know where this jump goes, so we have to reset the states of all - // JUMPDESTs. - unknownJumpEncountered = true; - for (auto const& it: m_blocks) - if (it.second.begin < it.second.end && m_items[it.second.begin].type() == Tag) - workQueue.push_back(make_pair(it.first, emptyState->copy())); + if (!unknownJumpEncountered) + { + // We do not know the target of this jump, so we have to reset the states of all + // JUMPDESTs. + unknownJumpEncountered = true; + for (auto const& it: m_blocks) + if (it.second.begin < it.second.end && m_items[it.second.begin].type() == Tag) + workQueue.push_back(make_pair(it.first, emptyState->copy())); + } } + else + for (auto tag: tags) + workQueue.push_back(make_pair(BlockId(tag), state->copy())); } else if (block.begin <= pc && pc < block.end) state->feedItem(m_items.at(pc++)); @@ -281,6 +288,15 @@ void ControlFlowGraph::gatherKnowledge() ) workQueue.push_back(make_pair(block.next, state->copy())); } + + // Remove all blocks we never visited here. This might happen because a tag is pushed but + // never used for a JUMP. + // Note that this invalidates some contents of pushedTags + for (auto it = m_blocks.begin(); it != m_blocks.end();) + if (!it->second.startState) + it = m_blocks.erase(it); + else + it++; } BasicBlocks ControlFlowGraph::rebuildCode() @@ -288,7 +304,8 @@ BasicBlocks ControlFlowGraph::rebuildCode() map pushes; for (auto& idAndBlock: m_blocks) for (BlockId ref: idAndBlock.second.pushedTags) - pushes[ref]++; + if (m_blocks.count(ref)) + pushes[ref]++; set blocksToAdd; for (auto it: m_blocks) @@ -317,7 +334,11 @@ BasicBlocks ControlFlowGraph::rebuildCode() if (previousHandedOver && !pushes[blockId] && m_items[block.begin].type() == Tag) ++block.begin; if (block.begin < block.end) + { blocks.push_back(block); + blocks.back().startState->clearTagUnions(); + blocks.back().endState->clearTagUnions(); + } previousHandedOver = (block.endType == BasicBlock::EndType::HANDOVER); } } @@ -325,18 +346,6 @@ BasicBlocks ControlFlowGraph::rebuildCode() return blocks; } -BlockId ControlFlowGraph::expressionClassToBlockId( - ExpressionClasses::Id _id, - ExpressionClasses& _exprClasses -) -{ - ExpressionClasses::Expression expr = _exprClasses.representative(_id); - if (expr.item && expr.item->type() == PushTag) - return BlockId(expr.item->data()); - else - return BlockId::invalid(); -} - BlockId ControlFlowGraph::generateNewId() { BlockId id = BlockId(++m_lastUsedId); diff --git a/libevmasm/ControlFlowGraph.h b/libevmasm/ControlFlowGraph.h index 3366dc45f..4480ba491 100644 --- a/libevmasm/ControlFlowGraph.h +++ b/libevmasm/ControlFlowGraph.h @@ -108,10 +108,6 @@ private: void setPrevLinks(); BasicBlocks rebuildCode(); - /// @returns the corresponding BlockId if _id is a pushed jump tag, - /// and an invalid BlockId otherwise. - BlockId expressionClassToBlockId(ExpressionClasses::Id _id, ExpressionClasses& _exprClasses); - BlockId generateNewId(); unsigned m_lastUsedId = 0; diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index cfbeba7fa..81adc0dbb 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -82,6 +82,16 @@ ExpressionClasses::Id ExpressionClasses::find( return exp.id; } +ExpressionClasses::Id ExpressionClasses::newClass(SourceLocation const& _location) +{ + Expression exp; + exp.id = m_representatives.size(); + exp.item = storeItem(AssemblyItem(UndefinedItem, (u256(1) << 255) + exp.id, _location)); + m_representatives.push_back(exp); + m_expressions.insert(exp); + return exp.id; +} + bool ExpressionClasses::knownToBeDifferent(ExpressionClasses::Id _a, ExpressionClasses::Id _b) { // Try to simplify "_a - _b" and return true iff the value is a non-zero constant. diff --git a/libevmasm/ExpressionClasses.h b/libevmasm/ExpressionClasses.h index c83520300..dd94092e8 100644 --- a/libevmasm/ExpressionClasses.h +++ b/libevmasm/ExpressionClasses.h @@ -52,7 +52,8 @@ public: Id id; AssemblyItem const* item = nullptr; Ids arguments; - unsigned sequenceNumber; ///< Storage modification sequence, only used for SLOAD/SSTORE instructions. + /// Storage modification sequence, only used for storage and memory operations. + unsigned sequenceNumber = 0; /// Behaves as if this was a tuple of (item->type(), item->data(), arguments, sequenceNumber). bool operator<(Expression const& _other) const; }; @@ -73,6 +74,9 @@ public: /// @returns the number of classes. Id size() const { return m_representatives.size(); } + /// @returns the id of a new class which is different to all other classes. + Id newClass(SourceLocation const& _location); + /// @returns true if the values of the given classes are known to be different (on every input). /// @note that this function might still return false for some different inputs. bool knownToBeDifferent(Id _a, Id _b); diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp index 41ac4802b..895778ed1 100644 --- a/libevmasm/KnownState.cpp +++ b/libevmasm/KnownState.cpp @@ -23,7 +23,7 @@ #include "KnownState.h" #include -#include +#include #include using namespace std; @@ -160,23 +160,68 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool return op; } -void KnownState::reduceToCommonKnowledge(KnownState const& /*_other*/) +/// Helper function for KnownState::reduceToCommonKnowledge, removes everything from +/// _this which is not in or not equal to the value in _other. +template void intersect(_Mapping& _this, _Mapping const& _other) { - //@todo - *this = KnownState(m_expressionClasses); + for (auto it = _this.begin(); it != _this.end();) + if (_other.count(it->first) && _other.at(it->first) == it->second) + ++it; + else + it = _this.erase(it); +} + +void KnownState::reduceToCommonKnowledge(KnownState const& _other) +{ + int stackDiff = m_stackHeight - _other.m_stackHeight; + for (auto it = m_stackElements.begin(); it != m_stackElements.end();) + if (_other.m_stackElements.count(it->first - stackDiff)) + { + Id other = _other.m_stackElements.at(it->first - stackDiff); + if (it->second == other) + ++it; + else + { + set theseTags = tagsInExpression(it->second); + set otherTags = tagsInExpression(other); + if (!theseTags.empty() && !otherTags.empty()) + { + theseTags.insert(otherTags.begin(), otherTags.end()); + it->second = tagUnion(theseTags); + ++it; + } + else + it = m_stackElements.erase(it); + } + } + else + it = m_stackElements.erase(it); + + // Use the smaller stack height. Essential to terminate in case of loops. + if (m_stackHeight > _other.m_stackHeight) + { + map shiftedStack; + for (auto const& stackElement: m_stackElements) + shiftedStack[stackElement.first - stackDiff] = stackElement.second; + m_stackElements = move(shiftedStack); + m_stackHeight = _other.m_stackHeight; + } + + intersect(m_storageContent, _other.m_storageContent); + intersect(m_memoryContent, _other.m_memoryContent); } bool KnownState::operator==(const KnownState& _other) const { - //@todo - return ( - m_stackElements.empty() && - _other.m_stackElements.empty() && - m_storageContent.empty() && - _other.m_storageContent.empty() && - m_memoryContent.empty() && - _other.m_memoryContent.empty() - ); + if (m_storageContent != _other.m_storageContent || m_memoryContent != _other.m_memoryContent) + return false; + int stackDiff = m_stackHeight - _other.m_stackHeight; + auto thisIt = m_stackElements.cbegin(); + auto otherIt = _other.m_stackElements.cbegin(); + for (; thisIt != m_stackElements.cend() && otherIt != _other.m_stackElements.cend(); ++thisIt, ++otherIt) + if (thisIt->first - stackDiff != otherIt->first || thisIt->second != otherIt->second) + return false; + return (thisIt == m_stackElements.cend() && otherIt == _other.m_stackElements.cend()); } ExpressionClasses::Id KnownState::stackElement(int _stackHeight, SourceLocation const& _location) @@ -184,18 +229,17 @@ ExpressionClasses::Id KnownState::stackElement(int _stackHeight, SourceLocation if (m_stackElements.count(_stackHeight)) return m_stackElements.at(_stackHeight); // Stack element not found (not assigned yet), create new unknown equivalence class. - //@todo check that we do not infer incorrect equivalences when the stack is cleared partially - //in between. - return m_stackElements[_stackHeight] = initialStackElement(_stackHeight, _location); + return m_stackElements[_stackHeight] = + m_expressionClasses->find(AssemblyItem(UndefinedItem, _stackHeight, _location)); } -ExpressionClasses::Id KnownState::initialStackElement( - int _stackHeight, - SourceLocation const& _location -) +void KnownState::clearTagUnions() { - // This is a special assembly item that refers to elements pre-existing on the initial stack. - return m_expressionClasses->find(AssemblyItem(UndefinedItem, u256(_stackHeight), _location)); + for (auto it = m_stackElements.begin(); it != m_stackElements.end();) + if (m_tagUnions.left.count(it->second)) + it = m_stackElements.erase(it); + else + ++it; } void KnownState::setStackElement(int _stackHeight, Id _class) @@ -324,3 +368,27 @@ KnownState::Id KnownState::applySha3( return m_knownSha3Hashes[arguments] = v; } +set KnownState::tagsInExpression(KnownState::Id _expressionId) +{ + if (m_tagUnions.left.count(_expressionId)) + return m_tagUnions.left.at(_expressionId); + // Might be a tag, then return the set of itself. + ExpressionClasses::Expression expr = m_expressionClasses->representative(_expressionId); + if (expr.item && expr.item->type() == PushTag) + return set({expr.item->data()}); + else + return set(); +} + +KnownState::Id KnownState::tagUnion(set _tags) +{ + if (m_tagUnions.right.count(_tags)) + return m_tagUnions.right.at(_tags); + else + { + Id id = m_expressionClasses->newClass(SourceLocation()); + m_tagUnions.right.insert(make_pair(_tags, id)); + return id; + } +} + diff --git a/libevmasm/KnownState.h b/libevmasm/KnownState.h index f7a3dd675..3505df74f 100644 --- a/libevmasm/KnownState.h +++ b/libevmasm/KnownState.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -107,15 +108,16 @@ public: /// @returns true if the knowledge about the state of both objects is (known to be) equal. bool operator==(KnownState const& _other) const; - ///@todo the sequence numbers in two copies of this class should never be the same. - /// might be doable using two-dimensional sequence numbers, where the first value is incremented - /// for each copy - /// Retrieves the current equivalence class fo the given stack element (or generates a new /// one if it does not exist yet). Id stackElement(int _stackHeight, SourceLocation const& _location); - /// @returns the equivalence class id of the special initial stack element at the given height. - Id initialStackElement(int _stackHeight, SourceLocation const& _location); + + /// @returns its set of tags if the given expression class is a known tag union; returns a set + /// containing the tag if it is a PushTag expression and the empty set otherwise. + std::set tagsInExpression(Id _expressionId); + /// During analysis, different tags on the stack are partially treated as the same class. + /// This removes such classes not to confuse later analyzers. + void clearTagUnions(); int stackHeight() const { return m_stackHeight; } std::map const& stackElements() const { return m_stackElements; } @@ -142,6 +144,9 @@ private: /// Finds or creates a new expression that applies the sha3 hash function to the contents in memory. Id applySha3(Id _start, Id _length, SourceLocation const& _location); + /// @returns a new or already used Id representing the given set of tags. + Id tagUnion(std::set _tags); + /// Current stack height, can be negative. int m_stackHeight = 0; /// Current stack layout, mapping stack height -> equivalence class @@ -157,6 +162,8 @@ private: std::map, Id> m_knownSha3Hashes; /// Structure containing the classes of equivalent expressions. std::shared_ptr m_expressionClasses; + /// Container for unions of tags stored on the stack. + boost::bimap> m_tagUnions; }; } diff --git a/libjsconsole/JSConsole.cpp b/libjsconsole/JSConsole.cpp index 791df2de4..d1f7c0264 100644 --- a/libjsconsole/JSConsole.cpp +++ b/libjsconsole/JSConsole.cpp @@ -25,7 +25,6 @@ #include #include "JSConsole.h" #include "JSV8Connector.h" -#include "libjsconsole/JSConsoleResources.hpp" // TODO! make readline optional! #include @@ -35,12 +34,12 @@ using namespace std; using namespace dev; using namespace dev::eth; -JSConsole::JSConsole(WebThreeDirect& _web3, std::vector const& _accounts): +JSConsole::JSConsole(WebThreeDirect& _web3, shared_ptr const& _accounts): m_engine(), m_printer(m_engine) { m_jsonrpcConnector.reset(new JSV8Connector(m_engine)); - m_jsonrpcServer.reset(new WebThreeStubServer(*m_jsonrpcConnector.get(), _web3, _accounts)); + m_jsonrpcServer.reset(new WebThreeStubServer(*m_jsonrpcConnector.get(), _web3, _accounts, vector())); } JSConsole::~JSConsole() {} diff --git a/libjsconsole/JSConsole.h b/libjsconsole/JSConsole.h index 3b65691f6..b7aded4f3 100644 --- a/libjsconsole/JSConsole.h +++ b/libjsconsole/JSConsole.h @@ -33,10 +33,12 @@ namespace dev namespace eth { +class AccountHolder; + class JSConsole { public: - JSConsole(WebThreeDirect& _web3, std::vector const& _accounts); + JSConsole(WebThreeDirect& _web3, std::shared_ptr const& _accounts); ~JSConsole(); void repl() const; diff --git a/libjsqrc/ethereumjs/bower.json b/libjsqrc/ethereumjs/bower.json index db9a4702d..ed620555f 100644 --- a/libjsqrc/ethereumjs/bower.json +++ b/libjsqrc/ethereumjs/bower.json @@ -1,7 +1,7 @@ { "name": "web3", "namespace": "ethereum", - "version": "0.3.6", + "version": "0.4.2", "description": "Ethereum Compatible JavaScript API", "main": [ "./dist/web3.js", diff --git a/libjsqrc/ethereumjs/dist/web3-light.js b/libjsqrc/ethereumjs/dist/web3-light.js index c128634de..be6d95eec 100644 --- a/libjsqrc/ethereumjs/dist/web3-light.js +++ b/libjsqrc/ethereumjs/dist/web3-light.js @@ -15,52 +15,6 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ You should have received a copy of the GNU Lesser General Public License along with ethereum.js. If not, see . */ -/** - * @file abi.js - * @author Marek Kotewicz - * @author Gav Wood - * @date 2014 - */ - -var coder = require('./coder'); -var utils = require('./utils'); - -var formatConstructorParams = function (abi, params) { - var constructor = utils.getConstructor(abi, params.length); - if (!constructor) { - if (params.length > 0) { - console.warn("didn't found matching constructor, using default one"); - } - return ''; - } - - return coder.encodeParams(constructor.inputs.map(function (input) { - return input.type; - }), params); -}; - -module.exports = { - formatConstructorParams: formatConstructorParams -}; - - -},{"./coder":2,"./utils":5}],2:[function(require,module,exports){ -/* - This file is part of ethereum.js. - - ethereum.js is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethereum.js 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with ethereum.js. If not, see . -*/ /** * @file coder.js * @author Marek Kotewicz @@ -328,7 +282,7 @@ var coder = new SolidityCoder([ module.exports = coder; -},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(require,module,exports){ +},{"../utils/utils":6,"./formatters":2,"./param":3,"bignumber.js":"bignumber.js"}],2:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -548,7 +502,7 @@ module.exports = { }; -},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":6,"./param":3,"bignumber.js":"bignumber.js"}],3:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -760,54 +714,7 @@ SolidityParam.decodeArray = function (bytes, index) { module.exports = SolidityParam; -},{"../utils/utils":8}],5:[function(require,module,exports){ -/* - This file is part of ethereum.js. - - ethereum.js is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethereum.js 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with ethereum.js. If not, see . -*/ -/** - * @file utils.js - * @author Marek Kotewicz - * @date 2015 - */ - -/** - * Returns the contstructor with matching number of arguments - * - * @method getConstructor - * @param {Array} abi - * @param {Number} numberOfArgs - * @returns {Object} constructor function abi - */ -var getConstructor = function (abi, numberOfArgs) { - return abi.filter(function (f) { - return f.type === 'constructor' && f.inputs.length === numberOfArgs; - })[0]; -}; - -//var getSupremeType = function (type) { - //return type.substr(0, type.indexOf('[')) + ']'; -//}; - - -module.exports = { - getConstructor: getConstructor -}; - - -},{}],6:[function(require,module,exports){ +},{"../utils/utils":6}],4:[function(require,module,exports){ 'use strict'; // go env doesn't have and need XMLHttpRequest @@ -818,7 +725,7 @@ if (typeof XMLHttpRequest === 'undefined') { } -},{}],7:[function(require,module,exports){ +},{}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -890,7 +797,7 @@ module.exports = { }; -},{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],6:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1256,6 +1163,7 @@ var toAddress = function (address) { return '0x' + padLeft(toHex(address).substr(2), 40); }; + /** * Returns true if object is BigNumber, otherwise false * @@ -1366,12 +1274,12 @@ module.exports = { }; -},{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],7:[function(require,module,exports){ module.exports={ - "version": "0.3.6" + "version": "0.4.2" } -},{}],10:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1411,6 +1319,7 @@ var RequestManager = require('./web3/requestmanager'); var c = require('./utils/config'); var Method = require('./web3/method'); var Property = require('./web3/property'); +var Batch = require('./web3/batch'); var web3Methods = [ new Method({ @@ -1503,6 +1412,9 @@ web3.toBigNumber = utils.toBigNumber; web3.toWei = utils.toWei; web3.fromWei = utils.fromWei; web3.isAddress = utils.isAddress; +web3.createBatch = function () { + return new Batch(); +}; // ADD defaultblock Object.defineProperty(web3.eth, 'defaultBlock', { @@ -1538,7 +1450,70 @@ setupMethods(web3.shh, shh.methods); module.exports = web3; -},{"./utils/config":7,"./utils/utils":8,"./version.json":9,"./web3/db":12,"./web3/eth":14,"./web3/filter":16,"./web3/formatters":17,"./web3/method":21,"./web3/net":22,"./web3/property":23,"./web3/requestmanager":25,"./web3/shh":26,"./web3/watches":27}],11:[function(require,module,exports){ +},{"./utils/config":5,"./utils/utils":6,"./version.json":7,"./web3/batch":9,"./web3/db":11,"./web3/eth":13,"./web3/filter":15,"./web3/formatters":16,"./web3/method":20,"./web3/net":21,"./web3/property":22,"./web3/requestmanager":24,"./web3/shh":25,"./web3/watches":26}],9:[function(require,module,exports){ +/* + This file is part of ethereum.js. + + ethereum.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ethereum.js 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with ethereum.js. If not, see . +*/ +/** + * @file batch.js + * @author Marek Kotewicz + * @date 2015 + */ + +var RequestManager = require('./requestmanager'); + +var Batch = function () { + this.requests = []; +}; + +/** + * Should be called to add create new request to batch request + * + * @method add + * @param {Object} jsonrpc requet object + */ +Batch.prototype.add = function (request) { + this.requests.push(request); +}; + +/** + * Should be called to execute batch request + * + * @method execute + */ +Batch.prototype.execute = function () { + var requests = this.requests; + RequestManager.getInstance().sendBatch(requests, function (err, results) { + results = results || []; + requests.map(function (request, index) { + return results[index] || {}; + }).map(function (result, index) { + return requests[index].format ? requests[index].format(result.result) : result.result; + }).forEach(function (result, index) { + if (requests[index].callback) { + requests[index].callback(err, result); + } + }); + }); +}; + +module.exports = Batch; + + +},{"./requestmanager":24}],10:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1562,13 +1537,39 @@ module.exports = web3; */ var web3 = require('../web3'); -var solAbi = require('../solidity/abi'); var utils = require('../utils/utils'); +var coder = require('../solidity/coder'); var SolidityEvent = require('./event'); var SolidityFunction = require('./function'); -var addFunctionsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to encode constructor params + * + * @method encodeConstructorParams + * @param {Array} abi + * @param {Array} constructor params + */ +var encodeConstructorParams = function (abi, params) { + return abi.filter(function (json) { + return json.type === 'constructor' && json.inputs.length === params.length; + }).map(function (json) { + return json.inputs.map(function (input) { + return input.type; + }); + }).map(function (types) { + return coder.encodeParams(types, params); + })[0] || ''; +}; + +/** + * Should be called to add functions to contract object + * + * @method addFunctionsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addFunctionsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'function'; }).map(function (json) { return new SolidityFunction(json, contract.address); @@ -1577,8 +1578,15 @@ var addFunctionsToContract = function (contract, desc) { }); }; -var addEventsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to add events to contract object + * + * @method addEventsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addEventsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'event'; }).map(function (json) { return new SolidityEvent(json, contract.address); @@ -1588,65 +1596,106 @@ var addEventsToContract = function (contract, desc) { }; /** - * This method should be called when we want to call / transact some solidity method from javascript - * it returns an object which has same methods available as solidity contract description - * usage example: - * - * var abi = [{ - * name: 'myMethod', - * inputs: [{ name: 'a', type: 'string' }], - * outputs: [{name: 'd', type: 'string' }] - * }]; // contract abi - * - * var MyContract = web3.eth.contract(abi); // creation of contract prototype - * - * var contractInstance = new MyContract('0x0123123121'); + * Should be called to create new ContractFactory * - * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default) - * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit) - * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction - * - * @param abi - abi json description of the contract, which is being created - * @returns contract object + * @method contract + * @param {Array} abi + * @returns {ContractFactory} new contract factory */ var contract = function (abi) { + return new ContractFactory(abi); +}; - // return prototype - return Contract.bind(null, abi); +/** + * Should be called to create new ContractFactory instance + * + * @method ContractFactory + * @param {Array} abi + */ +var ContractFactory = function (abi) { + this.abi = abi; }; -var Contract = function (abi, options) { +/** + * Should be called to create new contract on a blockchain + * + * @method new + * @param {Any} contract constructor param1 (optional) + * @param {Any} contract constructor param2 (optional) + * @param {Object} contract transaction object (required) + * @param {Function} callback + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.new = function () { + // parse arguments + var options = {}; // required! + var callback; - this.address = ''; - if (utils.isAddress(options)) { - this.address = options; - } else { // is an object! - // TODO, parse the rest of the args - options = options || {}; - var args = Array.prototype.slice.call(arguments, 2); - var bytes = solAbi.formatConstructorParams(abi, args); - options.data += bytes; - this.address = web3.eth.sendTransaction(options); + var args = Array.prototype.slice.call(arguments); + if (utils.isFunction(args[args.length - 1])) { + callback = args.pop(); } - addFunctionsToContract(this, abi); - addEventsToContract(this, abi); + var last = args[args.length - 1]; + if (utils.isObject(last) && !utils.isArray(last)) { + options = args.pop(); + } + + // throw an error if there are no options + + var bytes = encodeConstructorParams(this.abi, args); + options.data += bytes; + + if (!callback) { + var address = web3.eth.sendTransaction(options); + return this.at(address); + } + + var self = this; + web3.eth.sendTransaction(options, function (err, address) { + if (err) { + callback(err); + } + self.at(address, callback); + }); }; -Contract.prototype.call = function () { - console.error('contract.call is deprecated'); - return this; +/** + * Should be called to get access to existing contract on a blockchain + * + * @method at + * @param {Address} contract address (required) + * @param {Function} callback {optional) + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.at = function (address, callback) { + // TODO: address is required + + if (callback) { + callback(null, new Contract(this.abi, address)); + } + return new Contract(this.abi, address); }; -Contract.prototype.sendTransaction = function () { - console.error('contract.sendTransact is deprecated'); - return this; +/** + * Should be called to create new contract instance + * + * @method Contract + * @param {Array} abi + * @param {Address} contract address + */ +var Contract = function (abi, address) { + this.address = address; + addFunctionsToContract(this, abi); + addEventsToContract(this, abi); }; module.exports = contract; -},{"../solidity/abi":1,"../utils/utils":8,"../web3":10,"./event":15,"./function":18}],12:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":6,"../web3":8,"./event":14,"./function":17}],11:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1704,7 +1753,7 @@ module.exports = { methods: methods }; -},{"./method":21}],13:[function(require,module,exports){ +},{"./method":20}],12:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1744,7 +1793,7 @@ module.exports = { }; -},{}],14:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1921,6 +1970,14 @@ var call = new Method({ inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter] }); +var estimateGas = new Method({ + name: 'estimateGas', + call: 'eth_estimateGas', + params: 1, + inputFormatter: [formatters.inputTransactionFormatter], + outputFormatter: utils.toDecimal +}); + var compileSolidity = new Method({ name: 'compile.solidity', call: 'eth_compileSolidity', @@ -1939,6 +1996,18 @@ var compileSerpent = new Method({ params: 1 }); +var submitWork = new Method({ + name: 'submitWork', + call: 'eth_submitWork', + params: 3 +}); + +var getWork = new Method({ + name: 'getWork', + call: 'eth_getWork', + params: 0 +}); + var methods = [ getBalance, getStorageAt, @@ -1952,10 +2021,13 @@ var methods = [ getTransactionFromBlock, getTransactionCount, call, + estimateGas, sendTransaction, compileSolidity, compileLLL, compileSerpent, + submitWork, + getWork ]; /// @returns an array of objects describing web3.eth api properties @@ -1998,7 +2070,7 @@ module.exports = { }; -},{"../utils/utils":8,"./formatters":17,"./method":21,"./property":23}],15:[function(require,module,exports){ +},{"../utils/utils":6,"./formatters":16,"./method":20,"./property":22}],14:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2194,7 +2266,7 @@ SolidityEvent.prototype.attachToContract = function (contract) { module.exports = SolidityEvent; -},{"../solidity/coder":2,"../utils/utils":8,"../web3":10,"./formatters":17}],16:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":6,"../web3":8,"./formatters":16}],15:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2351,7 +2423,7 @@ Filter.prototype.get = function (callback) { module.exports = Filter; -},{"../utils/utils":8,"./formatters":17,"./requestmanager":25}],17:[function(require,module,exports){ +},{"../utils/utils":6,"./formatters":16,"./requestmanager":24}],16:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2571,7 +2643,7 @@ module.exports = { }; -},{"../utils/config":7,"../utils/utils":8}],18:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":6}],17:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2588,7 +2660,7 @@ module.exports = { You should have received a copy of the GNU Lesser General Public License along with ethereum.js. If not, see . */ -/** +/** * @file function.js * @author Marek Kotewicz * @date 2015 @@ -2613,18 +2685,23 @@ var SolidityFunction = function (json, address) { this._address = address; }; +SolidityFunction.prototype.extractCallback = function (args) { + if (utils.isFunction(args[args.length - 1])) { + return args.pop(); // modify the args array! + } +}; + /** * Should be used to create payload from arguments * * @method toPayload - * @param {...} solidity function params + * @param {Array} solidity function params * @param {Object} optional payload options */ -SolidityFunction.prototype.toPayload = function () { - var args = Array.prototype.slice.call(arguments); +SolidityFunction.prototype.toPayload = function (args) { var options = {}; if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) { - options = args.pop(); + options = args[args.length - 1]; } options.to = this._address; options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args); @@ -2641,19 +2718,41 @@ SolidityFunction.prototype.signature = function () { return web3.sha3(web3.fromAscii(this._name)).slice(2, 10); }; + +SolidityFunction.prototype.unpackOutput = function (output) { + if (output === null) { + return; + } + + output = output.length >= 2 ? output.slice(2) : output; + var result = coder.decodeParams(this._outputTypes, output); + return result.length === 1 ? result[0] : result; +}; + /** - * Should be used to call function - * + * Calls a contract function. + * * @method call - * @param {Object} options + * @param {...Object} Contract function arguments + * @param {function} If the last argument is a function, the contract function + * call will be asynchronous, and the callback will be passed the + * error and result. * @return {String} output bytes */ SolidityFunction.prototype.call = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - var output = web3.eth.call(payload); - output = output.length >= 2 ? output.slice(2) : output; - var result = coder.decodeParams(this._outputTypes, output); - return result.length === 1 ? result[0] : result; + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + var output = web3.eth.call(payload); + return this.unpackOutput(output); + } + + var self = this; + web3.eth.call(payload, function (error, output) { + callback(error, self.unpackOutput(output)); + }); }; /** @@ -2663,8 +2762,16 @@ SolidityFunction.prototype.call = function () { * @param {Object} options */ SolidityFunction.prototype.sendTransaction = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - web3.eth.sendTransaction(payload); + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + web3.eth.sendTransaction(payload); + return; + } + + web3.eth.sendTransaction(payload, callback); }; /** @@ -2679,7 +2786,7 @@ SolidityFunction.prototype.displayName = function () { /** * Should be used to get function type name - * + * * @method typeName * @return {String} type name of the function */ @@ -2687,6 +2794,25 @@ SolidityFunction.prototype.typeName = function () { return utils.extractTypeName(this._name); }; +/** + * Should be called to get rpc requests from solidity function + * + * @method request + * @returns {Object} + */ +SolidityFunction.prototype.request = function () { + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + var format = this.unpackOutput.bind(this); + + return { + callback: callback, + payload: payload, + format: format + }; +}; + /** * Should be called to execute function * @@ -2694,7 +2820,7 @@ SolidityFunction.prototype.typeName = function () { */ SolidityFunction.prototype.execute = function () { var transaction = !this._constant; - + // send transaction if (transaction) { return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments)); @@ -2712,6 +2838,7 @@ SolidityFunction.prototype.execute = function () { */ SolidityFunction.prototype.attachToContract = function (contract) { var execute = this.execute.bind(this); + execute.request = this.request.bind(this); execute.call = this.call.bind(this); execute.sendTransaction = this.sendTransaction.bind(this); var displayName = this.displayName(); @@ -2724,7 +2851,7 @@ SolidityFunction.prototype.attachToContract = function (contract) { module.exports = SolidityFunction; -},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":6,"../web3":8}],18:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2816,7 +2943,7 @@ HttpProvider.prototype.sendAsync = function (payload, callback) { module.exports = HttpProvider; -},{"./errors":13,"xmlhttprequest":6}],20:[function(require,module,exports){ +},{"./errors":12,"xmlhttprequest":4}],19:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2909,7 +3036,7 @@ Jsonrpc.prototype.toBatchPayload = function (messages) { module.exports = Jsonrpc; -},{}],21:[function(require,module,exports){ +},{}],20:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2966,7 +3093,6 @@ Method.prototype.extractCallback = function (args) { if (utils.isFunction(args[args.length - 1])) { return args.pop(); // modify the args array! } - return null; }; /** @@ -3019,6 +3145,7 @@ Method.prototype.formatOutput = function (result) { */ Method.prototype.attachToObject = function (obj) { var func = this.send.bind(this); + func.request = this.request.bind(this); func.call = this.call; // that's ugly. filter.js uses it var name = this.name.split('.'); if (name.length > 1) { @@ -3049,6 +3176,19 @@ Method.prototype.toPayload = function (args) { }; }; +/** + * Should be called to create pure JSONRPC request which can be used in batch request + * + * @method request + * @param {...} params + * @return {Object} jsonrpc request + */ +Method.prototype.request = function () { + var payload = this.toPayload(Array.prototype.slice.call(arguments)); + payload.format = this.formatOutput.bind(this); + return payload; +}; + /** * Should send request to the API * @@ -3061,7 +3201,7 @@ Method.prototype.send = function () { if (payload.callback) { var self = this; return RequestManager.getInstance().sendAsync(payload, function (err, result) { - payload.callback(null, self.formatOutput(result)); + payload.callback(err, self.formatOutput(result)); }); } return this.formatOutput(RequestManager.getInstance().send(payload)); @@ -3070,7 +3210,7 @@ Method.prototype.send = function () { module.exports = Method; -},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(require,module,exports){ +},{"../utils/utils":6,"./errors":12,"./requestmanager":24}],21:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3120,7 +3260,7 @@ module.exports = { }; -},{"../utils/utils":8,"./property":23}],23:[function(require,module,exports){ +},{"../utils/utils":6,"./property":22}],22:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3186,16 +3326,23 @@ Property.prototype.formatOutput = function (result) { Property.prototype.attachToObject = function (obj) { var proto = { get: this.get.bind(this), - set: this.set.bind(this) }; - var name = this.name.split('.'); - if (name.length > 1) { - obj[name[0]] = obj[name[0]] || {}; - Object.defineProperty(obj[name[0]], name[1], proto); - } else { - Object.defineProperty(obj, name[0], proto); + var names = this.name.split('.'); + var name = names[0]; + if (names.length > 1) { + obj[names[0]] = obj[names[0]] || {}; + obj = obj[names[0]]; + name = names[1]; } + + Object.defineProperty(obj, name, proto); + + var toAsyncName = function (prefix, name) { + return prefix + name.charAt(0).toUpperCase() + name.slice(1); + }; + + obj[toAsyncName('get', name)] = this.getAsync.bind(this); }; /** @@ -3211,22 +3358,27 @@ Property.prototype.get = function () { }; /** - * Should be used to set value of the property + * Should be used to asynchrounously get value of property * - * @method set - * @param {Object} new value of the property + * @method getAsync + * @param {Function} */ -Property.prototype.set = function (value) { - return RequestManager.getInstance().send({ - method: this.setter, - params: [this.formatInput(value)] +Property.prototype.getAsync = function (callback) { + var self = this; + RequestManager.getInstance().sendAsync({ + method: this.getter + }, function (err, result) { + if (err) { + return callback(err); + } + callback(err, self.formatOutput(result)); }); }; module.exports = Property; -},{"./requestmanager":25}],24:[function(require,module,exports){ +},{"./requestmanager":24}],23:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3261,7 +3413,7 @@ QtSyncProvider.prototype.send = function (payload) { module.exports = QtSyncProvider; -},{}],25:[function(require,module,exports){ +},{}],24:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3369,6 +3521,33 @@ RequestManager.prototype.sendAsync = function (data, callback) { }); }; +/** + * Should be called to asynchronously send batch request + * + * @method sendBatch + * @param {Array} batch data + * @param {Function} callback + */ +RequestManager.prototype.sendBatch = function (data, callback) { + if (!this.provider) { + return callback(errors.InvalidProvider()); + } + + var payload = Jsonrpc.getInstance().toBatchPayload(data); + + this.provider.sendAsync(payload, function (err, results) { + if (err) { + return callback(err); + } + + if (!utils.isArray(results)) { + return callback(errors.InvalidResponse(results)); + } + + callback(err, results); + }); +}; + /** * Should be used to set provider of request manager * @@ -3482,7 +3661,7 @@ RequestManager.prototype.poll = function () { module.exports = RequestManager; -},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":6,"./errors":12,"./jsonrpc":19}],25:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3552,7 +3731,7 @@ module.exports = { }; -},{"./formatters":17,"./method":21}],27:[function(require,module,exports){ +},{"./formatters":16,"./method":20}],26:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3580,7 +3759,20 @@ var Method = require('./method'); /// @returns an array of objects describing web3.eth.filter api methods var eth = function () { var newFilterCall = function (args) { - return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter'; + var type = args[0]; + + switch(type) { + case 'latest': + args.pop(); + this.params = 0; + return 'eth_newBlockFilter'; + case 'pending': + args.pop(); + this.params = 0; + return 'eth_newPendingTransactionFilter'; + default: + return 'eth_newFilter'; + } }; var newFilter = new Method({ @@ -3655,7 +3847,7 @@ module.exports = { }; -},{"./method":21}],28:[function(require,module,exports){ +},{"./method":20}],27:[function(require,module,exports){ },{}],"bignumber.js":[function(require,module,exports){ 'use strict'; @@ -3668,7 +3860,6 @@ var web3 = require('./lib/web3'); web3.providers.HttpProvider = require('./lib/web3/httpprovider'); web3.providers.QtSyncProvider = require('./lib/web3/qtsync'); web3.eth.contract = require('./lib/web3/contract'); -web3.abi = require('./lib/solidity/abi'); // dont override global variable if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { @@ -3678,7 +3869,7 @@ if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { module.exports = web3; -},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]) +},{"./lib/web3":8,"./lib/web3/contract":10,"./lib/web3/httpprovider":18,"./lib/web3/qtsync":23}]},{},["web3"]) //# sourceMappingURL=web3-light.js.map \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/web3-light.js.map b/libjsqrc/ethereumjs/dist/web3-light.js.map index 31e9b5a44..53b78067d 100644 --- a/libjsqrc/ethereumjs/dist/web3-light.js.map +++ b/libjsqrc/ethereumjs/dist/web3-light.js.map @@ -2,16 +2,15 @@ "version": 3, "sources": [ "node_modules/browserify/node_modules/browser-pack/_prelude.js", - "lib/solidity/abi.js", "lib/solidity/coder.js", "lib/solidity/formatters.js", "lib/solidity/param.js", - "lib/solidity/utils.js", "lib/utils/browser-xhr.js", "lib/utils/config.js", "lib/utils/utils.js", "lib/version.json", "lib/web3.js", + "lib/web3/batch.js", "lib/web3/contract.js", "lib/web3/db.js", "lib/web3/errors.js", @@ -34,40 +33,39 @@ "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;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;;ACAA;AACA;AACA;AACA;AACA;;ACJA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClHA;;ACAA;AACA;AACA;AACA;AACA;;ACJA;AACA;AACA;AACA;AACA;AACA;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/** \n * @file abi.js\n * @author Marek Kotewicz \n * @author Gav Wood \n * @date 2014\n */\n\nvar coder = require('./coder');\nvar utils = require('./utils');\n\nvar formatConstructorParams = function (abi, params) {\n var constructor = utils.getConstructor(abi, params.length);\n if (!constructor) {\n if (params.length > 0) {\n console.warn(\"didn't found matching constructor, using default one\");\n }\n return '';\n }\n\n return coder.encodeParams(constructor.inputs.map(function (input) {\n return input.type;\n }), params);\n};\n\nmodule.exports = {\n formatConstructorParams: formatConstructorParams\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/** \n * @file coder.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar f = require('./formatters');\nvar SolidityParam = require('./param');\n\n/**\n * Should be used to check if a type is an array type\n *\n * @method isArrayType\n * @param {String} type\n * @return {Bool} true is the type is an array, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * SolidityType prototype is used to encode/decode solidity params of certain type\n */\nvar SolidityType = function (config) {\n this._name = config.name;\n this._match = config.match;\n this._mode = config.mode;\n this._inputFormatter = config.inputFormatter;\n this._outputFormatter = config.outputFormatter;\n};\n\n/**\n * Should be used to determine if this SolidityType do match given type\n *\n * @method isType\n * @param {String} name\n * @return {Bool} true if type match this SolidityType, otherwise false\n */\nSolidityType.prototype.isType = function (name) {\n if (this._match === 'strict') {\n return this._name === name || (name.indexOf(this._name) === 0 && name.slice(this._name.length) === '[]');\n } else if (this._match === 'prefix') {\n // TODO better type detection!\n return name.indexOf(this._name) === 0;\n }\n};\n\n/**\n * Should be used to transform plain param to SolidityParam object\n *\n * @method formatInput\n * @param {Object} param - plain object, or an array of objects\n * @param {Bool} arrayType - true if a param should be encoded as an array\n * @return {SolidityParam} encoded param wrapped in SolidityParam object \n */\nSolidityType.prototype.formatInput = function (param, arrayType) {\n if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same\n var self = this;\n return param.map(function (p) {\n return self._inputFormatter(p);\n }).reduce(function (acc, current) {\n return acc.combine(current);\n }, f.formatInputInt(param.length)).withOffset(32);\n } \n return this._inputFormatter(param);\n};\n\n/**\n * Should be used to transoform SolidityParam to plain param\n *\n * @method formatOutput\n * @param {SolidityParam} byteArray\n * @param {Bool} arrayType - true if a param should be decoded as an array\n * @return {Object} plain decoded param\n */\nSolidityType.prototype.formatOutput = function (param, arrayType) {\n if (arrayType) {\n // let's assume, that we solidity will never return long arrays :P \n var result = [];\n var length = new BigNumber(param.dynamicPart().slice(0, 64), 16);\n for (var i = 0; i < length * 64; i += 64) {\n result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64))));\n }\n return result;\n }\n return this._outputFormatter(param);\n};\n\n/**\n * Should be used to slice single param from bytes\n *\n * @method sliceParam\n * @param {String} bytes\n * @param {Number} index of param to slice\n * @param {String} type\n * @returns {SolidityParam} param\n */\nSolidityType.prototype.sliceParam = function (bytes, index, type) {\n if (this._mode === 'bytes') {\n return SolidityParam.decodeBytes(bytes, index);\n } else if (isArrayType(type)) {\n return SolidityParam.decodeArray(bytes, index);\n }\n return SolidityParam.decodeParam(bytes, index);\n};\n\n/**\n * SolidityCoder prototype should be used to encode/decode solidity params of any type\n */\nvar SolidityCoder = function (types) {\n this._types = types;\n};\n\n/**\n * This method should be used to transform type to SolidityType\n *\n * @method _requireType\n * @param {String} type\n * @returns {SolidityType} \n * @throws {Error} throws if no matching type is found\n */\nSolidityCoder.prototype._requireType = function (type) {\n var solidityType = this._types.filter(function (t) {\n return t.isType(type);\n })[0];\n\n if (!solidityType) {\n throw Error('invalid solidity type!: ' + type);\n }\n\n return solidityType;\n};\n\n/**\n * Should be used to transform plain param of given type to SolidityParam\n *\n * @method _formatInput\n * @param {String} type of param\n * @param {Object} plain param\n * @return {SolidityParam}\n */\nSolidityCoder.prototype._formatInput = function (type, param) {\n return this._requireType(type).formatInput(param, isArrayType(type));\n};\n\n/**\n * Should be used to encode plain param\n *\n * @method encodeParam\n * @param {String} type\n * @param {Object} plain param\n * @return {String} encoded plain param\n */\nSolidityCoder.prototype.encodeParam = function (type, param) {\n return this._formatInput(type, param).encode();\n};\n\n/**\n * Should be used to encode list of params\n *\n * @method encodeParams\n * @param {Array} types\n * @param {Array} params\n * @return {String} encoded list of params\n */\nSolidityCoder.prototype.encodeParams = function (types, params) {\n var self = this;\n var solidityParams = types.map(function (type, index) {\n return self._formatInput(type, params[index]);\n });\n\n return SolidityParam.encodeList(solidityParams);\n};\n\n/**\n * Should be used to decode bytes to plain param\n *\n * @method decodeParam\n * @param {String} type\n * @param {String} bytes\n * @return {Object} plain param\n */\nSolidityCoder.prototype.decodeParam = function (type, bytes) {\n return this.decodeParams([type], bytes)[0];\n};\n\n/**\n * Should be used to decode list of params\n *\n * @method decodeParam\n * @param {Array} types\n * @param {String} bytes\n * @return {Array} array of plain params\n */\nSolidityCoder.prototype.decodeParams = function (types, bytes) {\n var self = this;\n return types.map(function (type, index) {\n var solidityType = self._requireType(type);\n var p = solidityType.sliceParam(bytes, index, type);\n return solidityType.formatOutput(p, isArrayType(type));\n });\n};\n\nvar coder = new SolidityCoder([\n new SolidityType({\n name: 'address',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputAddress\n }),\n new SolidityType({\n name: 'bool',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputBool,\n outputFormatter: f.formatOutputBool\n }),\n new SolidityType({\n name: 'int',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputInt,\n }),\n new SolidityType({\n name: 'uint',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputUInt\n }),\n new SolidityType({\n name: 'bytes',\n match: 'strict',\n mode: 'bytes',\n inputFormatter: f.formatInputDynamicBytes,\n outputFormatter: f.formatOutputDynamicBytes\n }),\n new SolidityType({\n name: 'bytes',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputBytes,\n outputFormatter: f.formatOutputBytes\n }),\n new SolidityType({\n name: 'real',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputReal\n }),\n new SolidityType({\n name: 'ureal',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputUReal\n })\n]);\n\nmodule.exports = coder;\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/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar SolidityParam = require('./param');\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 {SolidityParam}\n */\nvar formatInputInt = function (value) {\n var padding = c.ETH_PADDING * 2;\n BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);\n var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputDynamicBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputDynamicBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(formatInputInt(value.length).value + result, 32);\n};\n\n/**\n * Formats input value to byte representation of bool\n *\n * @method formatInputBool\n * @param {Boolean}\n * @returns {SolidityParam}\n */\nvar formatInputBool = function (value) {\n var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n return new SolidityParam(result);\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 {SolidityParam}\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 {SolidityParam} param\n * @returns {BigNumber} right-aligned output bytes formatted to big number\n */\nvar formatOutputInt = function (param) {\n var value = param.staticPart() || \"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 {SolidityParam}\n * @returns {BigNumeber} right-aligned output bytes formatted to uint\n */\nvar formatOutputUInt = function (param) {\n var value = param.staticPart() || \"0\";\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to real\n *\n * @method formatOutputReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to real\n */\nvar formatOutputReal = function (param) {\n return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Formats right-aligned output bytes to ureal\n *\n * @method formatOutputUReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to ureal\n */\nvar formatOutputUReal = function (param) {\n return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Should be used to format output bool\n *\n * @method formatOutputBool\n * @param {SolidityParam}\n * @returns {Boolean} right-aligned input bytes formatted to bool\n */\nvar formatOutputBool = function (param) {\n return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.staticPart());\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputDynamicBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputDynamicBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.dynamicPart().slice(64));\n};\n\n/**\n * Should be used to format output address\n *\n * @method formatOutputAddress\n * @param {SolidityParam} right-aligned input bytes\n * @returns {String} address\n */\nvar formatOutputAddress = function (param) {\n var value = param.staticPart();\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nmodule.exports = {\n formatInputInt: formatInputInt,\n formatInputBytes: formatInputBytes,\n formatInputDynamicBytes: formatInputDynamicBytes,\n formatInputBool: formatInputBool,\n formatInputReal: formatInputReal,\n formatOutputInt: formatOutputInt,\n formatOutputUInt: formatOutputUInt,\n formatOutputReal: formatOutputReal,\n formatOutputUReal: formatOutputUReal,\n formatOutputBool: formatOutputBool,\n formatOutputBytes: formatOutputBytes,\n formatOutputDynamicBytes: formatOutputDynamicBytes,\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/** \n * @file param.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * SolidityParam object prototype.\n * Should be used when encoding, decoding solidity bytes\n */\nvar SolidityParam = function (value, offset) {\n this.value = value || '';\n this.offset = offset; // offset in bytes\n};\n\n/**\n * This method should be used to get length of params's dynamic part\n * \n * @method dynamicPartLength\n * @returns {Number} length of dynamic part (in bytes)\n */\nSolidityParam.prototype.dynamicPartLength = function () {\n return this.dynamicPart().length / 2;\n};\n\n/**\n * This method should be used to create copy of solidity param with different offset\n *\n * @method withOffset\n * @param {Number} offset length in bytes\n * @returns {SolidityParam} new solidity param with applied offset\n */\nSolidityParam.prototype.withOffset = function (offset) {\n return new SolidityParam(this.value, offset);\n};\n\n/**\n * This method should be used to combine solidity params together\n * eg. when appending an array\n *\n * @method combine\n * @param {SolidityParam} param with which we should combine\n * @param {SolidityParam} result of combination\n */\nSolidityParam.prototype.combine = function (param) {\n return new SolidityParam(this.value + param.value); \n};\n\n/**\n * This method should be called to check if param has dynamic size.\n * If it has, it returns true, otherwise false\n *\n * @method isDynamic\n * @returns {Boolean}\n */\nSolidityParam.prototype.isDynamic = function () {\n return this.value.length > 64;\n};\n\n/**\n * This method should be called to transform offset to bytes\n *\n * @method offsetAsBytes\n * @returns {String} bytes representation of offset\n */\nSolidityParam.prototype.offsetAsBytes = function () {\n return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);\n};\n\n/**\n * This method should be called to get static part of param\n *\n * @method staticPart\n * @returns {String} offset if it is a dynamic param, otherwise value\n */\nSolidityParam.prototype.staticPart = function () {\n if (!this.isDynamic()) {\n return this.value; \n } \n return this.offsetAsBytes();\n};\n\n/**\n * This method should be called to get dynamic part of param\n *\n * @method dynamicPart\n * @returns {String} returns a value if it is a dynamic param, otherwise empty string\n */\nSolidityParam.prototype.dynamicPart = function () {\n return this.isDynamic() ? this.value : '';\n};\n\n/**\n * This method should be called to encode param\n *\n * @method encode\n * @returns {String}\n */\nSolidityParam.prototype.encode = function () {\n return this.staticPart() + this.dynamicPart();\n};\n\n/**\n * This method should be called to encode array of params\n *\n * @method encodeList\n * @param {Array[SolidityParam]} params\n * @returns {String}\n */\nSolidityParam.encodeList = function (params) {\n \n // updating offsets\n var totalOffset = params.length * 32;\n var offsetParams = params.map(function (param) {\n if (!param.isDynamic()) {\n return param;\n }\n var offset = totalOffset;\n totalOffset += param.dynamicPartLength();\n return param.withOffset(offset);\n });\n\n // encode everything!\n return offsetParams.reduce(function (result, param) {\n return result + param.dynamicPart();\n }, offsetParams.reduce(function (result, param) {\n return result + param.staticPart();\n }, ''));\n};\n\n/**\n * This method should be used to decode plain (static) solidity param at given index\n *\n * @method decodeParam\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeParam = function (bytes, index) {\n index = index || 0;\n return new SolidityParam(bytes.substr(index * 64, 64)); \n};\n\n/**\n * This method should be called to get offset value from bytes at given index\n *\n * @method getOffset\n * @param {String} bytes\n * @param {Number} index\n * @returns {Number} offset as number\n */\nvar getOffset = function (bytes, index) {\n // we can do this cause offset is rather small\n return parseInt('0x' + bytes.substr(index * 64, 64));\n};\n\n/**\n * This method should be called to decode solidity bytes param at given index\n *\n * @method decodeBytes\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeBytes = function (bytes, index) {\n index = index || 0;\n //TODO add support for strings longer than 32 bytes\n //var length = parseInt('0x' + bytes.substr(offset * 64, 64));\n\n var offset = getOffset(bytes, index);\n\n // 2 * , cause we also parse length\n return new SolidityParam(bytes.substr(offset * 2, 2 * 64));\n};\n\n/**\n * This method should be used to decode solidity array at given index\n *\n * @method decodeArray\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeArray = function (bytes, index) {\n index = index || 0;\n var offset = getOffset(bytes, index);\n var length = parseInt('0x' + bytes.substr(offset * 2, 64));\n return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64));\n};\n\nmodule.exports = SolidityParam;\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/**\n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Returns the contstructor with matching number of arguments\n *\n * @method getConstructor\n * @param {Array} abi\n * @param {Number} numberOfArgs\n * @returns {Object} constructor function abi\n */\nvar getConstructor = function (abi, numberOfArgs) {\n return abi.filter(function (f) {\n return f.type === 'constructor' && f.inputs.length === numberOfArgs;\n })[0];\n};\n\n//var getSupremeType = function (type) {\n //return type.substr(0, type.indexOf('[')) + ']';\n//};\n\n\nmodule.exports = {\n getConstructor: getConstructor\n};\n\n", "'use strict';\n\n// go env doesn't have and need XMLHttpRequest\nif (typeof XMLHttpRequest === 'undefined') {\n exports.XMLHttpRequest = {};\n} else {\n exports.XMLHttpRequest = XMLHttpRequest; // jshint ignore:line\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\nvar BigNumber = require('bignumber.js');\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 defaultBlock: 'latest',\n defaultAccount: undefined\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/** \n * @file utils.js\n * @author 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\nvar BigNumber = require('bignumber.js');\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 * 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 * 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 toHexNative\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 used to create full function/event name from json abi\n *\n * @method transformToFullName\n * @param {Object} json-abi\n * @return {String} full fnction/event name\n */\nvar transformToFullName = function (json) {\n if (json.name.indexOf('(') !== -1) {\n return json.name;\n }\n\n var typeName = json.inputs.map(function(i){return i.type; }).join();\n return json.name + '(' + typeName + ')';\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 * 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 fromDecimal(+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 is strictly an address\n *\n * @method isStrictAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isStrictAddress = function (address) {\n return /^0x[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Checks if the given string is an address\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function (address) {\n return /^(0x)?[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Transforms given string to valid 20 bytes-length addres with 0x prefix\n *\n * @method toAddress\n * @param {String} address\n * @return {String} formatted address\n */\nvar toAddress = function (address) {\n if (isStrictAddress(address)) {\n return address;\n }\n \n if (/^[0-9a-f]{40}$/.test(address)) {\n return '0x' + address;\n }\n\n return '0x' + padLeft(toHex(address).substr(2), 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\n/**\n * Returns true if given string is valid json object\n * \n * @method isJson\n * @param {String}\n * @return {Boolean}\n */\nvar isJson = function (str) {\n try {\n return !!JSON.parse(str);\n } catch (e) {\n return false;\n }\n};\n\nmodule.exports = {\n padLeft: padLeft,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n transformToFullName: transformToFullName,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n toAddress: toAddress,\n isBigNumber: isBigNumber,\n isStrictAddress: isStrictAddress,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray,\n isJson: isJson\n};\n\n", - "module.exports={\n \"version\": \"0.3.6\"\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('./web3/formatters');\nvar RequestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\nvar Method = require('./web3/method');\nvar Property = require('./web3/property');\n\nvar web3Methods = [\n new Method({\n name: 'sha3',\n call: 'web3_sha3',\n params: 1\n })\n];\n\nvar web3Properties = [\n new Property({\n name: 'version.client',\n getter: 'web3_clientVersion'\n }),\n new Property({\n name: 'version.network',\n getter: 'net_version',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.ethereum',\n getter: 'eth_protocolVersion',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.whisper',\n getter: 'shh_version',\n inputFormatter: utils.toDecimal\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 method.attachToObject(obj);\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 property.attachToObject(obj);\n });\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {};\nweb3.providers = {};\nweb3.version = {};\nweb3.version.api = version.version;\nweb3.eth = {};\n\n/*jshint maxparams:4 */\nweb3.eth.filter = function (fil, eventParams, options, formatter) {\n\n // if its event, treat it differently\n // TODO: simplify and remove\n if (fil._isEvent) {\n return fil(eventParams, options);\n }\n\n // what outputLogFormatter? that's wrong\n //return new Filter(fil, watches.eth(), formatters.outputLogFormatter);\n return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter);\n};\n/*jshint maxparams:3 */\n\nweb3.shh = {};\nweb3.shh.filter = function (fil) {\n return new Filter(fil, watches.shh(), formatters.outputPostFormatter);\n};\nweb3.net = {};\nweb3.db = {};\nweb3.setProvider = function (provider) {\n RequestManager.getInstance().setProvider(provider);\n};\nweb3.reset = function () {\n RequestManager.getInstance().reset();\n c.defaultBlock = 'latest';\n c.defaultAccount = undefined;\n};\nweb3.toHex = utils.toHex;\nweb3.toAscii = utils.toAscii;\nweb3.fromAscii = utils.fromAscii;\nweb3.toDecimal = utils.toDecimal;\nweb3.fromDecimal = utils.fromDecimal;\nweb3.toBigNumber = utils.toBigNumber;\nweb3.toWei = utils.toWei;\nweb3.fromWei = utils.fromWei;\nweb3.isAddress = utils.isAddress;\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.defaultBlock;\n },\n set: function (val) {\n c.defaultBlock = val;\n return val;\n }\n});\n\nObject.defineProperty(web3.eth, 'defaultAccount', {\n get: function () {\n return c.defaultAccount;\n },\n set: function (val) {\n c.defaultAccount = val;\n return val;\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);\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/** \n * @file contract.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar solAbi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar SolidityEvent = require('./event');\nvar SolidityFunction = require('./function');\n\nvar addFunctionsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'function';\n }).map(function (json) {\n return new SolidityFunction(json, contract.address);\n }).forEach(function (f) {\n f.attachToContract(contract);\n });\n};\n\nvar addEventsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'event';\n }).map(function (json) {\n return new SolidityEvent(json, contract.address);\n }).forEach(function (e) {\n e.attachToContract(contract);\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 return Contract.bind(null, abi);\n};\n\nvar Contract = function (abi, options) {\n\n this.address = '';\n if (utils.isAddress(options)) {\n this.address = options;\n } else { // is an object!\n // TODO, parse the rest of the args\n options = options || {};\n var args = Array.prototype.slice.call(arguments, 2);\n var bytes = solAbi.formatConstructorParams(abi, args);\n options.data += bytes;\n this.address = web3.eth.sendTransaction(options);\n }\n\n addFunctionsToContract(this, abi);\n addEventsToContract(this, abi);\n};\n\nContract.prototype.call = function () {\n console.error('contract.call is deprecated');\n return this;\n};\n\nContract.prototype.sendTransaction = function () {\n console.error('contract.sendTransact is deprecated');\n return this;\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/** \n * @file utils.js\n * @author 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\nvar BigNumber = require('bignumber.js');\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 * 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 * 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 toHexNative\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 used to create full function/event name from json abi\n *\n * @method transformToFullName\n * @param {Object} json-abi\n * @return {String} full fnction/event name\n */\nvar transformToFullName = function (json) {\n if (json.name.indexOf('(') !== -1) {\n return json.name;\n }\n\n var typeName = json.inputs.map(function(i){return i.type; }).join();\n return json.name + '(' + typeName + ')';\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 * 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 fromDecimal(+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 is strictly an address\n *\n * @method isStrictAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isStrictAddress = function (address) {\n return /^0x[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Checks if the given string is an address\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function (address) {\n return /^(0x)?[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Transforms given string to valid 20 bytes-length addres with 0x prefix\n *\n * @method toAddress\n * @param {String} address\n * @return {String} formatted address\n */\nvar toAddress = function (address) {\n if (isStrictAddress(address)) {\n return address;\n }\n \n if (/^[0-9a-f]{40}$/.test(address)) {\n return '0x' + address;\n }\n\n return '0x' + padLeft(toHex(address).substr(2), 40);\n};\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\n/**\n * Returns true if given string is valid json object\n * \n * @method isJson\n * @param {String}\n * @return {Boolean}\n */\nvar isJson = function (str) {\n try {\n return !!JSON.parse(str);\n } catch (e) {\n return false;\n }\n};\n\nmodule.exports = {\n padLeft: padLeft,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n transformToFullName: transformToFullName,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n toAddress: toAddress,\n isBigNumber: isBigNumber,\n isStrictAddress: isStrictAddress,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray,\n isJson: isJson\n};\n\n", + "module.exports={\n \"version\": \"0.4.2\"\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('./web3/formatters');\nvar RequestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\nvar Method = require('./web3/method');\nvar Property = require('./web3/property');\nvar Batch = require('./web3/batch');\n\nvar web3Methods = [\n new Method({\n name: 'sha3',\n call: 'web3_sha3',\n params: 1\n })\n];\n\nvar web3Properties = [\n new Property({\n name: 'version.client',\n getter: 'web3_clientVersion'\n }),\n new Property({\n name: 'version.network',\n getter: 'net_version',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.ethereum',\n getter: 'eth_protocolVersion',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.whisper',\n getter: 'shh_version',\n inputFormatter: utils.toDecimal\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 method.attachToObject(obj);\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 property.attachToObject(obj);\n });\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {};\nweb3.providers = {};\nweb3.version = {};\nweb3.version.api = version.version;\nweb3.eth = {};\n\n/*jshint maxparams:4 */\nweb3.eth.filter = function (fil, eventParams, options, formatter) {\n\n // if its event, treat it differently\n // TODO: simplify and remove\n if (fil._isEvent) {\n return fil(eventParams, options);\n }\n\n // what outputLogFormatter? that's wrong\n //return new Filter(fil, watches.eth(), formatters.outputLogFormatter);\n return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter);\n};\n/*jshint maxparams:3 */\n\nweb3.shh = {};\nweb3.shh.filter = function (fil) {\n return new Filter(fil, watches.shh(), formatters.outputPostFormatter);\n};\nweb3.net = {};\nweb3.db = {};\nweb3.setProvider = function (provider) {\n RequestManager.getInstance().setProvider(provider);\n};\nweb3.reset = function () {\n RequestManager.getInstance().reset();\n c.defaultBlock = 'latest';\n c.defaultAccount = undefined;\n};\nweb3.toHex = utils.toHex;\nweb3.toAscii = utils.toAscii;\nweb3.fromAscii = utils.fromAscii;\nweb3.toDecimal = utils.toDecimal;\nweb3.fromDecimal = utils.fromDecimal;\nweb3.toBigNumber = utils.toBigNumber;\nweb3.toWei = utils.toWei;\nweb3.fromWei = utils.fromWei;\nweb3.isAddress = utils.isAddress;\nweb3.createBatch = function () {\n return new Batch();\n};\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.defaultBlock;\n },\n set: function (val) {\n c.defaultBlock = val;\n return val;\n }\n});\n\nObject.defineProperty(web3.eth, 'defaultAccount', {\n get: function () {\n return c.defaultAccount;\n },\n set: function (val) {\n c.defaultAccount = val;\n return val;\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);\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/** \n * @file batch.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\n\nvar Batch = function () {\n this.requests = [];\n};\n\n/**\n * Should be called to add create new request to batch request\n *\n * @method add\n * @param {Object} jsonrpc requet object\n */\nBatch.prototype.add = function (request) {\n this.requests.push(request);\n};\n\n/**\n * Should be called to execute batch request\n *\n * @method execute\n */\nBatch.prototype.execute = function () {\n var requests = this.requests;\n RequestManager.getInstance().sendBatch(requests, function (err, results) {\n results = results || [];\n requests.map(function (request, index) {\n return results[index] || {};\n }).map(function (result, index) {\n return requests[index].format ? requests[index].format(result.result) : result.result;\n }).forEach(function (result, index) {\n if (requests[index].callback) {\n requests[index].callback(err, result);\n }\n });\n }); \n};\n\nmodule.exports = Batch;\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/** \n * @file contract.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar SolidityEvent = require('./event');\nvar SolidityFunction = require('./function');\n\n/**\n * Should be called to encode constructor params\n *\n * @method encodeConstructorParams\n * @param {Array} abi\n * @param {Array} constructor params\n */\nvar encodeConstructorParams = function (abi, params) {\n return abi.filter(function (json) {\n return json.type === 'constructor' && json.inputs.length === params.length;\n }).map(function (json) {\n return json.inputs.map(function (input) {\n return input.type;\n });\n }).map(function (types) {\n return coder.encodeParams(types, params);\n })[0] || '';\n};\n\n/**\n * Should be called to add functions to contract object\n *\n * @method addFunctionsToContract\n * @param {Contract} contract\n * @param {Array} abi\n */\nvar addFunctionsToContract = function (contract, abi) {\n abi.filter(function (json) {\n return json.type === 'function';\n }).map(function (json) {\n return new SolidityFunction(json, contract.address);\n }).forEach(function (f) {\n f.attachToContract(contract);\n });\n};\n\n/**\n * Should be called to add events to contract object\n *\n * @method addEventsToContract\n * @param {Contract} contract\n * @param {Array} abi\n */\nvar addEventsToContract = function (contract, abi) {\n abi.filter(function (json) {\n return json.type === 'event';\n }).map(function (json) {\n return new SolidityEvent(json, contract.address);\n }).forEach(function (e) {\n e.attachToContract(contract);\n });\n};\n\n/**\n * Should be called to create new ContractFactory\n *\n * @method contract\n * @param {Array} abi\n * @returns {ContractFactory} new contract factory\n */\nvar contract = function (abi) {\n return new ContractFactory(abi);\n};\n\n/**\n * Should be called to create new ContractFactory instance\n *\n * @method ContractFactory\n * @param {Array} abi\n */\nvar ContractFactory = function (abi) {\n this.abi = abi;\n};\n\n/**\n * Should be called to create new contract on a blockchain\n * \n * @method new\n * @param {Any} contract constructor param1 (optional)\n * @param {Any} contract constructor param2 (optional)\n * @param {Object} contract transaction object (required)\n * @param {Function} callback\n * @returns {Contract} returns contract if no callback was passed,\n * otherwise calls callback function (err, contract)\n */\nContractFactory.prototype.new = function () {\n // parse arguments\n var options = {}; // required!\n var callback;\n\n var args = Array.prototype.slice.call(arguments);\n if (utils.isFunction(args[args.length - 1])) {\n callback = args.pop();\n }\n\n var last = args[args.length - 1];\n if (utils.isObject(last) && !utils.isArray(last)) {\n options = args.pop();\n }\n\n // throw an error if there are no options\n\n var bytes = encodeConstructorParams(this.abi, args);\n options.data += bytes;\n\n if (!callback) {\n var address = web3.eth.sendTransaction(options);\n return this.at(address);\n }\n \n var self = this;\n web3.eth.sendTransaction(options, function (err, address) {\n if (err) {\n callback(err);\n }\n self.at(address, callback); \n }); \n};\n\n/**\n * Should be called to get access to existing contract on a blockchain\n *\n * @method at\n * @param {Address} contract address (required)\n * @param {Function} callback {optional)\n * @returns {Contract} returns contract if no callback was passed,\n * otherwise calls callback function (err, contract)\n */\nContractFactory.prototype.at = function (address, callback) {\n // TODO: address is required\n \n if (callback) {\n callback(null, new Contract(this.abi, address));\n } \n return new Contract(this.abi, address);\n};\n\n/**\n * Should be called to create new contract instance\n *\n * @method Contract\n * @param {Array} abi\n * @param {Address} contract address\n */\nvar Contract = function (abi, address) {\n this.address = address;\n addFunctionsToContract(this, abi);\n addEventsToContract(this, abi);\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\nvar Method = require('./method');\n\nvar putString = new Method({\n name: 'putString',\n call: 'db_putString',\n params: 3\n});\n\n\nvar getString = new Method({\n name: 'getString',\n call: 'db_getString',\n params: 2\n});\n\nvar putHex = new Method({\n name: 'putHex',\n call: 'db_putHex',\n params: 3\n});\n\nvar getHex = new Method({\n name: 'getHex',\n call: 'db_getHex',\n params: 2\n});\n\nvar methods = [\n putString, getString, putHex, getHex\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/** \n * @file errors.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nmodule.exports = {\n InvalidNumberOfParams: function () {\n return new Error('Invalid number of input parameters');\n },\n InvalidConnection: function (host){\n return new Error('CONNECTION ERROR: Couldn\\'t connect to node '+ host +', is it running?');\n },\n InvalidProvider: function () {\n return new Error('Providor not set or invalid');\n },\n InvalidResponse: function (result){\n var message = !!result && !!result.error && !!result.error.message ? result.error.message : 'Invalid JSON RPC response';\n return new Error(message);\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/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author 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 * params: 2,\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){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\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\n\nvar getBalance = new Method({\n name: 'getBalance',\n call: 'eth_getBalance',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt',\n call: 'eth_getStorageAt',\n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock',\n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'hashrate',\n getter: 'eth_hashrate',\n outputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n 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/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author 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 * params: 2,\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){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\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\n\nvar getBalance = new Method({\n name: 'getBalance',\n call: 'eth_getBalance',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt',\n call: 'eth_getStorageAt',\n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock',\n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar estimateGas = new Method({\n name: 'estimateGas',\n call: 'eth_estimateGas',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar submitWork = new Method({\n name: 'submitWork',\n call: 'eth_submitWork',\n params: 3\n});\n\nvar getWork = new Method({\n name: 'getWork',\n call: 'eth_getWork',\n params: 0\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n estimateGas,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n submitWork,\n getWork\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'hashrate',\n getter: 'eth_hashrate',\n outputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n 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/** \n * @file event.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar web3 = require('../web3');\nvar formatters = require('./formatters');\n\n/**\n * This prototype should be used to create event filters\n */\nvar SolidityEvent = function (json, address) {\n this._params = json.inputs;\n this._name = utils.transformToFullName(json);\n this._address = address;\n this._anonymous = json.anonymous;\n};\n\n/**\n * Should be used to get filtered param types\n *\n * @method types\n * @param {Bool} decide if returned typed should be indexed\n * @return {Array} array of types\n */\nSolidityEvent.prototype.types = function (indexed) {\n return this._params.filter(function (i) {\n return i.indexed === indexed;\n }).map(function (i) {\n return i.type;\n });\n};\n\n/**\n * Should be used to get event display name\n *\n * @method displayName\n * @return {String} event display name\n */\nSolidityEvent.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get event type name\n *\n * @method typeName\n * @return {String} event type name\n */\nSolidityEvent.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be used to get event signature\n *\n * @method signature\n * @return {String} event signature\n */\nSolidityEvent.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2);\n};\n\n/**\n * Should be used to encode indexed params and options to one final object\n * \n * @method encode\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} everything combined together and encoded\n */\nSolidityEvent.prototype.encode = function (indexed, options) {\n indexed = indexed || {};\n options = options || {};\n var result = {};\n\n ['fromBlock', 'toBlock'].filter(function (f) {\n return options[f] !== undefined;\n }).forEach(function (f) {\n result[f] = formatters.inputBlockNumberFormatter(options[f]);\n });\n\n result.topics = [];\n\n if (!this._anonymous) {\n result.address = this._address;\n result.topics.push('0x' + this.signature());\n }\n\n var indexedTopics = this._params.filter(function (i) {\n return i.indexed === true;\n }).map(function (i) {\n var value = indexed[i.name];\n if (value === undefined || value === null) {\n return null;\n }\n \n if (utils.isArray(value)) {\n return value.map(function (v) {\n return '0x' + coder.encodeParam(i.type, v);\n });\n }\n return '0x' + coder.encodeParam(i.type, value);\n });\n\n result.topics = result.topics.concat(indexedTopics);\n\n return result;\n};\n\n/**\n * Should be used to decode indexed params and options\n *\n * @method decode\n * @param {Object} data\n * @return {Object} result object with decoded indexed && not indexed params\n */\nSolidityEvent.prototype.decode = function (data) {\n \n data.data = data.data || '';\n data.topics = data.topics || [];\n\n var argTopics = this._anonymous ? data.topics : data.topics.slice(1);\n var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedParams = coder.decodeParams(this.types(true), indexedData); \n\n var notIndexedData = data.data.slice(2);\n var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);\n \n var result = formatters.outputLogFormatter(data);\n result.event = this.displayName();\n result.address = data.address;\n\n result.args = this._params.reduce(function (acc, current) {\n acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();\n return acc;\n }, {});\n\n delete result.data;\n delete result.topics;\n\n return result;\n};\n\n/**\n * Should be used to create new filter object from event\n *\n * @method execute\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} filter object\n */\nSolidityEvent.prototype.execute = function (indexed, options) {\n var o = this.encode(indexed, options);\n var formatter = this.decode.bind(this);\n return web3.eth.filter(o, undefined, undefined, formatter);\n};\n\n/**\n * Should be used to attach event to contract object\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityEvent.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = this.execute.bind(this, contract);\n};\n\nmodule.exports = SolidityEvent;\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 RequestManager = require('./requestmanager');\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n/**\n* Converts a given topic to a hex string, but also allows null values.\n*\n* @param {Mixed} value\n* @return {String}\n*/\nvar toTopic = function(value){\n\n if(value === null || typeof value === 'undefined')\n return null;\n\n value = String(value);\n\n if(value.indexOf('0x') === 0)\n return value;\n else\n return utils.fromAscii(value);\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\n if (utils.isString(options)) {\n return options;\n } \n\n options = options || {};\n\n // make sure topics, get converted to hex\n options.topics = options.topics || [];\n options.topics = options.topics.map(function(topic){\n return (utils.isArray(topic)) ? topic.map(toTopic) : toTopic(topic);\n });\n\n // lazy load\n return {\n topics: options.topics,\n to: options.to,\n address: options.address,\n fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock),\n toBlock: formatters.inputBlockNumberFormatter(options.toBlock) \n }; \n};\n\nvar Filter = function (options, methods, formatter) {\n var implementation = {};\n methods.forEach(function (method) {\n method.attachToObject(implementation);\n });\n this.options = getOptions(options);\n this.implementation = implementation;\n this.callbacks = [];\n this.formatter = formatter;\n this.filterId = this.implementation.newFilter(this.options);\n};\n\nFilter.prototype.watch = function (callback) {\n this.callbacks.push(callback);\n var self = this;\n\n var onMessage = function (error, messages) {\n if (error) {\n return self.callbacks.forEach(function (callback) {\n callback(error);\n });\n }\n\n messages.forEach(function (message) {\n message = self.formatter ? self.formatter(message) : message;\n self.callbacks.forEach(function (callback) {\n callback(null, message);\n });\n });\n };\n\n // call getFilterLogs on start\n if (!utils.isString(this.options)) {\n this.get(function (err, messages) {\n // don't send all the responses to all the watches again... just to this one\n if (err) {\n callback(err);\n }\n\n messages.forEach(function (message) {\n callback(null, message);\n });\n });\n }\n\n RequestManager.getInstance().startPolling({\n method: this.implementation.poll.call,\n params: [this.filterId],\n }, this.filterId, onMessage, this.stopWatching.bind(this));\n};\n\nFilter.prototype.stopWatching = function () {\n RequestManager.getInstance().stopPolling(this.filterId);\n this.implementation.uninstallFilter(this.filterId);\n this.callbacks = [];\n};\n\nFilter.prototype.get = function (callback) {\n var self = this;\n if (utils.isFunction(callback)) {\n this.implementation.getLogs(this.filterId, function(err, res){\n if (err) {\n callback(err);\n } else {\n callback(null, res.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\n }));\n }\n });\n } else {\n var logs = this.implementation.getLogs(this.filterId);\n return logs.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\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/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar config = require('../utils/config');\n\n/**\n * Should the format output to a big number\n *\n * @method outputBigNumberFormatter\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar outputBigNumberFormatter = function (number) {\n return utils.toBigNumber(number);\n};\n\nvar isPredefinedBlockNumber = function (blockNumber) {\n return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest';\n};\n\nvar inputDefaultBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return config.defaultBlock;\n }\n return inputBlockNumberFormatter(blockNumber);\n};\n\nvar inputBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return undefined;\n } else if (isPredefinedBlockNumber(blockNumber)) {\n return blockNumber;\n }\n return utils.toHex(blockNumber);\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 options.from = options.from || config.defaultAccount;\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {\n return options[key] !== undefined;\n }).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.blockNumber = utils.toDecimal(tx.blockNumber);\n tx.transactionIndex = utils.toDecimal(tx.transactionIndex);\n tx.nonce = utils.toDecimal(tx.nonce);\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 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.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if (utils.isArray(block.transactions)) {\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 if (log === null) { // 'pending' && 'latest' filters are nulls\n return null;\n }\n\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 * 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.workToProve = utils.fromDecimal(post.workToProve);\n post.priority = utils.fromDecimal(post.priority);\n\n // fallback\n if (!utils.isArray(post.topics)) {\n post.topics = 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 (utils.isJson(post.payload)) {\n post.payload = JSON.parse(post.payload);\n }\n\n // format the following options\n if (!post.topics) {\n post.topics = [];\n }\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,\n inputBlockNumberFormatter: inputBlockNumberFormatter,\n inputTransactionFormatter: inputTransactionFormatter,\n inputPostFormatter: inputPostFormatter,\n outputBigNumberFormatter: outputBigNumberFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\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/** \n * @file function.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar web3 = require('../web3');\nvar coder = require('../solidity/coder');\nvar utils = require('../utils/utils');\n\n/**\n * This prototype should be used to call/sendTransaction to solidity functions\n */\nvar SolidityFunction = function (json, address) {\n this._inputTypes = json.inputs.map(function (i) {\n return i.type;\n });\n this._outputTypes = json.outputs.map(function (i) {\n return i.type;\n });\n this._constant = json.constant;\n this._name = utils.transformToFullName(json);\n this._address = address;\n};\n\n/**\n * Should be used to create payload from arguments\n *\n * @method toPayload\n * @param {...} solidity function params\n * @param {Object} optional payload options\n */\nSolidityFunction.prototype.toPayload = function () {\n var args = Array.prototype.slice.call(arguments);\n var options = {};\n if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) {\n options = args.pop();\n }\n options.to = this._address;\n options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);\n return options;\n};\n\n/**\n * Should be used to get function signature\n *\n * @method signature\n * @return {String} function signature\n */\nSolidityFunction.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2, 10);\n};\n\n/**\n * Should be used to call function\n * \n * @method call\n * @param {Object} options\n * @return {String} output bytes\n */\nSolidityFunction.prototype.call = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n var output = web3.eth.call(payload);\n output = output.length >= 2 ? output.slice(2) : output;\n var result = coder.decodeParams(this._outputTypes, output);\n return result.length === 1 ? result[0] : result;\n};\n\n/**\n * Should be used to sendTransaction to solidity function\n *\n * @method sendTransaction\n * @param {Object} options\n */\nSolidityFunction.prototype.sendTransaction = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n web3.eth.sendTransaction(payload);\n};\n\n/**\n * Should be used to get function display name\n *\n * @method displayName\n * @return {String} display name of the function\n */\nSolidityFunction.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get function type name\n * \n * @method typeName\n * @return {String} type name of the function\n */\nSolidityFunction.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be called to execute function\n *\n * @method execute\n */\nSolidityFunction.prototype.execute = function () {\n var transaction = !this._constant;\n \n // send transaction\n if (transaction) {\n return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments));\n }\n\n // call\n return this.call.apply(this, Array.prototype.slice.call(arguments));\n};\n\n/**\n * Should be called to attach function to contract\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityFunction.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n execute.call = this.call.bind(this);\n execute.sendTransaction = this.sendTransaction.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = execute; // circular!!!!\n};\n\nmodule.exports = SolidityFunction;\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/**\n * @file function.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar web3 = require('../web3');\nvar coder = require('../solidity/coder');\nvar utils = require('../utils/utils');\n\n/**\n * This prototype should be used to call/sendTransaction to solidity functions\n */\nvar SolidityFunction = function (json, address) {\n this._inputTypes = json.inputs.map(function (i) {\n return i.type;\n });\n this._outputTypes = json.outputs.map(function (i) {\n return i.type;\n });\n this._constant = json.constant;\n this._name = utils.transformToFullName(json);\n this._address = address;\n};\n\nSolidityFunction.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n};\n\n/**\n * Should be used to create payload from arguments\n *\n * @method toPayload\n * @param {Array} solidity function params\n * @param {Object} optional payload options\n */\nSolidityFunction.prototype.toPayload = function (args) {\n var options = {};\n if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) {\n options = args[args.length - 1];\n }\n options.to = this._address;\n options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);\n return options;\n};\n\n/**\n * Should be used to get function signature\n *\n * @method signature\n * @return {String} function signature\n */\nSolidityFunction.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2, 10);\n};\n\n\nSolidityFunction.prototype.unpackOutput = function (output) {\n if (output === null) {\n return;\n }\n\n output = output.length >= 2 ? output.slice(2) : output;\n var result = coder.decodeParams(this._outputTypes, output);\n return result.length === 1 ? result[0] : result;\n};\n\n/**\n * Calls a contract function.\n *\n * @method call\n * @param {...Object} Contract function arguments\n * @param {function} If the last argument is a function, the contract function\n * call will be asynchronous, and the callback will be passed the\n * error and result.\n * @return {String} output bytes\n */\nSolidityFunction.prototype.call = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n\n if (!callback) {\n var output = web3.eth.call(payload);\n return this.unpackOutput(output);\n } \n \n var self = this;\n web3.eth.call(payload, function (error, output) {\n callback(error, self.unpackOutput(output));\n });\n};\n\n/**\n * Should be used to sendTransaction to solidity function\n *\n * @method sendTransaction\n * @param {Object} options\n */\nSolidityFunction.prototype.sendTransaction = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n\n if (!callback) {\n web3.eth.sendTransaction(payload);\n return;\n }\n\n web3.eth.sendTransaction(payload, callback);\n};\n\n/**\n * Should be used to get function display name\n *\n * @method displayName\n * @return {String} display name of the function\n */\nSolidityFunction.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get function type name\n *\n * @method typeName\n * @return {String} type name of the function\n */\nSolidityFunction.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be called to get rpc requests from solidity function\n *\n * @method request\n * @returns {Object}\n */\nSolidityFunction.prototype.request = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n var format = this.unpackOutput.bind(this);\n \n return {\n callback: callback,\n payload: payload, \n format: format\n };\n};\n\n/**\n * Should be called to execute function\n *\n * @method execute\n */\nSolidityFunction.prototype.execute = function () {\n var transaction = !this._constant;\n\n // send transaction\n if (transaction) {\n return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments));\n }\n\n // call\n return this.call.apply(this, Array.prototype.slice.call(arguments));\n};\n\n/**\n * Should be called to attach function to contract\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityFunction.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n execute.request = this.request.bind(this);\n execute.call = this.call.bind(this);\n execute.sendTransaction = this.sendTransaction.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = execute; // circular!!!!\n};\n\nmodule.exports = SolidityFunction;\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\n\"use strict\";\n\nvar XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\nvar errors = require('./errors');\n\nvar HttpProvider = function (host) {\n this.host = host || 'http://localhost:8545';\n};\n\nHttpProvider.prototype.send = function (payload) {\n var request = new XMLHttpRequest();\n\n request.open('POST', this.host, false);\n \n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n throw errors.InvalidConnection(this.host);\n }\n\n\n // check request.status\n // TODO: throw an error here! it cannot silently fail!!!\n //if (request.status !== 200) {\n //return;\n //}\n\n var result = request.responseText;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n throw errors.InvalidResponse(result); \n }\n\n return result;\n};\n\nHttpProvider.prototype.sendAsync = function (payload, callback) {\n var request = new XMLHttpRequest();\n request.onreadystatechange = function() {\n if (request.readyState === 4) {\n var result = request.responseText;\n var error = null;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n error = errors.InvalidResponse(result); \n }\n\n callback(error, result);\n }\n };\n\n request.open('POST', this.host, true);\n\n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n callback(errors.InvalidConnection(this.host));\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 Jsonrpc = function () {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.messageId = 1;\n};\n\n/**\n * @return {Jsonrpc} singleton\n */\nJsonrpc.getInstance = function () {\n var instance = new Jsonrpc();\n return instance;\n};\n\n/**\n * Should be called to valid json create payload object\n *\n * @method toPayload\n * @param {Function} method of jsonrpc call, required\n * @param {Array} params, an array of method params, optional\n * @returns {Object} valid jsonrpc payload object\n */\nJsonrpc.prototype.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: this.messageId++\n };\n};\n\n/**\n * Should be called to check if jsonrpc response is valid\n *\n * @method isValidResponse\n * @param {Object}\n * @returns {Boolean} true if response is valid, otherwise false\n */\nJsonrpc.prototype.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/**\n * Should be called to create batch payload object\n *\n * @method toBatchPayload\n * @param {Array} messages, an array of objects with method (required) and params (optional) fields\n * @returns {Array} batch payload\n */\nJsonrpc.prototype.toBatchPayload = function (messages) {\n var self = this;\n return messages.map(function (message) {\n return self.toPayload(message.method, message.params);\n });\n};\n\nmodule.exports = Jsonrpc;\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/**\n * @file method.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\nvar utils = require('../utils/utils');\nvar errors = require('./errors');\n\nvar Method = function (options) {\n this.name = options.name;\n this.call = options.call;\n this.params = options.params || 0;\n this.inputFormatter = options.inputFormatter;\n this.outputFormatter = options.outputFormatter;\n};\n\n/**\n * Should be used to determine name of the jsonrpc method based on arguments\n *\n * @method getCall\n * @param {Array} arguments\n * @return {String} name of jsonrpc method\n */\nMethod.prototype.getCall = function (args) {\n return utils.isFunction(this.call) ? this.call(args) : this.call;\n};\n\n/**\n * Should be used to extract callback from array of arguments. Modifies input param\n *\n * @method extractCallback\n * @param {Array} arguments\n * @return {Function|Null} callback, if exists\n */\nMethod.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n return null;\n};\n\n/**\n * Should be called to check if the number of arguments is correct\n * \n * @method validateArgs\n * @param {Array} arguments\n * @throws {Error} if it is not\n */\nMethod.prototype.validateArgs = function (args) {\n if (args.length !== this.params) {\n throw errors.InvalidNumberOfParams();\n }\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nMethod.prototype.formatInput = function (args) {\n if (!this.inputFormatter) {\n return args;\n }\n\n return this.inputFormatter.map(function (formatter, index) {\n return formatter ? formatter(args[index]) : args[index];\n });\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nMethod.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nMethod.prototype.attachToObject = function (obj) {\n var func = this.send.bind(this);\n func.call = this.call; // that's ugly. filter.js uses it\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n obj[name[0]][name[1]] = func;\n } else {\n obj[name[0]] = func; \n }\n};\n\n/**\n * Should create payload from given input args\n *\n * @method toPayload\n * @param {Array} args\n * @return {Object}\n */\nMethod.prototype.toPayload = function (args) {\n var call = this.getCall(args);\n var callback = this.extractCallback(args);\n var params = this.formatInput(args);\n this.validateArgs(params);\n\n return {\n method: call,\n params: params,\n callback: callback\n };\n};\n\n/**\n * Should send request to the API\n *\n * @method send\n * @param list of params\n * @return result\n */\nMethod.prototype.send = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n if (payload.callback) {\n var self = this;\n return RequestManager.getInstance().sendAsync(payload, function (err, result) {\n payload.callback(null, self.formatOutput(result));\n });\n }\n return this.formatOutput(RequestManager.getInstance().send(payload));\n};\n\nmodule.exports = Method;\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/**\n * @file method.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\nvar utils = require('../utils/utils');\nvar errors = require('./errors');\n\nvar Method = function (options) {\n this.name = options.name;\n this.call = options.call;\n this.params = options.params || 0;\n this.inputFormatter = options.inputFormatter;\n this.outputFormatter = options.outputFormatter;\n};\n\n/**\n * Should be used to determine name of the jsonrpc method based on arguments\n *\n * @method getCall\n * @param {Array} arguments\n * @return {String} name of jsonrpc method\n */\nMethod.prototype.getCall = function (args) {\n return utils.isFunction(this.call) ? this.call(args) : this.call;\n};\n\n/**\n * Should be used to extract callback from array of arguments. Modifies input param\n *\n * @method extractCallback\n * @param {Array} arguments\n * @return {Function|Null} callback, if exists\n */\nMethod.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n};\n\n/**\n * Should be called to check if the number of arguments is correct\n * \n * @method validateArgs\n * @param {Array} arguments\n * @throws {Error} if it is not\n */\nMethod.prototype.validateArgs = function (args) {\n if (args.length !== this.params) {\n throw errors.InvalidNumberOfParams();\n }\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nMethod.prototype.formatInput = function (args) {\n if (!this.inputFormatter) {\n return args;\n }\n\n return this.inputFormatter.map(function (formatter, index) {\n return formatter ? formatter(args[index]) : args[index];\n });\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nMethod.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nMethod.prototype.attachToObject = function (obj) {\n var func = this.send.bind(this);\n func.request = this.request.bind(this);\n func.call = this.call; // that's ugly. filter.js uses it\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n obj[name[0]][name[1]] = func;\n } else {\n obj[name[0]] = func; \n }\n};\n\n/**\n * Should create payload from given input args\n *\n * @method toPayload\n * @param {Array} args\n * @return {Object}\n */\nMethod.prototype.toPayload = function (args) {\n var call = this.getCall(args);\n var callback = this.extractCallback(args);\n var params = this.formatInput(args);\n this.validateArgs(params);\n\n return {\n method: call,\n params: params,\n callback: callback\n };\n};\n\n/**\n * Should be called to create pure JSONRPC request which can be used in batch request\n *\n * @method request\n * @param {...} params\n * @return {Object} jsonrpc request\n */\nMethod.prototype.request = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n payload.format = this.formatOutput.bind(this);\n return payload;\n};\n\n/**\n * Should send request to the API\n *\n * @method send\n * @param list of params\n * @return result\n */\nMethod.prototype.send = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n if (payload.callback) {\n var self = this;\n return RequestManager.getInstance().sendAsync(payload, function (err, result) {\n payload.callback(err, self.formatOutput(result));\n });\n }\n return this.formatOutput(RequestManager.getInstance().send(payload));\n};\n\nmodule.exports = Method;\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');\nvar Property = require('./property');\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n new Property({\n name: 'listening',\n getter: 'net_listening'\n }),\n new Property({\n name: 'peerCount',\n getter: 'net_peerCount',\n outputFormatter: utils.toDecimal\n })\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/**\n * @file property.js\n * @author Fabian Vogelsteller \n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\n\nvar Property = function (options) {\n this.name = options.name;\n this.getter = options.getter;\n this.setter = options.setter;\n this.outputFormatter = options.outputFormatter;\n this.inputFormatter = options.inputFormatter;\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nProperty.prototype.formatInput = function (arg) {\n return this.inputFormatter ? this.inputFormatter(arg) : arg;\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nProperty.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nProperty.prototype.attachToObject = function (obj) {\n var proto = {\n get: this.get.bind(this),\n set: this.set.bind(this)\n };\n\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n Object.defineProperty(obj[name[0]], name[1], proto); \n } else {\n Object.defineProperty(obj, name[0], proto);\n }\n};\n\n/**\n * Should be used to get value of the property\n *\n * @method get\n * @return {Object} value of the property\n */\nProperty.prototype.get = function () {\n return this.formatOutput(RequestManager.getInstance().send({\n method: this.getter\n }));\n};\n\n/**\n * Should be used to set value of the property\n *\n * @method set\n * @param {Object} new value of the property\n */\nProperty.prototype.set = function (value) {\n return RequestManager.getInstance().send({\n method: this.setter,\n params: [this.formatInput(value)]\n });\n};\n\nmodule.exports = Property;\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/**\n * @file property.js\n * @author Fabian Vogelsteller \n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\n\nvar Property = function (options) {\n this.name = options.name;\n this.getter = options.getter;\n this.setter = options.setter;\n this.outputFormatter = options.outputFormatter;\n this.inputFormatter = options.inputFormatter;\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nProperty.prototype.formatInput = function (arg) {\n return this.inputFormatter ? this.inputFormatter(arg) : arg;\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nProperty.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nProperty.prototype.attachToObject = function (obj) {\n var proto = {\n get: this.get.bind(this),\n };\n\n var names = this.name.split('.');\n var name = names[0];\n if (names.length > 1) {\n obj[names[0]] = obj[names[0]] || {};\n obj = obj[names[0]];\n name = names[1];\n }\n \n Object.defineProperty(obj, name, proto);\n\n var toAsyncName = function (prefix, name) {\n return prefix + name.charAt(0).toUpperCase() + name.slice(1);\n };\n\n obj[toAsyncName('get', name)] = this.getAsync.bind(this);\n};\n\n/**\n * Should be used to get value of the property\n *\n * @method get\n * @return {Object} value of the property\n */\nProperty.prototype.get = function () {\n return this.formatOutput(RequestManager.getInstance().send({\n method: this.getter\n }));\n};\n\n/**\n * Should be used to asynchrounously get value of property\n *\n * @method getAsync\n * @param {Function}\n */\nProperty.prototype.getAsync = function (callback) {\n var self = this;\n RequestManager.getInstance().sendAsync({\n method: this.getter\n }, function (err, result) {\n if (err) {\n return callback(err);\n }\n callback(err, self.formatOutput(result));\n });\n};\n\nmodule.exports = Property;\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/** \n * @file requestmanager.js\n * @author Jeffrey Wilcke \n * @author Marek Kotewicz \n * @author Marian Oancea \n * @author Fabian Vogelsteller \n * @author Gav Wood \n * @date 2014\n */\n\nvar Jsonrpc = require('./jsonrpc');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar errors = require('./errors');\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 * Singleton\n */\nvar RequestManager = function (provider) {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.provider = provider;\n this.polls = [];\n this.timeout = null;\n this.poll();\n};\n\n/**\n * @return {RequestManager} singleton\n */\nRequestManager.getInstance = function () {\n var instance = new RequestManager();\n return instance;\n};\n\n/**\n * Should be used to synchronously send request\n *\n * @method send\n * @param {Object} data\n * @return {Object}\n */\nRequestManager.prototype.send = function (data) {\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return null;\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n var result = this.provider.send(payload);\n\n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n throw errors.InvalidResponse(result);\n }\n\n return result.result;\n};\n\n/**\n * Should be used to asynchronously send request\n *\n * @method sendAsync\n * @param {Object} data\n * @param {Function} callback\n */\nRequestManager.prototype.sendAsync = function (data, callback) {\n if (!this.provider) {\n return callback(errors.InvalidProvider());\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n this.provider.sendAsync(payload, function (err, result) {\n if (err) {\n return callback(err);\n }\n \n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n return callback(errors.InvalidResponse(result));\n }\n\n callback(null, result.result);\n });\n};\n\n/**\n * Should be used to set provider of request manager\n *\n * @method setProvider\n * @param {Object}\n */\nRequestManager.prototype.setProvider = function (p) {\n this.provider = p;\n};\n\n/*jshint maxparams:4 */\n\n/**\n * Should be used to start polling\n *\n * @method startPolling\n * @param {Object} data\n * @param {Number} pollId\n * @param {Function} callback\n * @param {Function} uninstall\n *\n * @todo cleanup number of params\n */\nRequestManager.prototype.startPolling = function (data, pollId, callback, uninstall) {\n this.polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});\n};\n/*jshint maxparams:3 */\n\n/**\n * Should be used to stop polling for filter with given id\n *\n * @method stopPolling\n * @param {Number} pollId\n */\nRequestManager.prototype.stopPolling = function (pollId) {\n for (var i = this.polls.length; i--;) {\n var poll = this.polls[i];\n if (poll.id === pollId) {\n this.polls.splice(i, 1);\n }\n }\n};\n\n/**\n * Should be called to reset polling mechanism of request manager\n *\n * @method reset\n */\nRequestManager.prototype.reset = function () {\n this.polls.forEach(function (poll) {\n poll.uninstall(poll.id); \n });\n this.polls = [];\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n this.poll();\n};\n\n/**\n * Should be called to poll for changes on filter with given id\n *\n * @method poll\n */\nRequestManager.prototype.poll = function () {\n this.timeout = setTimeout(this.poll.bind(this), c.ETH_POLLING_TIMEOUT);\n\n if (!this.polls.length) {\n return;\n }\n\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return;\n }\n\n var payload = Jsonrpc.getInstance().toBatchPayload(this.polls.map(function (data) {\n return data.data;\n }));\n\n var self = this;\n this.provider.sendAsync(payload, function (error, results) {\n // TODO: console log?\n if (error) {\n return;\n }\n \n if (!utils.isArray(results)) {\n throw errors.InvalidResponse(results);\n }\n\n results.map(function (result, index) {\n result.callback = self.polls[index].callback;\n return result;\n }).filter(function (result) {\n var valid = Jsonrpc.getInstance().isValidResponse(result);\n if (!valid) {\n result.callback(errors.InvalidResponse(result));\n }\n return valid;\n }).filter(function (result) {\n return utils.isArray(result.result) && result.result.length > 0;\n }).forEach(function (result) {\n result.callback(null, result.result);\n });\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/** \n * @file requestmanager.js\n * @author Jeffrey Wilcke \n * @author Marek Kotewicz \n * @author Marian Oancea \n * @author Fabian Vogelsteller \n * @author Gav Wood \n * @date 2014\n */\n\nvar Jsonrpc = require('./jsonrpc');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar errors = require('./errors');\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 * Singleton\n */\nvar RequestManager = function (provider) {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.provider = provider;\n this.polls = [];\n this.timeout = null;\n this.poll();\n};\n\n/**\n * @return {RequestManager} singleton\n */\nRequestManager.getInstance = function () {\n var instance = new RequestManager();\n return instance;\n};\n\n/**\n * Should be used to synchronously send request\n *\n * @method send\n * @param {Object} data\n * @return {Object}\n */\nRequestManager.prototype.send = function (data) {\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return null;\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n var result = this.provider.send(payload);\n\n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n throw errors.InvalidResponse(result);\n }\n\n return result.result;\n};\n\n/**\n * Should be used to asynchronously send request\n *\n * @method sendAsync\n * @param {Object} data\n * @param {Function} callback\n */\nRequestManager.prototype.sendAsync = function (data, callback) {\n if (!this.provider) {\n return callback(errors.InvalidProvider());\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n this.provider.sendAsync(payload, function (err, result) {\n if (err) {\n return callback(err);\n }\n \n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n return callback(errors.InvalidResponse(result));\n }\n\n callback(null, result.result);\n });\n};\n\n/**\n * Should be called to asynchronously send batch request\n *\n * @method sendBatch\n * @param {Array} batch data\n * @param {Function} callback\n */\nRequestManager.prototype.sendBatch = function (data, callback) {\n if (!this.provider) {\n return callback(errors.InvalidProvider());\n }\n\n var payload = Jsonrpc.getInstance().toBatchPayload(data);\n\n this.provider.sendAsync(payload, function (err, results) {\n if (err) {\n return callback(err);\n }\n\n if (!utils.isArray(results)) {\n return callback(errors.InvalidResponse(results));\n }\n\n callback(err, results);\n }); \n};\n\n/**\n * Should be used to set provider of request manager\n *\n * @method setProvider\n * @param {Object}\n */\nRequestManager.prototype.setProvider = function (p) {\n this.provider = p;\n};\n\n/*jshint maxparams:4 */\n\n/**\n * Should be used to start polling\n *\n * @method startPolling\n * @param {Object} data\n * @param {Number} pollId\n * @param {Function} callback\n * @param {Function} uninstall\n *\n * @todo cleanup number of params\n */\nRequestManager.prototype.startPolling = function (data, pollId, callback, uninstall) {\n this.polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});\n};\n/*jshint maxparams:3 */\n\n/**\n * Should be used to stop polling for filter with given id\n *\n * @method stopPolling\n * @param {Number} pollId\n */\nRequestManager.prototype.stopPolling = function (pollId) {\n for (var i = this.polls.length; i--;) {\n var poll = this.polls[i];\n if (poll.id === pollId) {\n this.polls.splice(i, 1);\n }\n }\n};\n\n/**\n * Should be called to reset polling mechanism of request manager\n *\n * @method reset\n */\nRequestManager.prototype.reset = function () {\n this.polls.forEach(function (poll) {\n poll.uninstall(poll.id); \n });\n this.polls = [];\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n this.poll();\n};\n\n/**\n * Should be called to poll for changes on filter with given id\n *\n * @method poll\n */\nRequestManager.prototype.poll = function () {\n this.timeout = setTimeout(this.poll.bind(this), c.ETH_POLLING_TIMEOUT);\n\n if (!this.polls.length) {\n return;\n }\n\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return;\n }\n\n var payload = Jsonrpc.getInstance().toBatchPayload(this.polls.map(function (data) {\n return data.data;\n }));\n\n var self = this;\n this.provider.sendAsync(payload, function (error, results) {\n // TODO: console log?\n if (error) {\n return;\n }\n \n if (!utils.isArray(results)) {\n throw errors.InvalidResponse(results);\n }\n\n results.map(function (result, index) {\n result.callback = self.polls[index].callback;\n return result;\n }).filter(function (result) {\n var valid = Jsonrpc.getInstance().isValidResponse(result);\n if (!valid) {\n result.callback(errors.InvalidResponse(result));\n }\n return valid;\n }).filter(function (result) {\n return utils.isArray(result.result) && result.result.length > 0;\n }).forEach(function (result) {\n result.callback(null, result.result);\n });\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 Method = require('./method');\nvar formatters = require('./formatters');\n\nvar post = new Method({\n name: 'post', \n call: 'shh_post', \n params: 1,\n inputFormatter: [formatters.inputPostFormatter]\n});\n\nvar newIdentity = new Method({\n name: 'newIdentity',\n call: 'shh_newIdentity',\n params: 0\n});\n\nvar hasIdentity = new Method({\n name: 'hasIdentity',\n call: 'shh_hasIdentity',\n params: 1\n});\n\nvar newGroup = new Method({\n name: 'newGroup',\n call: 'shh_newGroup',\n params: 0\n});\n\nvar addToGroup = new Method({\n name: 'addToGroup',\n call: 'shh_addToGroup',\n params: 0\n});\n\nvar methods = [\n post,\n newIdentity,\n hasIdentity,\n newGroup,\n addToGroup\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 watches.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar Method = require('./method');\n\n/// @returns an array of objects describing web3.eth.filter api methods\nvar eth = function () {\n var newFilterCall = function (args) {\n return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter';\n };\n\n var newFilter = new Method({\n name: 'newFilter',\n call: newFilterCall,\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'eth_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'eth_getFilterLogs',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'eth_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\n/// @returns an array of objects describing web3.shh.watch api methods\nvar shh = function () {\n var newFilter = new Method({\n name: 'newFilter',\n call: 'shh_newFilter',\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'shh_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'shh_getMessages',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'shh_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\nmodule.exports = {\n eth: eth,\n shh: shh\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\nvar Method = require('./method');\n\n/// @returns an array of objects describing web3.eth.filter api methods\nvar eth = function () {\n var newFilterCall = function (args) {\n var type = args[0];\n\n switch(type) {\n case 'latest':\n args.pop();\n this.params = 0;\n return 'eth_newBlockFilter';\n case 'pending':\n args.pop();\n this.params = 0;\n return 'eth_newPendingTransactionFilter';\n default:\n return 'eth_newFilter';\n }\n };\n\n var newFilter = new Method({\n name: 'newFilter',\n call: newFilterCall,\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'eth_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'eth_getFilterLogs',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'eth_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\n/// @returns an array of objects describing web3.shh.watch api methods\nvar shh = function () {\n var newFilter = new Method({\n name: 'newFilter',\n call: 'shh_newFilter',\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'shh_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'shh_getMessages',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'shh_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\nmodule.exports = {\n eth: eth,\n shh: shh\n};\n\n", null, "'use strict';\n\nmodule.exports = BigNumber; // jshint ignore:line\n\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\n// dont override global variable\nif (typeof window !== 'undefined' && typeof window.web3 === 'undefined') {\n window.web3 = web3;\n}\n\nmodule.exports = web3;\n\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');\n\n// dont override global variable\nif (typeof window !== 'undefined' && typeof window.web3 === 'undefined') {\n window.web3 = web3;\n}\n\nmodule.exports = web3;\n\n" ] } \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/web3-light.min.js b/libjsqrc/ethereumjs/dist/web3-light.min.js index 4c0fd2930..22527f18e 100644 --- a/libjsqrc/ethereumjs/dist/web3-light.min.js +++ b/libjsqrc/ethereumjs/dist/web3-light.min.js @@ -1,2 +1,2 @@ -require=function t(e,r,n){function o(a,s){if(!r[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=r[a]={exports:{}};e[a][0].call(l.exports,function(t){var r=e[a][1][t];return o(r?r:t)},l,l.exports,t,e,r,n)}return r[a].exports}for(var i="function"==typeof require&&require,a=0;a0&&console.warn("didn't found matching constructor, using default one"),"")};e.exports={formatConstructorParams:i}},{"./coder":2,"./utils":5}],2:[function(t,e,r){var n=t("bignumber.js"),o=t("../utils/utils"),i=t("./formatters"),a=t("./param"),s=function(t){return"[]"===t.slice(-2)},u=function(t){this._name=t.name,this._match=t.match,this._mode=t.mode,this._inputFormatter=t.inputFormatter,this._outputFormatter=t.outputFormatter};u.prototype.isType=function(t){return"strict"===this._match?this._name===t||0===t.indexOf(this._name)&&"[]"===t.slice(this._name.length):"prefix"===this._match?0===t.indexOf(this._name):void 0},u.prototype.formatInput=function(t,e){if(o.isArray(t)&&e){var r=this;return t.map(function(t){return r._inputFormatter(t)}).reduce(function(t,e){return t.combine(e)},i.formatInputInt(t.length)).withOffset(32)}return this._inputFormatter(t)},u.prototype.formatOutput=function(t,e){if(e){for(var r=[],o=new n(t.dynamicPart().slice(0,64),16),i=0;64*o>i;i+=64)r.push(this._outputFormatter(new a(t.dynamicPart().substr(i+64,64))));return r}return this._outputFormatter(t)},u.prototype.sliceParam=function(t,e,r){return"bytes"===this._mode?a.decodeBytes(t,e):s(r)?a.decodeArray(t,e):a.decodeParam(t,e)};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var r=this,n=t.map(function(t,n){return r._formatInput(t,e[n])});return a.encodeList(n)},c.prototype.decodeParam=function(t,e){return this.decodeParams([t],e)[0]},c.prototype.decodeParams=function(t,e){var r=this;return t.map(function(t,n){var o=r._requireType(t),i=o.sliceParam(e,n,t);return o.formatOutput(i,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:i.formatInputBool,outputFormatter:i.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:i.formatInputDynamicBytes,outputFormatter:i.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:i.formatInputBytes,outputFormatter:i.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputUReal})]);e.exports=l},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(t,e,r){var n=t("bignumber.js"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./param"),s=function(t){var e=2*i.ETH_PADDING;n.config(i.ETH_BIGNUMBER_ROUNDING_MODE);var r=o.padLeft(o.toTwosComplement(t).round().toString(16),e);return new a(r)},u=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(s(t.length).value+e,32)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},p=function(t){return s(new n(t).times(new n(2).pow(128)))},f=function(t){return"1"===new n(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.staticPart()||"0";return f(e)?new n(e,16).minus(new n("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new n(e,16)},h=function(t){var e=t.staticPart()||"0";return new n(e,16)},d=function(t){return m(t).dividedBy(new n(2).pow(128))},y=function(t){return h(t).dividedBy(new n(2).pow(128))},g=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},b=function(t){return o.toAscii(t.staticPart())},v=function(t){return o.toAscii(t.dynamicPart().slice(64))},w=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:p,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:y,formatOutputBool:g,formatOutputBytes:b,formatOutputDynamicBytes:v,formatOutputAddress:w}},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(t,e,r){var n=t("../utils/utils"),o=function(t,e){this.value=t||"",this.offset=e};o.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},o.prototype.withOffset=function(t){return new o(this.value,t)},o.prototype.combine=function(t){return new o(this.value+t.value)},o.prototype.isDynamic=function(){return this.value.length>64},o.prototype.offsetAsBytes=function(){return this.isDynamic()?n.padLeft(n.toTwosComplement(this.offset).toString(16),64):""},o.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},o.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},o.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},o.encodeList=function(t){var e=32*t.length,r=t.map(function(t){if(!t.isDynamic())return t;var r=e;return e+=t.dynamicPartLength(),t.withOffset(r)});return r.reduce(function(t,e){return t+e.dynamicPart()},r.reduce(function(t,e){return t+e.staticPart()},""))},o.decodeParam=function(t,e){return e=e||0,new o(t.substr(64*e,64))};var i=function(t,e){return parseInt("0x"+t.substr(64*e,64))};o.decodeBytes=function(t,e){e=e||0;var r=i(t,e);return new o(t.substr(2*r,128))},o.decodeArray=function(t,e){e=e||0;var r=i(t,e),n=parseInt("0x"+t.substr(2*r,64));return new o(t.substr(2*r,64*(n+1)))},e.exports=o},{"../utils/utils":8}],5:[function(t,e,r){var n=function(t,e){return t.filter(function(t){return"constructor"===t.type&&t.inputs.length===e})[0]};e.exports={getConstructor:n}},{}],6:[function(t,e,r){"use strict";r.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],7:[function(t,e,r){var n=t("bignumber.js"),o=["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:o,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:n.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],8:[function(t,e,r){var n=t("bignumber.js"),o={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"},i=function(t,e,r){return new Array(e-t.length+1).join(r?r:"0")+t},a=function(t){var e="",r=0,n=t.length;for("0x"===t.substring(0,2)&&(r=2);n>r;r+=2){var o=parseInt(t.substr(r,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",r=0;rthis._inputTypes.length&&i.isObject(t[t.length-1])&&(e=t.pop()),e.to=this._address,e.data="0x"+this.signature()+o.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return n.sha3(n.fromAscii(this._name)).slice(2,10)},a.prototype.call=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments)),e=n.eth.call(t);e=e.length>=2?e.slice(2):e;var r=o.decodeParams(this._outputTypes,e);return 1===r.length?r[0]:r},a.prototype.sendTransaction=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments));n.eth.sendTransaction(t)},a.prototype.displayName=function(){return i.extractDisplayName(this._name)},a.prototype.typeName=function(){return i.extractTypeName(this._name)},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var r=this.displayName();t[r]||(t[r]=e),t[r][this.typeName()]=e},e.exports=a},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(t,e,r){"use strict";var n=t("xmlhttprequest").XMLHttpRequest,o=t("./errors"),i=function(t){this.host=t||"http://localhost:8545"};i.prototype.send=function(t){var e=new n;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(r){throw o.InvalidConnection(this.host)}var i=e.responseText;try{i=JSON.parse(i)}catch(a){throw o.InvalidResponse(i)}return i},i.prototype.sendAsync=function(t,e){var r=new n;r.onreadystatechange=function(){if(4===r.readyState){var t=r.responseText,n=null;try{t=JSON.parse(t)}catch(i){n=o.InvalidResponse(t)}e(n,t)}},r.open("POST",this.host,!0);try{r.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":13,xmlhttprequest:6}],20:[function(t,e,r){var n=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};n.getInstance=function(){var t=new n;return t},n.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},n.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},n.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=n},{}],21:[function(t,e,r){var n=t("./requestmanager"),o=t("../utils/utils"),i=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return o.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():null},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw i.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,r){return e?e(t[r]):t[r]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.call=this.call;var r=this.name.split(".");r.length>1?(t[r[0]]=t[r[0]]||{},t[r[0]][r[1]]=e):t[r[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),r=this.extractCallback(t),n=this.formatInput(t);return this.validateArgs(n),{method:e,params:n,callback:r}},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return n.getInstance().sendAsync(t,function(r,n){t.callback(null,e.formatOutput(n))})}return this.formatOutput(n.getInstance().send(t))},e.exports=a},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(t,e,r){var n=t("../utils/utils"),o=t("./property"),i=[],a=[new o({name:"listening",getter:"net_listening"}),new o({name:"peerCount",getter:"net_peerCount",outputFormatter:n.toDecimal})];e.exports={methods:i,properties:a}},{"../utils/utils":8,"./property":23}],23:[function(t,e,r){var n=t("./requestmanager"),o=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};o.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},o.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},o.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},r=this.name.split(".");r.length>1?(t[r[0]]=t[r[0]]||{},Object.defineProperty(t[r[0]],r[1],e)):Object.defineProperty(t,r[0],e)},o.prototype.get=function(){return this.formatOutput(n.getInstance().send({method:this.getter}))},o.prototype.set=function(t){return n.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=o},{"./requestmanager":25}],24:[function(t,e,r){var n=function(){};n.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=n},{}],25:[function(t,e,r){var n=t("./jsonrpc"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=n.getInstance().toPayload(t.method,t.params),r=this.provider.send(e);if(!n.getInstance().isValidResponse(r))throw a.InvalidResponse(r);return r.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var r=n.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(r,function(t,r){return t?e(t):n.getInstance().isValidResponse(r)?void e(null,r.result):e(a.InvalidResponse(r))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,r,n){this.polls.push({data:t,id:e,callback:r,uninstall:n})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var r=this.polls[e];r.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),i.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=n.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,r){if(!t){if(!o.isArray(r))throw a.InvalidResponse(r);r.map(function(t,r){return t.callback=e.polls[r].callback,t}).filter(function(t){var e=n.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return o.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(t,e,r){var n=t("./method"),o=t("./formatters"),i=new n({name:"post",call:"shh_post",params:1,inputFormatter:[o.inputPostFormatter]}),a=new n({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new n({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new n({name:"newGroup",call:"shh_newGroup",params:0}),c=new n({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[i,a,s,u,c];e.exports={methods:l}},{"./formatters":17,"./method":21}],27:[function(t,e,r){var n=t("./method"),o=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new n({name:"newFilter",call:t,params:1}),r=new n({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new n({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new n({name:"poll",call:"eth_getFilterChanges",params:1});return[e,r,o,i]},i=function(){var t=new n({name:"newFilter",call:"shh_newFilter",params:1}),e=new n({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),r=new n({name:"getLogs",call:"shh_getMessages",params:1}),o=new n({name:"poll",call:"shh_getFilterChanges",params:1 -});return[t,e,r,o]};e.exports={eth:o,shh:i}},{"./method":21}],28:[function(t,e,r){},{}],"bignumber.js":[function(t,e,r){"use strict";e.exports=BigNumber},{}],web3:[function(t,e,r){var n=t("./lib/web3");n.providers.HttpProvider=t("./lib/web3/httpprovider"),n.providers.QtSyncProvider=t("./lib/web3/qtsync"),n.eth.contract=t("./lib/web3/contract"),n.abi=t("./lib/solidity/abi"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=n),e.exports=n},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]); \ No newline at end of file +require=function t(e,n,r){function o(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ai;i+=64)n.push(this._outputFormatter(new a(t.dynamicPart().substr(i+64,64))));return n}return this._outputFormatter(t)},u.prototype.sliceParam=function(t,e,n){return"bytes"===this._mode?a.decodeBytes(t,e):s(n)?a.decodeArray(t,e):a.decodeParam(t,e)};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var n=this,r=t.map(function(t,r){return n._formatInput(t,e[r])});return a.encodeList(r)},c.prototype.decodeParam=function(t,e){return this.decodeParams([t],e)[0]},c.prototype.decodeParams=function(t,e){var n=this;return t.map(function(t,r){var o=n._requireType(t),i=o.sliceParam(e,r,t);return o.formatOutput(i,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:i.formatInputBool,outputFormatter:i.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:i.formatInputDynamicBytes,outputFormatter:i.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:i.formatInputBytes,outputFormatter:i.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputUReal})]);e.exports=l},{"../utils/utils":6,"./formatters":2,"./param":3,"bignumber.js":"bignumber.js"}],2:[function(t,e,n){var r=t("bignumber.js"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./param"),s=function(t){var e=2*i.ETH_PADDING;r.config(i.ETH_BIGNUMBER_ROUNDING_MODE);var n=o.padLeft(o.toTwosComplement(t).round().toString(16),e);return new a(n)},u=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(s(t.length).value+e,32)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},p=function(t){return s(new r(t).times(new r(2).pow(128)))},f=function(t){return"1"===new r(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.staticPart()||"0";return f(e)?new r(e,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(e,16)},h=function(t){var e=t.staticPart()||"0";return new r(e,16)},d=function(t){return m(t).dividedBy(new r(2).pow(128))},y=function(t){return h(t).dividedBy(new r(2).pow(128))},g=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},v=function(t){return o.toAscii(t.staticPart())},b=function(t){return o.toAscii(t.dynamicPart().slice(64))},w=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:p,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:y,formatOutputBool:g,formatOutputBytes:v,formatOutputDynamicBytes:b,formatOutputAddress:w}},{"../utils/config":5,"../utils/utils":6,"./param":3,"bignumber.js":"bignumber.js"}],3:[function(t,e,n){var r=t("../utils/utils"),o=function(t,e){this.value=t||"",this.offset=e};o.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},o.prototype.withOffset=function(t){return new o(this.value,t)},o.prototype.combine=function(t){return new o(this.value+t.value)},o.prototype.isDynamic=function(){return this.value.length>64},o.prototype.offsetAsBytes=function(){return this.isDynamic()?r.padLeft(r.toTwosComplement(this.offset).toString(16),64):""},o.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},o.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},o.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},o.encodeList=function(t){var e=32*t.length,n=t.map(function(t){if(!t.isDynamic())return t;var n=e;return e+=t.dynamicPartLength(),t.withOffset(n)});return n.reduce(function(t,e){return t+e.dynamicPart()},n.reduce(function(t,e){return t+e.staticPart()},""))},o.decodeParam=function(t,e){return e=e||0,new o(t.substr(64*e,64))};var i=function(t,e){return parseInt("0x"+t.substr(64*e,64))};o.decodeBytes=function(t,e){e=e||0;var n=i(t,e);return new o(t.substr(2*n,128))},o.decodeArray=function(t,e){e=e||0;var n=i(t,e),r=parseInt("0x"+t.substr(2*n,64));return new o(t.substr(2*n,64*(r+1)))},e.exports=o},{"../utils/utils":6}],4:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],5:[function(t,e,n){var r=t("bignumber.js"),o=["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:o,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],6:[function(t,e,n){var r=t("bignumber.js"),o={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"},i=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t){var e="",n=0,r=t.length;for("0x"===t.substring(0,2)&&(n=2);r>n;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",n=0;nthis._inputTypes.length&&i.isObject(t[t.length-1])&&(e=t[t.length-1]),e.to=this._address,e.data="0x"+this.signature()+o.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return r.sha3(r.fromAscii(this._name)).slice(2,10)},a.prototype.unpackOutput=function(t){if(null!==t){t=t.length>=2?t.slice(2):t;var e=o.decodeParams(this._outputTypes,t);return 1===e.length?e[0]:e}},a.prototype.call=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);if(!e){var o=r.eth.call(n);return this.unpackOutput(o)}var i=this;r.eth.call(n,function(t,n){e(t,i.unpackOutput(n))})},a.prototype.sendTransaction=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.sendTransaction(n,e):void r.eth.sendTransaction(n)},a.prototype.displayName=function(){return i.extractDisplayName(this._name)},a.prototype.typeName=function(){return i.extractTypeName(this._name)},a.prototype.request=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t),r=this.unpackOutput.bind(this);return{callback:e,payload:n,format:r}},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.request=this.request.bind(this),e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=a},{"../solidity/coder":1,"../utils/utils":6,"../web3":8}],18:[function(t,e,n){"use strict";var r=t("xmlhttprequest").XMLHttpRequest,o=t("./errors"),i=function(t){this.host=t||"http://localhost:8545"};i.prototype.send=function(t){var e=new r;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(n){throw o.InvalidConnection(this.host)}var i=e.responseText;try{i=JSON.parse(i)}catch(a){throw o.InvalidResponse(i)}return i},i.prototype.sendAsync=function(t,e){var n=new r;n.onreadystatechange=function(){if(4===n.readyState){var t=n.responseText,r=null;try{t=JSON.parse(t)}catch(i){r=o.InvalidResponse(t)}e(r,t)}},n.open("POST",this.host,!0);try{n.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":12,xmlhttprequest:4}],19:[function(t,e,n){var r=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};r.getInstance=function(){var t=new r;return t},r.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},r.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},r.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=r},{}],20:[function(t,e,n){var r=t("./requestmanager"),o=t("../utils/utils"),i=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return o.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():void 0},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw i.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,n){return e?e(t[n]):t[n]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.request=this.request.bind(this),e.call=this.call;var n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},t[n[0]][n[1]]=e):t[n[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),n=this.extractCallback(t),r=this.formatInput(t);return this.validateArgs(r),{method:e,params:r,callback:n}},a.prototype.request=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));return t.format=this.formatOutput.bind(this),t},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return r.getInstance().sendAsync(t,function(n,r){t.callback(n,e.formatOutput(r))})}return this.formatOutput(r.getInstance().send(t))},e.exports=a},{"../utils/utils":6,"./errors":12,"./requestmanager":24}],21:[function(t,e,n){var r=t("../utils/utils"),o=t("./property"),i=[],a=[new o({name:"listening",getter:"net_listening"}),new o({name:"peerCount",getter:"net_peerCount",outputFormatter:r.toDecimal})];e.exports={methods:i,properties:a}},{"../utils/utils":6,"./property":22}],22:[function(t,e,n){var r=t("./requestmanager"),o=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};o.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},o.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},o.prototype.attachToObject=function(t){var e={get:this.get.bind(this)},n=this.name.split("."),r=n[0];n.length>1&&(t[n[0]]=t[n[0]]||{},t=t[n[0]],r=n[1]),Object.defineProperty(t,r,e);var o=function(t,e){return t+e.charAt(0).toUpperCase()+e.slice(1)};t[o("get",r)]=this.getAsync.bind(this)},o.prototype.get=function(){return this.formatOutput(r.getInstance().send({method:this.getter}))},o.prototype.getAsync=function(t){var e=this;r.getInstance().sendAsync({method:this.getter},function(n,r){return n?t(n):void t(n,e.formatOutput(r))})},e.exports=o},{"./requestmanager":24}],23:[function(t,e,n){var r=function(){};r.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=r},{}],24:[function(t,e,n){var r=t("./jsonrpc"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=r.getInstance().toPayload(t.method,t.params),n=this.provider.send(e);if(!r.getInstance().isValidResponse(n))throw a.InvalidResponse(n);return n.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var n=r.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(n,function(t,n){return t?e(t):r.getInstance().isValidResponse(n)?void e(null,n.result):e(a.InvalidResponse(n))})},s.prototype.sendBatch=function(t,e){if(!this.provider)return e(a.InvalidProvider());var n=r.getInstance().toBatchPayload(t);this.provider.sendAsync(n,function(t,n){return t?e(t):o.isArray(n)?void e(t,n):e(a.InvalidResponse(n))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,n,r){this.polls.push({data:t,id:e,callback:n,uninstall:r})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var n=this.polls[e];n.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),i.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=r.getInstance().toBatchPayload(this.polls.map(function(t){ +return t.data})),e=this;this.provider.sendAsync(t,function(t,n){if(!t){if(!o.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){return t.callback=e.polls[n].callback,t}).filter(function(t){var e=r.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return o.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":5,"../utils/utils":6,"./errors":12,"./jsonrpc":19}],25:[function(t,e,n){var r=t("./method"),o=t("./formatters"),i=new r({name:"post",call:"shh_post",params:1,inputFormatter:[o.inputPostFormatter]}),a=new r({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new r({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new r({name:"newGroup",call:"shh_newGroup",params:0}),c=new r({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[i,a,s,u,c];e.exports={methods:l}},{"./formatters":16,"./method":20}],26:[function(t,e,n){var r=t("./method"),o=function(){var t=function(t){var e=t[0];switch(e){case"latest":return t.pop(),this.params=0,"eth_newBlockFilter";case"pending":return t.pop(),this.params=0,"eth_newPendingTransactionFilter";default:return"eth_newFilter"}},e=new r({name:"newFilter",call:t,params:1}),n=new r({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new r({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new r({name:"poll",call:"eth_getFilterChanges",params:1});return[e,n,o,i]},i=function(){var t=new r({name:"newFilter",call:"shh_newFilter",params:1}),e=new r({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),n=new r({name:"getLogs",call:"shh_getMessages",params:1}),o=new r({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,n,o]};e.exports={eth:o,shh:i}},{"./method":20}],27:[function(t,e,n){},{}],"bignumber.js":[function(t,e,n){"use strict";e.exports=BigNumber},{}],web3:[function(t,e,n){var r=t("./lib/web3");r.providers.HttpProvider=t("./lib/web3/httpprovider"),r.providers.QtSyncProvider=t("./lib/web3/qtsync"),r.eth.contract=t("./lib/web3/contract"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/web3":8,"./lib/web3/contract":10,"./lib/web3/httpprovider":18,"./lib/web3/qtsync":23}]},{},["web3"]); \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/web3.js b/libjsqrc/ethereumjs/dist/web3.js index ec66a38d8..2745ab36f 100644 --- a/libjsqrc/ethereumjs/dist/web3.js +++ b/libjsqrc/ethereumjs/dist/web3.js @@ -15,52 +15,6 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ You should have received a copy of the GNU Lesser General Public License along with ethereum.js. If not, see . */ -/** - * @file abi.js - * @author Marek Kotewicz - * @author Gav Wood - * @date 2014 - */ - -var coder = require('./coder'); -var utils = require('./utils'); - -var formatConstructorParams = function (abi, params) { - var constructor = utils.getConstructor(abi, params.length); - if (!constructor) { - if (params.length > 0) { - console.warn("didn't found matching constructor, using default one"); - } - return ''; - } - - return coder.encodeParams(constructor.inputs.map(function (input) { - return input.type; - }), params); -}; - -module.exports = { - formatConstructorParams: formatConstructorParams -}; - - -},{"./coder":2,"./utils":5}],2:[function(require,module,exports){ -/* - This file is part of ethereum.js. - - ethereum.js is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethereum.js 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with ethereum.js. If not, see . -*/ /** * @file coder.js * @author Marek Kotewicz @@ -328,7 +282,7 @@ var coder = new SolidityCoder([ module.exports = coder; -},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(require,module,exports){ +},{"../utils/utils":6,"./formatters":2,"./param":3,"bignumber.js":"bignumber.js"}],2:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -548,7 +502,7 @@ module.exports = { }; -},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":6,"./param":3,"bignumber.js":"bignumber.js"}],3:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -760,54 +714,7 @@ SolidityParam.decodeArray = function (bytes, index) { module.exports = SolidityParam; -},{"../utils/utils":8}],5:[function(require,module,exports){ -/* - This file is part of ethereum.js. - - ethereum.js is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethereum.js 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with ethereum.js. If not, see . -*/ -/** - * @file utils.js - * @author Marek Kotewicz - * @date 2015 - */ - -/** - * Returns the contstructor with matching number of arguments - * - * @method getConstructor - * @param {Array} abi - * @param {Number} numberOfArgs - * @returns {Object} constructor function abi - */ -var getConstructor = function (abi, numberOfArgs) { - return abi.filter(function (f) { - return f.type === 'constructor' && f.inputs.length === numberOfArgs; - })[0]; -}; - -//var getSupremeType = function (type) { - //return type.substr(0, type.indexOf('[')) + ']'; -//}; - - -module.exports = { - getConstructor: getConstructor -}; - - -},{}],6:[function(require,module,exports){ +},{"../utils/utils":6}],4:[function(require,module,exports){ 'use strict'; // go env doesn't have and need XMLHttpRequest @@ -818,7 +725,7 @@ if (typeof XMLHttpRequest === 'undefined') { } -},{}],7:[function(require,module,exports){ +},{}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -890,7 +797,7 @@ module.exports = { }; -},{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],6:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1256,6 +1163,7 @@ var toAddress = function (address) { return '0x' + padLeft(toHex(address).substr(2), 40); }; + /** * Returns true if object is BigNumber, otherwise false * @@ -1366,12 +1274,12 @@ module.exports = { }; -},{"bignumber.js":"bignumber.js"}],9:[function(require,module,exports){ +},{"bignumber.js":"bignumber.js"}],7:[function(require,module,exports){ module.exports={ - "version": "0.3.6" + "version": "0.4.2" } -},{}],10:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1411,6 +1319,7 @@ var RequestManager = require('./web3/requestmanager'); var c = require('./utils/config'); var Method = require('./web3/method'); var Property = require('./web3/property'); +var Batch = require('./web3/batch'); var web3Methods = [ new Method({ @@ -1503,6 +1412,9 @@ web3.toBigNumber = utils.toBigNumber; web3.toWei = utils.toWei; web3.fromWei = utils.fromWei; web3.isAddress = utils.isAddress; +web3.createBatch = function () { + return new Batch(); +}; // ADD defaultblock Object.defineProperty(web3.eth, 'defaultBlock', { @@ -1538,7 +1450,70 @@ setupMethods(web3.shh, shh.methods); module.exports = web3; -},{"./utils/config":7,"./utils/utils":8,"./version.json":9,"./web3/db":12,"./web3/eth":14,"./web3/filter":16,"./web3/formatters":17,"./web3/method":21,"./web3/net":22,"./web3/property":23,"./web3/requestmanager":25,"./web3/shh":26,"./web3/watches":27}],11:[function(require,module,exports){ +},{"./utils/config":5,"./utils/utils":6,"./version.json":7,"./web3/batch":9,"./web3/db":11,"./web3/eth":13,"./web3/filter":15,"./web3/formatters":16,"./web3/method":20,"./web3/net":21,"./web3/property":22,"./web3/requestmanager":24,"./web3/shh":25,"./web3/watches":26}],9:[function(require,module,exports){ +/* + This file is part of ethereum.js. + + ethereum.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ethereum.js 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with ethereum.js. If not, see . +*/ +/** + * @file batch.js + * @author Marek Kotewicz + * @date 2015 + */ + +var RequestManager = require('./requestmanager'); + +var Batch = function () { + this.requests = []; +}; + +/** + * Should be called to add create new request to batch request + * + * @method add + * @param {Object} jsonrpc requet object + */ +Batch.prototype.add = function (request) { + this.requests.push(request); +}; + +/** + * Should be called to execute batch request + * + * @method execute + */ +Batch.prototype.execute = function () { + var requests = this.requests; + RequestManager.getInstance().sendBatch(requests, function (err, results) { + results = results || []; + requests.map(function (request, index) { + return results[index] || {}; + }).map(function (result, index) { + return requests[index].format ? requests[index].format(result.result) : result.result; + }).forEach(function (result, index) { + if (requests[index].callback) { + requests[index].callback(err, result); + } + }); + }); +}; + +module.exports = Batch; + + +},{"./requestmanager":24}],10:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1562,13 +1537,39 @@ module.exports = web3; */ var web3 = require('../web3'); -var solAbi = require('../solidity/abi'); var utils = require('../utils/utils'); +var coder = require('../solidity/coder'); var SolidityEvent = require('./event'); var SolidityFunction = require('./function'); -var addFunctionsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to encode constructor params + * + * @method encodeConstructorParams + * @param {Array} abi + * @param {Array} constructor params + */ +var encodeConstructorParams = function (abi, params) { + return abi.filter(function (json) { + return json.type === 'constructor' && json.inputs.length === params.length; + }).map(function (json) { + return json.inputs.map(function (input) { + return input.type; + }); + }).map(function (types) { + return coder.encodeParams(types, params); + })[0] || ''; +}; + +/** + * Should be called to add functions to contract object + * + * @method addFunctionsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addFunctionsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'function'; }).map(function (json) { return new SolidityFunction(json, contract.address); @@ -1577,8 +1578,15 @@ var addFunctionsToContract = function (contract, desc) { }); }; -var addEventsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to add events to contract object + * + * @method addEventsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addEventsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'event'; }).map(function (json) { return new SolidityEvent(json, contract.address); @@ -1588,65 +1596,106 @@ var addEventsToContract = function (contract, desc) { }; /** - * This method should be called when we want to call / transact some solidity method from javascript - * it returns an object which has same methods available as solidity contract description - * usage example: - * - * var abi = [{ - * name: 'myMethod', - * inputs: [{ name: 'a', type: 'string' }], - * outputs: [{name: 'd', type: 'string' }] - * }]; // contract abi - * - * var MyContract = web3.eth.contract(abi); // creation of contract prototype + * Should be called to create new ContractFactory * - * var contractInstance = new MyContract('0x0123123121'); - * - * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default) - * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit) - * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction - * - * @param abi - abi json description of the contract, which is being created - * @returns contract object + * @method contract + * @param {Array} abi + * @returns {ContractFactory} new contract factory */ var contract = function (abi) { + return new ContractFactory(abi); +}; - // return prototype - return Contract.bind(null, abi); +/** + * Should be called to create new ContractFactory instance + * + * @method ContractFactory + * @param {Array} abi + */ +var ContractFactory = function (abi) { + this.abi = abi; }; -var Contract = function (abi, options) { +/** + * Should be called to create new contract on a blockchain + * + * @method new + * @param {Any} contract constructor param1 (optional) + * @param {Any} contract constructor param2 (optional) + * @param {Object} contract transaction object (required) + * @param {Function} callback + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.new = function () { + // parse arguments + var options = {}; // required! + var callback; - this.address = ''; - if (utils.isAddress(options)) { - this.address = options; - } else { // is an object! - // TODO, parse the rest of the args - options = options || {}; - var args = Array.prototype.slice.call(arguments, 2); - var bytes = solAbi.formatConstructorParams(abi, args); - options.data += bytes; - this.address = web3.eth.sendTransaction(options); + var args = Array.prototype.slice.call(arguments); + if (utils.isFunction(args[args.length - 1])) { + callback = args.pop(); } - addFunctionsToContract(this, abi); - addEventsToContract(this, abi); + var last = args[args.length - 1]; + if (utils.isObject(last) && !utils.isArray(last)) { + options = args.pop(); + } + + // throw an error if there are no options + + var bytes = encodeConstructorParams(this.abi, args); + options.data += bytes; + + if (!callback) { + var address = web3.eth.sendTransaction(options); + return this.at(address); + } + + var self = this; + web3.eth.sendTransaction(options, function (err, address) { + if (err) { + callback(err); + } + self.at(address, callback); + }); }; -Contract.prototype.call = function () { - console.error('contract.call is deprecated'); - return this; +/** + * Should be called to get access to existing contract on a blockchain + * + * @method at + * @param {Address} contract address (required) + * @param {Function} callback {optional) + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.at = function (address, callback) { + // TODO: address is required + + if (callback) { + callback(null, new Contract(this.abi, address)); + } + return new Contract(this.abi, address); }; -Contract.prototype.sendTransaction = function () { - console.error('contract.sendTransact is deprecated'); - return this; +/** + * Should be called to create new contract instance + * + * @method Contract + * @param {Array} abi + * @param {Address} contract address + */ +var Contract = function (abi, address) { + this.address = address; + addFunctionsToContract(this, abi); + addEventsToContract(this, abi); }; module.exports = contract; -},{"../solidity/abi":1,"../utils/utils":8,"../web3":10,"./event":15,"./function":18}],12:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":6,"../web3":8,"./event":14,"./function":17}],11:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1704,7 +1753,7 @@ module.exports = { methods: methods }; -},{"./method":21}],13:[function(require,module,exports){ +},{"./method":20}],12:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1744,7 +1793,7 @@ module.exports = { }; -},{}],14:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1921,6 +1970,14 @@ var call = new Method({ inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter] }); +var estimateGas = new Method({ + name: 'estimateGas', + call: 'eth_estimateGas', + params: 1, + inputFormatter: [formatters.inputTransactionFormatter], + outputFormatter: utils.toDecimal +}); + var compileSolidity = new Method({ name: 'compile.solidity', call: 'eth_compileSolidity', @@ -1939,6 +1996,18 @@ var compileSerpent = new Method({ params: 1 }); +var submitWork = new Method({ + name: 'submitWork', + call: 'eth_submitWork', + params: 3 +}); + +var getWork = new Method({ + name: 'getWork', + call: 'eth_getWork', + params: 0 +}); + var methods = [ getBalance, getStorageAt, @@ -1952,10 +2021,13 @@ var methods = [ getTransactionFromBlock, getTransactionCount, call, + estimateGas, sendTransaction, compileSolidity, compileLLL, compileSerpent, + submitWork, + getWork ]; /// @returns an array of objects describing web3.eth api properties @@ -1998,7 +2070,7 @@ module.exports = { }; -},{"../utils/utils":8,"./formatters":17,"./method":21,"./property":23}],15:[function(require,module,exports){ +},{"../utils/utils":6,"./formatters":16,"./method":20,"./property":22}],14:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2194,7 +2266,7 @@ SolidityEvent.prototype.attachToContract = function (contract) { module.exports = SolidityEvent; -},{"../solidity/coder":2,"../utils/utils":8,"../web3":10,"./formatters":17}],16:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":6,"../web3":8,"./formatters":16}],15:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2351,7 +2423,7 @@ Filter.prototype.get = function (callback) { module.exports = Filter; -},{"../utils/utils":8,"./formatters":17,"./requestmanager":25}],17:[function(require,module,exports){ +},{"../utils/utils":6,"./formatters":16,"./requestmanager":24}],16:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2571,7 +2643,7 @@ module.exports = { }; -},{"../utils/config":7,"../utils/utils":8}],18:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":6}],17:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2588,7 +2660,7 @@ module.exports = { You should have received a copy of the GNU Lesser General Public License along with ethereum.js. If not, see . */ -/** +/** * @file function.js * @author Marek Kotewicz * @date 2015 @@ -2613,18 +2685,23 @@ var SolidityFunction = function (json, address) { this._address = address; }; +SolidityFunction.prototype.extractCallback = function (args) { + if (utils.isFunction(args[args.length - 1])) { + return args.pop(); // modify the args array! + } +}; + /** * Should be used to create payload from arguments * * @method toPayload - * @param {...} solidity function params + * @param {Array} solidity function params * @param {Object} optional payload options */ -SolidityFunction.prototype.toPayload = function () { - var args = Array.prototype.slice.call(arguments); +SolidityFunction.prototype.toPayload = function (args) { var options = {}; if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) { - options = args.pop(); + options = args[args.length - 1]; } options.to = this._address; options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args); @@ -2641,19 +2718,41 @@ SolidityFunction.prototype.signature = function () { return web3.sha3(web3.fromAscii(this._name)).slice(2, 10); }; + +SolidityFunction.prototype.unpackOutput = function (output) { + if (output === null) { + return; + } + + output = output.length >= 2 ? output.slice(2) : output; + var result = coder.decodeParams(this._outputTypes, output); + return result.length === 1 ? result[0] : result; +}; + /** - * Should be used to call function - * + * Calls a contract function. + * * @method call - * @param {Object} options + * @param {...Object} Contract function arguments + * @param {function} If the last argument is a function, the contract function + * call will be asynchronous, and the callback will be passed the + * error and result. * @return {String} output bytes */ SolidityFunction.prototype.call = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - var output = web3.eth.call(payload); - output = output.length >= 2 ? output.slice(2) : output; - var result = coder.decodeParams(this._outputTypes, output); - return result.length === 1 ? result[0] : result; + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + var output = web3.eth.call(payload); + return this.unpackOutput(output); + } + + var self = this; + web3.eth.call(payload, function (error, output) { + callback(error, self.unpackOutput(output)); + }); }; /** @@ -2663,8 +2762,16 @@ SolidityFunction.prototype.call = function () { * @param {Object} options */ SolidityFunction.prototype.sendTransaction = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - web3.eth.sendTransaction(payload); + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + web3.eth.sendTransaction(payload); + return; + } + + web3.eth.sendTransaction(payload, callback); }; /** @@ -2679,7 +2786,7 @@ SolidityFunction.prototype.displayName = function () { /** * Should be used to get function type name - * + * * @method typeName * @return {String} type name of the function */ @@ -2687,6 +2794,25 @@ SolidityFunction.prototype.typeName = function () { return utils.extractTypeName(this._name); }; +/** + * Should be called to get rpc requests from solidity function + * + * @method request + * @returns {Object} + */ +SolidityFunction.prototype.request = function () { + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + var format = this.unpackOutput.bind(this); + + return { + callback: callback, + payload: payload, + format: format + }; +}; + /** * Should be called to execute function * @@ -2694,7 +2820,7 @@ SolidityFunction.prototype.typeName = function () { */ SolidityFunction.prototype.execute = function () { var transaction = !this._constant; - + // send transaction if (transaction) { return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments)); @@ -2712,6 +2838,7 @@ SolidityFunction.prototype.execute = function () { */ SolidityFunction.prototype.attachToContract = function (contract) { var execute = this.execute.bind(this); + execute.request = this.request.bind(this); execute.call = this.call.bind(this); execute.sendTransaction = this.sendTransaction.bind(this); var displayName = this.displayName(); @@ -2724,7 +2851,7 @@ SolidityFunction.prototype.attachToContract = function (contract) { module.exports = SolidityFunction; -},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":6,"../web3":8}],18:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2816,7 +2943,7 @@ HttpProvider.prototype.sendAsync = function (payload, callback) { module.exports = HttpProvider; -},{"./errors":13,"xmlhttprequest":6}],20:[function(require,module,exports){ +},{"./errors":12,"xmlhttprequest":4}],19:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2909,7 +3036,7 @@ Jsonrpc.prototype.toBatchPayload = function (messages) { module.exports = Jsonrpc; -},{}],21:[function(require,module,exports){ +},{}],20:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2966,7 +3093,6 @@ Method.prototype.extractCallback = function (args) { if (utils.isFunction(args[args.length - 1])) { return args.pop(); // modify the args array! } - return null; }; /** @@ -3019,6 +3145,7 @@ Method.prototype.formatOutput = function (result) { */ Method.prototype.attachToObject = function (obj) { var func = this.send.bind(this); + func.request = this.request.bind(this); func.call = this.call; // that's ugly. filter.js uses it var name = this.name.split('.'); if (name.length > 1) { @@ -3049,6 +3176,19 @@ Method.prototype.toPayload = function (args) { }; }; +/** + * Should be called to create pure JSONRPC request which can be used in batch request + * + * @method request + * @param {...} params + * @return {Object} jsonrpc request + */ +Method.prototype.request = function () { + var payload = this.toPayload(Array.prototype.slice.call(arguments)); + payload.format = this.formatOutput.bind(this); + return payload; +}; + /** * Should send request to the API * @@ -3061,7 +3201,7 @@ Method.prototype.send = function () { if (payload.callback) { var self = this; return RequestManager.getInstance().sendAsync(payload, function (err, result) { - payload.callback(null, self.formatOutput(result)); + payload.callback(err, self.formatOutput(result)); }); } return this.formatOutput(RequestManager.getInstance().send(payload)); @@ -3070,7 +3210,7 @@ Method.prototype.send = function () { module.exports = Method; -},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(require,module,exports){ +},{"../utils/utils":6,"./errors":12,"./requestmanager":24}],21:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3120,7 +3260,7 @@ module.exports = { }; -},{"../utils/utils":8,"./property":23}],23:[function(require,module,exports){ +},{"../utils/utils":6,"./property":22}],22:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3186,16 +3326,23 @@ Property.prototype.formatOutput = function (result) { Property.prototype.attachToObject = function (obj) { var proto = { get: this.get.bind(this), - set: this.set.bind(this) }; - var name = this.name.split('.'); - if (name.length > 1) { - obj[name[0]] = obj[name[0]] || {}; - Object.defineProperty(obj[name[0]], name[1], proto); - } else { - Object.defineProperty(obj, name[0], proto); + var names = this.name.split('.'); + var name = names[0]; + if (names.length > 1) { + obj[names[0]] = obj[names[0]] || {}; + obj = obj[names[0]]; + name = names[1]; } + + Object.defineProperty(obj, name, proto); + + var toAsyncName = function (prefix, name) { + return prefix + name.charAt(0).toUpperCase() + name.slice(1); + }; + + obj[toAsyncName('get', name)] = this.getAsync.bind(this); }; /** @@ -3211,22 +3358,27 @@ Property.prototype.get = function () { }; /** - * Should be used to set value of the property + * Should be used to asynchrounously get value of property * - * @method set - * @param {Object} new value of the property + * @method getAsync + * @param {Function} */ -Property.prototype.set = function (value) { - return RequestManager.getInstance().send({ - method: this.setter, - params: [this.formatInput(value)] +Property.prototype.getAsync = function (callback) { + var self = this; + RequestManager.getInstance().sendAsync({ + method: this.getter + }, function (err, result) { + if (err) { + return callback(err); + } + callback(err, self.formatOutput(result)); }); }; module.exports = Property; -},{"./requestmanager":25}],24:[function(require,module,exports){ +},{"./requestmanager":24}],23:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3261,7 +3413,7 @@ QtSyncProvider.prototype.send = function (payload) { module.exports = QtSyncProvider; -},{}],25:[function(require,module,exports){ +},{}],24:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3369,6 +3521,33 @@ RequestManager.prototype.sendAsync = function (data, callback) { }); }; +/** + * Should be called to asynchronously send batch request + * + * @method sendBatch + * @param {Array} batch data + * @param {Function} callback + */ +RequestManager.prototype.sendBatch = function (data, callback) { + if (!this.provider) { + return callback(errors.InvalidProvider()); + } + + var payload = Jsonrpc.getInstance().toBatchPayload(data); + + this.provider.sendAsync(payload, function (err, results) { + if (err) { + return callback(err); + } + + if (!utils.isArray(results)) { + return callback(errors.InvalidResponse(results)); + } + + callback(err, results); + }); +}; + /** * Should be used to set provider of request manager * @@ -3482,7 +3661,7 @@ RequestManager.prototype.poll = function () { module.exports = RequestManager; -},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":6,"./errors":12,"./jsonrpc":19}],25:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3552,7 +3731,7 @@ module.exports = { }; -},{"./formatters":17,"./method":21}],27:[function(require,module,exports){ +},{"./formatters":16,"./method":20}],26:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3580,7 +3759,20 @@ var Method = require('./method'); /// @returns an array of objects describing web3.eth.filter api methods var eth = function () { var newFilterCall = function (args) { - return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter'; + var type = args[0]; + + switch(type) { + case 'latest': + args.pop(); + this.params = 0; + return 'eth_newBlockFilter'; + case 'pending': + args.pop(); + this.params = 0; + return 'eth_newPendingTransactionFilter'; + default: + return 'eth_newFilter'; + } }; var newFilter = new Method({ @@ -3655,7 +3847,7 @@ module.exports = { }; -},{"./method":21}],28:[function(require,module,exports){ +},{"./method":20}],27:[function(require,module,exports){ },{}],"bignumber.js":[function(require,module,exports){ /*! bignumber.js v2.0.7 https://github.com/MikeMcl/bignumber.js/LICENCE */ @@ -6342,12 +6534,11 @@ module.exports = { } })(this); -},{"crypto":28}],"web3":[function(require,module,exports){ +},{"crypto":27}],"web3":[function(require,module,exports){ var web3 = require('./lib/web3'); web3.providers.HttpProvider = require('./lib/web3/httpprovider'); web3.providers.QtSyncProvider = require('./lib/web3/qtsync'); web3.eth.contract = require('./lib/web3/contract'); -web3.abi = require('./lib/solidity/abi'); // dont override global variable if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { @@ -6357,7 +6548,7 @@ if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { module.exports = web3; -},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]) +},{"./lib/web3":8,"./lib/web3/contract":10,"./lib/web3/httpprovider":18,"./lib/web3/qtsync":23}]},{},["web3"]) //# sourceMappingURL=web3.js.map \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/web3.js.map b/libjsqrc/ethereumjs/dist/web3.js.map index 4efb07df1..e25fa3aed 100644 --- a/libjsqrc/ethereumjs/dist/web3.js.map +++ b/libjsqrc/ethereumjs/dist/web3.js.map @@ -2,16 +2,15 @@ "version": 3, "sources": [ "node_modules/browserify/node_modules/browser-pack/_prelude.js", - "lib/solidity/abi.js", "lib/solidity/coder.js", "lib/solidity/formatters.js", "lib/solidity/param.js", - "lib/solidity/utils.js", "lib/utils/browser-xhr.js", "lib/utils/config.js", "lib/utils/utils.js", "lib/version.json", "lib/web3.js", + "lib/web3/batch.js", "lib/web3/contract.js", "lib/web3/db.js", "lib/web3/errors.js", @@ -34,40 +33,39 @@ "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;;AC5CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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/JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrGA;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3nFA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClNA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3dA;AACA;AACA;AACA;;ACHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClHA;;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3nFA;AACA;AACA;AACA;AACA;AACA;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/** \n * @file abi.js\n * @author Marek Kotewicz \n * @author Gav Wood \n * @date 2014\n */\n\nvar coder = require('./coder');\nvar utils = require('./utils');\n\nvar formatConstructorParams = function (abi, params) {\n var constructor = utils.getConstructor(abi, params.length);\n if (!constructor) {\n if (params.length > 0) {\n console.warn(\"didn't found matching constructor, using default one\");\n }\n return '';\n }\n\n return coder.encodeParams(constructor.inputs.map(function (input) {\n return input.type;\n }), params);\n};\n\nmodule.exports = {\n formatConstructorParams: formatConstructorParams\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/** \n * @file coder.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar f = require('./formatters');\nvar SolidityParam = require('./param');\n\n/**\n * Should be used to check if a type is an array type\n *\n * @method isArrayType\n * @param {String} type\n * @return {Bool} true is the type is an array, otherwise false\n */\nvar isArrayType = function (type) {\n return type.slice(-2) === '[]';\n};\n\n/**\n * SolidityType prototype is used to encode/decode solidity params of certain type\n */\nvar SolidityType = function (config) {\n this._name = config.name;\n this._match = config.match;\n this._mode = config.mode;\n this._inputFormatter = config.inputFormatter;\n this._outputFormatter = config.outputFormatter;\n};\n\n/**\n * Should be used to determine if this SolidityType do match given type\n *\n * @method isType\n * @param {String} name\n * @return {Bool} true if type match this SolidityType, otherwise false\n */\nSolidityType.prototype.isType = function (name) {\n if (this._match === 'strict') {\n return this._name === name || (name.indexOf(this._name) === 0 && name.slice(this._name.length) === '[]');\n } else if (this._match === 'prefix') {\n // TODO better type detection!\n return name.indexOf(this._name) === 0;\n }\n};\n\n/**\n * Should be used to transform plain param to SolidityParam object\n *\n * @method formatInput\n * @param {Object} param - plain object, or an array of objects\n * @param {Bool} arrayType - true if a param should be encoded as an array\n * @return {SolidityParam} encoded param wrapped in SolidityParam object \n */\nSolidityType.prototype.formatInput = function (param, arrayType) {\n if (utils.isArray(param) && arrayType) { // TODO: should fail if this two are not the same\n var self = this;\n return param.map(function (p) {\n return self._inputFormatter(p);\n }).reduce(function (acc, current) {\n return acc.combine(current);\n }, f.formatInputInt(param.length)).withOffset(32);\n } \n return this._inputFormatter(param);\n};\n\n/**\n * Should be used to transoform SolidityParam to plain param\n *\n * @method formatOutput\n * @param {SolidityParam} byteArray\n * @param {Bool} arrayType - true if a param should be decoded as an array\n * @return {Object} plain decoded param\n */\nSolidityType.prototype.formatOutput = function (param, arrayType) {\n if (arrayType) {\n // let's assume, that we solidity will never return long arrays :P \n var result = [];\n var length = new BigNumber(param.dynamicPart().slice(0, 64), 16);\n for (var i = 0; i < length * 64; i += 64) {\n result.push(this._outputFormatter(new SolidityParam(param.dynamicPart().substr(i + 64, 64))));\n }\n return result;\n }\n return this._outputFormatter(param);\n};\n\n/**\n * Should be used to slice single param from bytes\n *\n * @method sliceParam\n * @param {String} bytes\n * @param {Number} index of param to slice\n * @param {String} type\n * @returns {SolidityParam} param\n */\nSolidityType.prototype.sliceParam = function (bytes, index, type) {\n if (this._mode === 'bytes') {\n return SolidityParam.decodeBytes(bytes, index);\n } else if (isArrayType(type)) {\n return SolidityParam.decodeArray(bytes, index);\n }\n return SolidityParam.decodeParam(bytes, index);\n};\n\n/**\n * SolidityCoder prototype should be used to encode/decode solidity params of any type\n */\nvar SolidityCoder = function (types) {\n this._types = types;\n};\n\n/**\n * This method should be used to transform type to SolidityType\n *\n * @method _requireType\n * @param {String} type\n * @returns {SolidityType} \n * @throws {Error} throws if no matching type is found\n */\nSolidityCoder.prototype._requireType = function (type) {\n var solidityType = this._types.filter(function (t) {\n return t.isType(type);\n })[0];\n\n if (!solidityType) {\n throw Error('invalid solidity type!: ' + type);\n }\n\n return solidityType;\n};\n\n/**\n * Should be used to transform plain param of given type to SolidityParam\n *\n * @method _formatInput\n * @param {String} type of param\n * @param {Object} plain param\n * @return {SolidityParam}\n */\nSolidityCoder.prototype._formatInput = function (type, param) {\n return this._requireType(type).formatInput(param, isArrayType(type));\n};\n\n/**\n * Should be used to encode plain param\n *\n * @method encodeParam\n * @param {String} type\n * @param {Object} plain param\n * @return {String} encoded plain param\n */\nSolidityCoder.prototype.encodeParam = function (type, param) {\n return this._formatInput(type, param).encode();\n};\n\n/**\n * Should be used to encode list of params\n *\n * @method encodeParams\n * @param {Array} types\n * @param {Array} params\n * @return {String} encoded list of params\n */\nSolidityCoder.prototype.encodeParams = function (types, params) {\n var self = this;\n var solidityParams = types.map(function (type, index) {\n return self._formatInput(type, params[index]);\n });\n\n return SolidityParam.encodeList(solidityParams);\n};\n\n/**\n * Should be used to decode bytes to plain param\n *\n * @method decodeParam\n * @param {String} type\n * @param {String} bytes\n * @return {Object} plain param\n */\nSolidityCoder.prototype.decodeParam = function (type, bytes) {\n return this.decodeParams([type], bytes)[0];\n};\n\n/**\n * Should be used to decode list of params\n *\n * @method decodeParam\n * @param {Array} types\n * @param {String} bytes\n * @return {Array} array of plain params\n */\nSolidityCoder.prototype.decodeParams = function (types, bytes) {\n var self = this;\n return types.map(function (type, index) {\n var solidityType = self._requireType(type);\n var p = solidityType.sliceParam(bytes, index, type);\n return solidityType.formatOutput(p, isArrayType(type));\n });\n};\n\nvar coder = new SolidityCoder([\n new SolidityType({\n name: 'address',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputAddress\n }),\n new SolidityType({\n name: 'bool',\n match: 'strict',\n mode: 'value',\n inputFormatter: f.formatInputBool,\n outputFormatter: f.formatOutputBool\n }),\n new SolidityType({\n name: 'int',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputInt,\n }),\n new SolidityType({\n name: 'uint',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputInt,\n outputFormatter: f.formatOutputUInt\n }),\n new SolidityType({\n name: 'bytes',\n match: 'strict',\n mode: 'bytes',\n inputFormatter: f.formatInputDynamicBytes,\n outputFormatter: f.formatOutputDynamicBytes\n }),\n new SolidityType({\n name: 'bytes',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputBytes,\n outputFormatter: f.formatOutputBytes\n }),\n new SolidityType({\n name: 'real',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputReal\n }),\n new SolidityType({\n name: 'ureal',\n match: 'prefix',\n mode: 'value',\n inputFormatter: f.formatInputReal,\n outputFormatter: f.formatOutputUReal\n })\n]);\n\nmodule.exports = coder;\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/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar BigNumber = require('bignumber.js');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar SolidityParam = require('./param');\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 {SolidityParam}\n */\nvar formatInputInt = function (value) {\n var padding = c.ETH_PADDING * 2;\n BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);\n var result = utils.padLeft(utils.toTwosComplement(value).round().toString(16), padding);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputDynamicBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputDynamicBytes = function (value) {\n var result = utils.fromAscii(value, c.ETH_PADDING).substr(2);\n return new SolidityParam(formatInputInt(value.length).value + result, 32);\n};\n\n/**\n * Formats input value to byte representation of bool\n *\n * @method formatInputBool\n * @param {Boolean}\n * @returns {SolidityParam}\n */\nvar formatInputBool = function (value) {\n var result = '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n return new SolidityParam(result);\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 {SolidityParam}\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 {SolidityParam} param\n * @returns {BigNumber} right-aligned output bytes formatted to big number\n */\nvar formatOutputInt = function (param) {\n var value = param.staticPart() || \"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 {SolidityParam}\n * @returns {BigNumeber} right-aligned output bytes formatted to uint\n */\nvar formatOutputUInt = function (param) {\n var value = param.staticPart() || \"0\";\n return new BigNumber(value, 16);\n};\n\n/**\n * Formats right-aligned output bytes to real\n *\n * @method formatOutputReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to real\n */\nvar formatOutputReal = function (param) {\n return formatOutputInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Formats right-aligned output bytes to ureal\n *\n * @method formatOutputUReal\n * @param {SolidityParam}\n * @returns {BigNumber} input bytes formatted to ureal\n */\nvar formatOutputUReal = function (param) {\n return formatOutputUInt(param).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/**\n * Should be used to format output bool\n *\n * @method formatOutputBool\n * @param {SolidityParam}\n * @returns {Boolean} right-aligned input bytes formatted to bool\n */\nvar formatOutputBool = function (param) {\n return param.staticPart() === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.staticPart());\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputDynamicBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputDynamicBytes = function (param) {\n // length might also be important!\n return utils.toAscii(param.dynamicPart().slice(64));\n};\n\n/**\n * Should be used to format output address\n *\n * @method formatOutputAddress\n * @param {SolidityParam} right-aligned input bytes\n * @returns {String} address\n */\nvar formatOutputAddress = function (param) {\n var value = param.staticPart();\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nmodule.exports = {\n formatInputInt: formatInputInt,\n formatInputBytes: formatInputBytes,\n formatInputDynamicBytes: formatInputDynamicBytes,\n formatInputBool: formatInputBool,\n formatInputReal: formatInputReal,\n formatOutputInt: formatOutputInt,\n formatOutputUInt: formatOutputUInt,\n formatOutputReal: formatOutputReal,\n formatOutputUReal: formatOutputUReal,\n formatOutputBool: formatOutputBool,\n formatOutputBytes: formatOutputBytes,\n formatOutputDynamicBytes: formatOutputDynamicBytes,\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/** \n * @file param.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * SolidityParam object prototype.\n * Should be used when encoding, decoding solidity bytes\n */\nvar SolidityParam = function (value, offset) {\n this.value = value || '';\n this.offset = offset; // offset in bytes\n};\n\n/**\n * This method should be used to get length of params's dynamic part\n * \n * @method dynamicPartLength\n * @returns {Number} length of dynamic part (in bytes)\n */\nSolidityParam.prototype.dynamicPartLength = function () {\n return this.dynamicPart().length / 2;\n};\n\n/**\n * This method should be used to create copy of solidity param with different offset\n *\n * @method withOffset\n * @param {Number} offset length in bytes\n * @returns {SolidityParam} new solidity param with applied offset\n */\nSolidityParam.prototype.withOffset = function (offset) {\n return new SolidityParam(this.value, offset);\n};\n\n/**\n * This method should be used to combine solidity params together\n * eg. when appending an array\n *\n * @method combine\n * @param {SolidityParam} param with which we should combine\n * @param {SolidityParam} result of combination\n */\nSolidityParam.prototype.combine = function (param) {\n return new SolidityParam(this.value + param.value); \n};\n\n/**\n * This method should be called to check if param has dynamic size.\n * If it has, it returns true, otherwise false\n *\n * @method isDynamic\n * @returns {Boolean}\n */\nSolidityParam.prototype.isDynamic = function () {\n return this.value.length > 64;\n};\n\n/**\n * This method should be called to transform offset to bytes\n *\n * @method offsetAsBytes\n * @returns {String} bytes representation of offset\n */\nSolidityParam.prototype.offsetAsBytes = function () {\n return !this.isDynamic() ? '' : utils.padLeft(utils.toTwosComplement(this.offset).toString(16), 64);\n};\n\n/**\n * This method should be called to get static part of param\n *\n * @method staticPart\n * @returns {String} offset if it is a dynamic param, otherwise value\n */\nSolidityParam.prototype.staticPart = function () {\n if (!this.isDynamic()) {\n return this.value; \n } \n return this.offsetAsBytes();\n};\n\n/**\n * This method should be called to get dynamic part of param\n *\n * @method dynamicPart\n * @returns {String} returns a value if it is a dynamic param, otherwise empty string\n */\nSolidityParam.prototype.dynamicPart = function () {\n return this.isDynamic() ? this.value : '';\n};\n\n/**\n * This method should be called to encode param\n *\n * @method encode\n * @returns {String}\n */\nSolidityParam.prototype.encode = function () {\n return this.staticPart() + this.dynamicPart();\n};\n\n/**\n * This method should be called to encode array of params\n *\n * @method encodeList\n * @param {Array[SolidityParam]} params\n * @returns {String}\n */\nSolidityParam.encodeList = function (params) {\n \n // updating offsets\n var totalOffset = params.length * 32;\n var offsetParams = params.map(function (param) {\n if (!param.isDynamic()) {\n return param;\n }\n var offset = totalOffset;\n totalOffset += param.dynamicPartLength();\n return param.withOffset(offset);\n });\n\n // encode everything!\n return offsetParams.reduce(function (result, param) {\n return result + param.dynamicPart();\n }, offsetParams.reduce(function (result, param) {\n return result + param.staticPart();\n }, ''));\n};\n\n/**\n * This method should be used to decode plain (static) solidity param at given index\n *\n * @method decodeParam\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeParam = function (bytes, index) {\n index = index || 0;\n return new SolidityParam(bytes.substr(index * 64, 64)); \n};\n\n/**\n * This method should be called to get offset value from bytes at given index\n *\n * @method getOffset\n * @param {String} bytes\n * @param {Number} index\n * @returns {Number} offset as number\n */\nvar getOffset = function (bytes, index) {\n // we can do this cause offset is rather small\n return parseInt('0x' + bytes.substr(index * 64, 64));\n};\n\n/**\n * This method should be called to decode solidity bytes param at given index\n *\n * @method decodeBytes\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeBytes = function (bytes, index) {\n index = index || 0;\n //TODO add support for strings longer than 32 bytes\n //var length = parseInt('0x' + bytes.substr(offset * 64, 64));\n\n var offset = getOffset(bytes, index);\n\n // 2 * , cause we also parse length\n return new SolidityParam(bytes.substr(offset * 2, 2 * 64));\n};\n\n/**\n * This method should be used to decode solidity array at given index\n *\n * @method decodeArray\n * @param {String} bytes\n * @param {Number} index\n * @returns {SolidityParam}\n */\nSolidityParam.decodeArray = function (bytes, index) {\n index = index || 0;\n var offset = getOffset(bytes, index);\n var length = parseInt('0x' + bytes.substr(offset * 2, 64));\n return new SolidityParam(bytes.substr(offset * 2, (length + 1) * 64));\n};\n\nmodule.exports = SolidityParam;\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/**\n * @file utils.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\n/**\n * Returns the contstructor with matching number of arguments\n *\n * @method getConstructor\n * @param {Array} abi\n * @param {Number} numberOfArgs\n * @returns {Object} constructor function abi\n */\nvar getConstructor = function (abi, numberOfArgs) {\n return abi.filter(function (f) {\n return f.type === 'constructor' && f.inputs.length === numberOfArgs;\n })[0];\n};\n\n//var getSupremeType = function (type) {\n //return type.substr(0, type.indexOf('[')) + ']';\n//};\n\n\nmodule.exports = {\n getConstructor: getConstructor\n};\n\n", "'use strict';\n\n// go env doesn't have and need XMLHttpRequest\nif (typeof XMLHttpRequest === 'undefined') {\n exports.XMLHttpRequest = {};\n} else {\n exports.XMLHttpRequest = XMLHttpRequest; // jshint ignore:line\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\nvar BigNumber = require('bignumber.js');\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 defaultBlock: 'latest',\n defaultAccount: undefined\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/** \n * @file utils.js\n * @author 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\nvar BigNumber = require('bignumber.js');\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 * 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 * 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 toHexNative\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 used to create full function/event name from json abi\n *\n * @method transformToFullName\n * @param {Object} json-abi\n * @return {String} full fnction/event name\n */\nvar transformToFullName = function (json) {\n if (json.name.indexOf('(') !== -1) {\n return json.name;\n }\n\n var typeName = json.inputs.map(function(i){return i.type; }).join();\n return json.name + '(' + typeName + ')';\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 * 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 fromDecimal(+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 is strictly an address\n *\n * @method isStrictAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isStrictAddress = function (address) {\n return /^0x[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Checks if the given string is an address\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function (address) {\n return /^(0x)?[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Transforms given string to valid 20 bytes-length addres with 0x prefix\n *\n * @method toAddress\n * @param {String} address\n * @return {String} formatted address\n */\nvar toAddress = function (address) {\n if (isStrictAddress(address)) {\n return address;\n }\n \n if (/^[0-9a-f]{40}$/.test(address)) {\n return '0x' + address;\n }\n\n return '0x' + padLeft(toHex(address).substr(2), 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\n/**\n * Returns true if given string is valid json object\n * \n * @method isJson\n * @param {String}\n * @return {Boolean}\n */\nvar isJson = function (str) {\n try {\n return !!JSON.parse(str);\n } catch (e) {\n return false;\n }\n};\n\nmodule.exports = {\n padLeft: padLeft,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n transformToFullName: transformToFullName,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n toAddress: toAddress,\n isBigNumber: isBigNumber,\n isStrictAddress: isStrictAddress,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray,\n isJson: isJson\n};\n\n", - "module.exports={\n \"version\": \"0.3.6\"\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('./web3/formatters');\nvar RequestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\nvar Method = require('./web3/method');\nvar Property = require('./web3/property');\n\nvar web3Methods = [\n new Method({\n name: 'sha3',\n call: 'web3_sha3',\n params: 1\n })\n];\n\nvar web3Properties = [\n new Property({\n name: 'version.client',\n getter: 'web3_clientVersion'\n }),\n new Property({\n name: 'version.network',\n getter: 'net_version',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.ethereum',\n getter: 'eth_protocolVersion',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.whisper',\n getter: 'shh_version',\n inputFormatter: utils.toDecimal\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 method.attachToObject(obj);\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 property.attachToObject(obj);\n });\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {};\nweb3.providers = {};\nweb3.version = {};\nweb3.version.api = version.version;\nweb3.eth = {};\n\n/*jshint maxparams:4 */\nweb3.eth.filter = function (fil, eventParams, options, formatter) {\n\n // if its event, treat it differently\n // TODO: simplify and remove\n if (fil._isEvent) {\n return fil(eventParams, options);\n }\n\n // what outputLogFormatter? that's wrong\n //return new Filter(fil, watches.eth(), formatters.outputLogFormatter);\n return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter);\n};\n/*jshint maxparams:3 */\n\nweb3.shh = {};\nweb3.shh.filter = function (fil) {\n return new Filter(fil, watches.shh(), formatters.outputPostFormatter);\n};\nweb3.net = {};\nweb3.db = {};\nweb3.setProvider = function (provider) {\n RequestManager.getInstance().setProvider(provider);\n};\nweb3.reset = function () {\n RequestManager.getInstance().reset();\n c.defaultBlock = 'latest';\n c.defaultAccount = undefined;\n};\nweb3.toHex = utils.toHex;\nweb3.toAscii = utils.toAscii;\nweb3.fromAscii = utils.fromAscii;\nweb3.toDecimal = utils.toDecimal;\nweb3.fromDecimal = utils.fromDecimal;\nweb3.toBigNumber = utils.toBigNumber;\nweb3.toWei = utils.toWei;\nweb3.fromWei = utils.fromWei;\nweb3.isAddress = utils.isAddress;\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.defaultBlock;\n },\n set: function (val) {\n c.defaultBlock = val;\n return val;\n }\n});\n\nObject.defineProperty(web3.eth, 'defaultAccount', {\n get: function () {\n return c.defaultAccount;\n },\n set: function (val) {\n c.defaultAccount = val;\n return val;\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);\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/** \n * @file contract.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar solAbi = require('../solidity/abi');\nvar utils = require('../utils/utils');\nvar SolidityEvent = require('./event');\nvar SolidityFunction = require('./function');\n\nvar addFunctionsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'function';\n }).map(function (json) {\n return new SolidityFunction(json, contract.address);\n }).forEach(function (f) {\n f.attachToContract(contract);\n });\n};\n\nvar addEventsToContract = function (contract, desc) {\n desc.filter(function (json) {\n return json.type === 'event';\n }).map(function (json) {\n return new SolidityEvent(json, contract.address);\n }).forEach(function (e) {\n e.attachToContract(contract);\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 return Contract.bind(null, abi);\n};\n\nvar Contract = function (abi, options) {\n\n this.address = '';\n if (utils.isAddress(options)) {\n this.address = options;\n } else { // is an object!\n // TODO, parse the rest of the args\n options = options || {};\n var args = Array.prototype.slice.call(arguments, 2);\n var bytes = solAbi.formatConstructorParams(abi, args);\n options.data += bytes;\n this.address = web3.eth.sendTransaction(options);\n }\n\n addFunctionsToContract(this, abi);\n addEventsToContract(this, abi);\n};\n\nContract.prototype.call = function () {\n console.error('contract.call is deprecated');\n return this;\n};\n\nContract.prototype.sendTransaction = function () {\n console.error('contract.sendTransact is deprecated');\n return this;\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/** \n * @file utils.js\n * @author 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\nvar BigNumber = require('bignumber.js');\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 * 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 * 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 toHexNative\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 used to create full function/event name from json abi\n *\n * @method transformToFullName\n * @param {Object} json-abi\n * @return {String} full fnction/event name\n */\nvar transformToFullName = function (json) {\n if (json.name.indexOf('(') !== -1) {\n return json.name;\n }\n\n var typeName = json.inputs.map(function(i){return i.type; }).join();\n return json.name + '(' + typeName + ')';\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 * 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 fromDecimal(+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 is strictly an address\n *\n * @method isStrictAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isStrictAddress = function (address) {\n return /^0x[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Checks if the given string is an address\n *\n * @method isAddress\n * @param {String} address the given HEX adress\n * @return {Boolean}\n*/\nvar isAddress = function (address) {\n return /^(0x)?[0-9a-f]{40}$/.test(address);\n};\n\n/**\n * Transforms given string to valid 20 bytes-length addres with 0x prefix\n *\n * @method toAddress\n * @param {String} address\n * @return {String} formatted address\n */\nvar toAddress = function (address) {\n if (isStrictAddress(address)) {\n return address;\n }\n \n if (/^[0-9a-f]{40}$/.test(address)) {\n return '0x' + address;\n }\n\n return '0x' + padLeft(toHex(address).substr(2), 40);\n};\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\n/**\n * Returns true if given string is valid json object\n * \n * @method isJson\n * @param {String}\n * @return {Boolean}\n */\nvar isJson = function (str) {\n try {\n return !!JSON.parse(str);\n } catch (e) {\n return false;\n }\n};\n\nmodule.exports = {\n padLeft: padLeft,\n toHex: toHex,\n toDecimal: toDecimal,\n fromDecimal: fromDecimal,\n toAscii: toAscii,\n fromAscii: fromAscii,\n transformToFullName: transformToFullName,\n extractDisplayName: extractDisplayName,\n extractTypeName: extractTypeName,\n toWei: toWei,\n fromWei: fromWei,\n toBigNumber: toBigNumber,\n toTwosComplement: toTwosComplement,\n toAddress: toAddress,\n isBigNumber: isBigNumber,\n isStrictAddress: isStrictAddress,\n isAddress: isAddress,\n isFunction: isFunction,\n isString: isString,\n isObject: isObject,\n isBoolean: isBoolean,\n isArray: isArray,\n isJson: isJson\n};\n\n", + "module.exports={\n \"version\": \"0.4.2\"\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('./web3/formatters');\nvar RequestManager = require('./web3/requestmanager');\nvar c = require('./utils/config');\nvar Method = require('./web3/method');\nvar Property = require('./web3/property');\nvar Batch = require('./web3/batch');\n\nvar web3Methods = [\n new Method({\n name: 'sha3',\n call: 'web3_sha3',\n params: 1\n })\n];\n\nvar web3Properties = [\n new Property({\n name: 'version.client',\n getter: 'web3_clientVersion'\n }),\n new Property({\n name: 'version.network',\n getter: 'net_version',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.ethereum',\n getter: 'eth_protocolVersion',\n inputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'version.whisper',\n getter: 'shh_version',\n inputFormatter: utils.toDecimal\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 method.attachToObject(obj);\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 property.attachToObject(obj);\n });\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {};\nweb3.providers = {};\nweb3.version = {};\nweb3.version.api = version.version;\nweb3.eth = {};\n\n/*jshint maxparams:4 */\nweb3.eth.filter = function (fil, eventParams, options, formatter) {\n\n // if its event, treat it differently\n // TODO: simplify and remove\n if (fil._isEvent) {\n return fil(eventParams, options);\n }\n\n // what outputLogFormatter? that's wrong\n //return new Filter(fil, watches.eth(), formatters.outputLogFormatter);\n return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter);\n};\n/*jshint maxparams:3 */\n\nweb3.shh = {};\nweb3.shh.filter = function (fil) {\n return new Filter(fil, watches.shh(), formatters.outputPostFormatter);\n};\nweb3.net = {};\nweb3.db = {};\nweb3.setProvider = function (provider) {\n RequestManager.getInstance().setProvider(provider);\n};\nweb3.reset = function () {\n RequestManager.getInstance().reset();\n c.defaultBlock = 'latest';\n c.defaultAccount = undefined;\n};\nweb3.toHex = utils.toHex;\nweb3.toAscii = utils.toAscii;\nweb3.fromAscii = utils.fromAscii;\nweb3.toDecimal = utils.toDecimal;\nweb3.fromDecimal = utils.fromDecimal;\nweb3.toBigNumber = utils.toBigNumber;\nweb3.toWei = utils.toWei;\nweb3.fromWei = utils.fromWei;\nweb3.isAddress = utils.isAddress;\nweb3.createBatch = function () {\n return new Batch();\n};\n\n// ADD defaultblock\nObject.defineProperty(web3.eth, 'defaultBlock', {\n get: function () {\n return c.defaultBlock;\n },\n set: function (val) {\n c.defaultBlock = val;\n return val;\n }\n});\n\nObject.defineProperty(web3.eth, 'defaultAccount', {\n get: function () {\n return c.defaultAccount;\n },\n set: function (val) {\n c.defaultAccount = val;\n return val;\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);\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/** \n * @file batch.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\n\nvar Batch = function () {\n this.requests = [];\n};\n\n/**\n * Should be called to add create new request to batch request\n *\n * @method add\n * @param {Object} jsonrpc requet object\n */\nBatch.prototype.add = function (request) {\n this.requests.push(request);\n};\n\n/**\n * Should be called to execute batch request\n *\n * @method execute\n */\nBatch.prototype.execute = function () {\n var requests = this.requests;\n RequestManager.getInstance().sendBatch(requests, function (err, results) {\n results = results || [];\n requests.map(function (request, index) {\n return results[index] || {};\n }).map(function (result, index) {\n return requests[index].format ? requests[index].format(result.result) : result.result;\n }).forEach(function (result, index) {\n if (requests[index].callback) {\n requests[index].callback(err, result);\n }\n });\n }); \n};\n\nmodule.exports = Batch;\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/** \n * @file contract.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('../web3'); \nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar SolidityEvent = require('./event');\nvar SolidityFunction = require('./function');\n\n/**\n * Should be called to encode constructor params\n *\n * @method encodeConstructorParams\n * @param {Array} abi\n * @param {Array} constructor params\n */\nvar encodeConstructorParams = function (abi, params) {\n return abi.filter(function (json) {\n return json.type === 'constructor' && json.inputs.length === params.length;\n }).map(function (json) {\n return json.inputs.map(function (input) {\n return input.type;\n });\n }).map(function (types) {\n return coder.encodeParams(types, params);\n })[0] || '';\n};\n\n/**\n * Should be called to add functions to contract object\n *\n * @method addFunctionsToContract\n * @param {Contract} contract\n * @param {Array} abi\n */\nvar addFunctionsToContract = function (contract, abi) {\n abi.filter(function (json) {\n return json.type === 'function';\n }).map(function (json) {\n return new SolidityFunction(json, contract.address);\n }).forEach(function (f) {\n f.attachToContract(contract);\n });\n};\n\n/**\n * Should be called to add events to contract object\n *\n * @method addEventsToContract\n * @param {Contract} contract\n * @param {Array} abi\n */\nvar addEventsToContract = function (contract, abi) {\n abi.filter(function (json) {\n return json.type === 'event';\n }).map(function (json) {\n return new SolidityEvent(json, contract.address);\n }).forEach(function (e) {\n e.attachToContract(contract);\n });\n};\n\n/**\n * Should be called to create new ContractFactory\n *\n * @method contract\n * @param {Array} abi\n * @returns {ContractFactory} new contract factory\n */\nvar contract = function (abi) {\n return new ContractFactory(abi);\n};\n\n/**\n * Should be called to create new ContractFactory instance\n *\n * @method ContractFactory\n * @param {Array} abi\n */\nvar ContractFactory = function (abi) {\n this.abi = abi;\n};\n\n/**\n * Should be called to create new contract on a blockchain\n * \n * @method new\n * @param {Any} contract constructor param1 (optional)\n * @param {Any} contract constructor param2 (optional)\n * @param {Object} contract transaction object (required)\n * @param {Function} callback\n * @returns {Contract} returns contract if no callback was passed,\n * otherwise calls callback function (err, contract)\n */\nContractFactory.prototype.new = function () {\n // parse arguments\n var options = {}; // required!\n var callback;\n\n var args = Array.prototype.slice.call(arguments);\n if (utils.isFunction(args[args.length - 1])) {\n callback = args.pop();\n }\n\n var last = args[args.length - 1];\n if (utils.isObject(last) && !utils.isArray(last)) {\n options = args.pop();\n }\n\n // throw an error if there are no options\n\n var bytes = encodeConstructorParams(this.abi, args);\n options.data += bytes;\n\n if (!callback) {\n var address = web3.eth.sendTransaction(options);\n return this.at(address);\n }\n \n var self = this;\n web3.eth.sendTransaction(options, function (err, address) {\n if (err) {\n callback(err);\n }\n self.at(address, callback); \n }); \n};\n\n/**\n * Should be called to get access to existing contract on a blockchain\n *\n * @method at\n * @param {Address} contract address (required)\n * @param {Function} callback {optional)\n * @returns {Contract} returns contract if no callback was passed,\n * otherwise calls callback function (err, contract)\n */\nContractFactory.prototype.at = function (address, callback) {\n // TODO: address is required\n \n if (callback) {\n callback(null, new Contract(this.abi, address));\n } \n return new Contract(this.abi, address);\n};\n\n/**\n * Should be called to create new contract instance\n *\n * @method Contract\n * @param {Array} abi\n * @param {Address} contract address\n */\nvar Contract = function (abi, address) {\n this.address = address;\n addFunctionsToContract(this, abi);\n addEventsToContract(this, abi);\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\nvar Method = require('./method');\n\nvar putString = new Method({\n name: 'putString',\n call: 'db_putString',\n params: 3\n});\n\n\nvar getString = new Method({\n name: 'getString',\n call: 'db_getString',\n params: 2\n});\n\nvar putHex = new Method({\n name: 'putHex',\n call: 'db_putHex',\n params: 3\n});\n\nvar getHex = new Method({\n name: 'getHex',\n call: 'db_getHex',\n params: 2\n});\n\nvar methods = [\n putString, getString, putHex, getHex\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/** \n * @file errors.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nmodule.exports = {\n InvalidNumberOfParams: function () {\n return new Error('Invalid number of input parameters');\n },\n InvalidConnection: function (host){\n return new Error('CONNECTION ERROR: Couldn\\'t connect to node '+ host +', is it running?');\n },\n InvalidProvider: function () {\n return new Error('Providor not set or invalid');\n },\n InvalidResponse: function (result){\n var message = !!result && !!result.error && !!result.error.message ? result.error.message : 'Invalid JSON RPC response';\n return new Error(message);\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/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author 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 * params: 2,\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){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\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\n\nvar getBalance = new Method({\n name: 'getBalance',\n call: 'eth_getBalance',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt',\n call: 'eth_getStorageAt',\n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock',\n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'hashrate',\n getter: 'eth_hashrate',\n outputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n 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/**\n * @file eth.js\n * @author Marek Kotewicz \n * @author 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 * params: 2,\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){ return !!param; } // formats paramter 2\n * ]\n * },\n *\n * @class [web3] eth\n * @constructor\n */\n\n\"use strict\";\n\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Method = require('./method');\nvar Property = require('./property');\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\n\nvar getBalance = new Method({\n name: 'getBalance',\n call: 'eth_getBalance',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: formatters.outputBigNumberFormatter\n});\n\nvar getStorageAt = new Method({\n name: 'getStorageAt',\n call: 'eth_getStorageAt',\n params: 3,\n inputFormatter: [null, utils.toHex, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getCode = new Method({\n name: 'getCode',\n call: 'eth_getCode',\n params: 2,\n inputFormatter: [utils.toAddress, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar getBlock = new Method({\n name: 'getBlock',\n call: blockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, function (val) { return !!val; }],\n outputFormatter: formatters.outputBlockFormatter\n});\n\nvar getUncle = new Method({\n name: 'getUncle',\n call: uncleCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputBlockFormatter,\n\n});\n\nvar getCompilers = new Method({\n name: 'getCompilers',\n call: 'eth_getCompilers',\n params: 0\n});\n\nvar getBlockTransactionCount = new Method({\n name: 'getBlockTransactionCount',\n call: getBlockTransactionCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getBlockUncleCount = new Method({\n name: 'getBlockUncleCount',\n call: uncleCountCall,\n params: 1,\n inputFormatter: [formatters.inputBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar getTransaction = new Method({\n name: 'getTransaction',\n call: 'eth_getTransactionByHash',\n params: 1,\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionFromBlock = new Method({\n name: 'getTransactionFromBlock',\n call: transactionFromBlockCall,\n params: 2,\n inputFormatter: [formatters.inputBlockNumberFormatter, utils.toHex],\n outputFormatter: formatters.outputTransactionFormatter\n});\n\nvar getTransactionCount = new Method({\n name: 'getTransactionCount',\n call: 'eth_getTransactionCount',\n params: 2,\n inputFormatter: [null, formatters.inputDefaultBlockNumberFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar sendTransaction = new Method({\n name: 'sendTransaction',\n call: 'eth_sendTransaction',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter]\n});\n\nvar call = new Method({\n name: 'call',\n call: 'eth_call',\n params: 2,\n inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter]\n});\n\nvar estimateGas = new Method({\n name: 'estimateGas',\n call: 'eth_estimateGas',\n params: 1,\n inputFormatter: [formatters.inputTransactionFormatter],\n outputFormatter: utils.toDecimal\n});\n\nvar compileSolidity = new Method({\n name: 'compile.solidity',\n call: 'eth_compileSolidity',\n params: 1\n});\n\nvar compileLLL = new Method({\n name: 'compile.lll',\n call: 'eth_compileLLL',\n params: 1\n});\n\nvar compileSerpent = new Method({\n name: 'compile.serpent',\n call: 'eth_compileSerpent',\n params: 1\n});\n\nvar submitWork = new Method({\n name: 'submitWork',\n call: 'eth_submitWork',\n params: 3\n});\n\nvar getWork = new Method({\n name: 'getWork',\n call: 'eth_getWork',\n params: 0\n});\n\nvar methods = [\n getBalance,\n getStorageAt,\n getCode,\n getBlock,\n getUncle,\n getCompilers,\n getBlockTransactionCount,\n getBlockUncleCount,\n getTransaction,\n getTransactionFromBlock,\n getTransactionCount,\n call,\n estimateGas,\n sendTransaction,\n compileSolidity,\n compileLLL,\n compileSerpent,\n submitWork,\n getWork\n];\n\n/// @returns an array of objects describing web3.eth api properties\n\n\n\nvar properties = [\n new Property({\n name: 'coinbase',\n getter: 'eth_coinbase'\n }),\n new Property({\n name: 'mining',\n getter: 'eth_mining'\n }),\n new Property({\n name: 'hashrate',\n getter: 'eth_hashrate',\n outputFormatter: utils.toDecimal\n }),\n new Property({\n name: 'gasPrice',\n getter: 'eth_gasPrice',\n outputFormatter: formatters.outputBigNumberFormatter\n }),\n new Property({\n name: 'accounts',\n getter: 'eth_accounts'\n }),\n new Property({\n name: 'blockNumber',\n getter: 'eth_blockNumber',\n 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/** \n * @file event.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar web3 = require('../web3');\nvar formatters = require('./formatters');\n\n/**\n * This prototype should be used to create event filters\n */\nvar SolidityEvent = function (json, address) {\n this._params = json.inputs;\n this._name = utils.transformToFullName(json);\n this._address = address;\n this._anonymous = json.anonymous;\n};\n\n/**\n * Should be used to get filtered param types\n *\n * @method types\n * @param {Bool} decide if returned typed should be indexed\n * @return {Array} array of types\n */\nSolidityEvent.prototype.types = function (indexed) {\n return this._params.filter(function (i) {\n return i.indexed === indexed;\n }).map(function (i) {\n return i.type;\n });\n};\n\n/**\n * Should be used to get event display name\n *\n * @method displayName\n * @return {String} event display name\n */\nSolidityEvent.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get event type name\n *\n * @method typeName\n * @return {String} event type name\n */\nSolidityEvent.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be used to get event signature\n *\n * @method signature\n * @return {String} event signature\n */\nSolidityEvent.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2);\n};\n\n/**\n * Should be used to encode indexed params and options to one final object\n * \n * @method encode\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} everything combined together and encoded\n */\nSolidityEvent.prototype.encode = function (indexed, options) {\n indexed = indexed || {};\n options = options || {};\n var result = {};\n\n ['fromBlock', 'toBlock'].filter(function (f) {\n return options[f] !== undefined;\n }).forEach(function (f) {\n result[f] = formatters.inputBlockNumberFormatter(options[f]);\n });\n\n result.topics = [];\n\n if (!this._anonymous) {\n result.address = this._address;\n result.topics.push('0x' + this.signature());\n }\n\n var indexedTopics = this._params.filter(function (i) {\n return i.indexed === true;\n }).map(function (i) {\n var value = indexed[i.name];\n if (value === undefined || value === null) {\n return null;\n }\n \n if (utils.isArray(value)) {\n return value.map(function (v) {\n return '0x' + coder.encodeParam(i.type, v);\n });\n }\n return '0x' + coder.encodeParam(i.type, value);\n });\n\n result.topics = result.topics.concat(indexedTopics);\n\n return result;\n};\n\n/**\n * Should be used to decode indexed params and options\n *\n * @method decode\n * @param {Object} data\n * @return {Object} result object with decoded indexed && not indexed params\n */\nSolidityEvent.prototype.decode = function (data) {\n \n data.data = data.data || '';\n data.topics = data.topics || [];\n\n var argTopics = this._anonymous ? data.topics : data.topics.slice(1);\n var indexedData = argTopics.map(function (topics) { return topics.slice(2); }).join(\"\");\n var indexedParams = coder.decodeParams(this.types(true), indexedData); \n\n var notIndexedData = data.data.slice(2);\n var notIndexedParams = coder.decodeParams(this.types(false), notIndexedData);\n \n var result = formatters.outputLogFormatter(data);\n result.event = this.displayName();\n result.address = data.address;\n\n result.args = this._params.reduce(function (acc, current) {\n acc[current.name] = current.indexed ? indexedParams.shift() : notIndexedParams.shift();\n return acc;\n }, {});\n\n delete result.data;\n delete result.topics;\n\n return result;\n};\n\n/**\n * Should be used to create new filter object from event\n *\n * @method execute\n * @param {Object} indexed\n * @param {Object} options\n * @return {Object} filter object\n */\nSolidityEvent.prototype.execute = function (indexed, options) {\n var o = this.encode(indexed, options);\n var formatter = this.decode.bind(this);\n return web3.eth.filter(o, undefined, undefined, formatter);\n};\n\n/**\n * Should be used to attach event to contract object\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityEvent.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = this.execute.bind(this, contract);\n};\n\nmodule.exports = SolidityEvent;\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 RequestManager = require('./requestmanager');\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\n\n/**\n* Converts a given topic to a hex string, but also allows null values.\n*\n* @param {Mixed} value\n* @return {String}\n*/\nvar toTopic = function(value){\n\n if(value === null || typeof value === 'undefined')\n return null;\n\n value = String(value);\n\n if(value.indexOf('0x') === 0)\n return value;\n else\n return utils.fromAscii(value);\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\n if (utils.isString(options)) {\n return options;\n } \n\n options = options || {};\n\n // make sure topics, get converted to hex\n options.topics = options.topics || [];\n options.topics = options.topics.map(function(topic){\n return (utils.isArray(topic)) ? topic.map(toTopic) : toTopic(topic);\n });\n\n // lazy load\n return {\n topics: options.topics,\n to: options.to,\n address: options.address,\n fromBlock: formatters.inputBlockNumberFormatter(options.fromBlock),\n toBlock: formatters.inputBlockNumberFormatter(options.toBlock) \n }; \n};\n\nvar Filter = function (options, methods, formatter) {\n var implementation = {};\n methods.forEach(function (method) {\n method.attachToObject(implementation);\n });\n this.options = getOptions(options);\n this.implementation = implementation;\n this.callbacks = [];\n this.formatter = formatter;\n this.filterId = this.implementation.newFilter(this.options);\n};\n\nFilter.prototype.watch = function (callback) {\n this.callbacks.push(callback);\n var self = this;\n\n var onMessage = function (error, messages) {\n if (error) {\n return self.callbacks.forEach(function (callback) {\n callback(error);\n });\n }\n\n messages.forEach(function (message) {\n message = self.formatter ? self.formatter(message) : message;\n self.callbacks.forEach(function (callback) {\n callback(null, message);\n });\n });\n };\n\n // call getFilterLogs on start\n if (!utils.isString(this.options)) {\n this.get(function (err, messages) {\n // don't send all the responses to all the watches again... just to this one\n if (err) {\n callback(err);\n }\n\n messages.forEach(function (message) {\n callback(null, message);\n });\n });\n }\n\n RequestManager.getInstance().startPolling({\n method: this.implementation.poll.call,\n params: [this.filterId],\n }, this.filterId, onMessage, this.stopWatching.bind(this));\n};\n\nFilter.prototype.stopWatching = function () {\n RequestManager.getInstance().stopPolling(this.filterId);\n this.implementation.uninstallFilter(this.filterId);\n this.callbacks = [];\n};\n\nFilter.prototype.get = function (callback) {\n var self = this;\n if (utils.isFunction(callback)) {\n this.implementation.getLogs(this.filterId, function(err, res){\n if (err) {\n callback(err);\n } else {\n callback(null, res.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\n }));\n }\n });\n } else {\n var logs = this.implementation.getLogs(this.filterId);\n return logs.map(function (log) {\n return self.formatter ? self.formatter(log) : log;\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/** \n * @file formatters.js\n * @author Marek Kotewicz \n * @author Fabian Vogelsteller \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\nvar config = require('../utils/config');\n\n/**\n * Should the format output to a big number\n *\n * @method outputBigNumberFormatter\n * @param {String|Number|BigNumber}\n * @returns {BigNumber} object\n */\nvar outputBigNumberFormatter = function (number) {\n return utils.toBigNumber(number);\n};\n\nvar isPredefinedBlockNumber = function (blockNumber) {\n return blockNumber === 'latest' || blockNumber === 'pending' || blockNumber === 'earliest';\n};\n\nvar inputDefaultBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return config.defaultBlock;\n }\n return inputBlockNumberFormatter(blockNumber);\n};\n\nvar inputBlockNumberFormatter = function (blockNumber) {\n if (blockNumber === undefined) {\n return undefined;\n } else if (isPredefinedBlockNumber(blockNumber)) {\n return blockNumber;\n }\n return utils.toHex(blockNumber);\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 options.from = options.from || config.defaultAccount;\n\n // make code -> data\n if (options.code) {\n options.data = options.code;\n delete options.code;\n }\n\n ['gasPrice', 'gas', 'value', 'nonce'].filter(function (key) {\n return options[key] !== undefined;\n }).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.blockNumber = utils.toDecimal(tx.blockNumber);\n tx.transactionIndex = utils.toDecimal(tx.transactionIndex);\n tx.nonce = utils.toDecimal(tx.nonce);\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 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.difficulty = utils.toBigNumber(block.difficulty);\n block.totalDifficulty = utils.toBigNumber(block.totalDifficulty);\n\n if (utils.isArray(block.transactions)) {\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 if (log === null) { // 'pending' && 'latest' filters are nulls\n return null;\n }\n\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 * 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.workToProve = utils.fromDecimal(post.workToProve);\n post.priority = utils.fromDecimal(post.priority);\n\n // fallback\n if (!utils.isArray(post.topics)) {\n post.topics = 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 (utils.isJson(post.payload)) {\n post.payload = JSON.parse(post.payload);\n }\n\n // format the following options\n if (!post.topics) {\n post.topics = [];\n }\n post.topics = post.topics.map(function(topic){\n return utils.toAscii(topic);\n });\n\n return post;\n};\n\nmodule.exports = {\n inputDefaultBlockNumberFormatter: inputDefaultBlockNumberFormatter,\n inputBlockNumberFormatter: inputBlockNumberFormatter,\n inputTransactionFormatter: inputTransactionFormatter,\n inputPostFormatter: inputPostFormatter,\n outputBigNumberFormatter: outputBigNumberFormatter,\n outputTransactionFormatter: outputTransactionFormatter,\n outputBlockFormatter: outputBlockFormatter,\n outputLogFormatter: outputLogFormatter,\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/** \n * @file function.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar web3 = require('../web3');\nvar coder = require('../solidity/coder');\nvar utils = require('../utils/utils');\n\n/**\n * This prototype should be used to call/sendTransaction to solidity functions\n */\nvar SolidityFunction = function (json, address) {\n this._inputTypes = json.inputs.map(function (i) {\n return i.type;\n });\n this._outputTypes = json.outputs.map(function (i) {\n return i.type;\n });\n this._constant = json.constant;\n this._name = utils.transformToFullName(json);\n this._address = address;\n};\n\n/**\n * Should be used to create payload from arguments\n *\n * @method toPayload\n * @param {...} solidity function params\n * @param {Object} optional payload options\n */\nSolidityFunction.prototype.toPayload = function () {\n var args = Array.prototype.slice.call(arguments);\n var options = {};\n if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) {\n options = args.pop();\n }\n options.to = this._address;\n options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);\n return options;\n};\n\n/**\n * Should be used to get function signature\n *\n * @method signature\n * @return {String} function signature\n */\nSolidityFunction.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2, 10);\n};\n\n/**\n * Should be used to call function\n * \n * @method call\n * @param {Object} options\n * @return {String} output bytes\n */\nSolidityFunction.prototype.call = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n var output = web3.eth.call(payload);\n output = output.length >= 2 ? output.slice(2) : output;\n var result = coder.decodeParams(this._outputTypes, output);\n return result.length === 1 ? result[0] : result;\n};\n\n/**\n * Should be used to sendTransaction to solidity function\n *\n * @method sendTransaction\n * @param {Object} options\n */\nSolidityFunction.prototype.sendTransaction = function () {\n var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments));\n web3.eth.sendTransaction(payload);\n};\n\n/**\n * Should be used to get function display name\n *\n * @method displayName\n * @return {String} display name of the function\n */\nSolidityFunction.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get function type name\n * \n * @method typeName\n * @return {String} type name of the function\n */\nSolidityFunction.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be called to execute function\n *\n * @method execute\n */\nSolidityFunction.prototype.execute = function () {\n var transaction = !this._constant;\n \n // send transaction\n if (transaction) {\n return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments));\n }\n\n // call\n return this.call.apply(this, Array.prototype.slice.call(arguments));\n};\n\n/**\n * Should be called to attach function to contract\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityFunction.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n execute.call = this.call.bind(this);\n execute.sendTransaction = this.sendTransaction.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = execute; // circular!!!!\n};\n\nmodule.exports = SolidityFunction;\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/**\n * @file function.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar web3 = require('../web3');\nvar coder = require('../solidity/coder');\nvar utils = require('../utils/utils');\n\n/**\n * This prototype should be used to call/sendTransaction to solidity functions\n */\nvar SolidityFunction = function (json, address) {\n this._inputTypes = json.inputs.map(function (i) {\n return i.type;\n });\n this._outputTypes = json.outputs.map(function (i) {\n return i.type;\n });\n this._constant = json.constant;\n this._name = utils.transformToFullName(json);\n this._address = address;\n};\n\nSolidityFunction.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n};\n\n/**\n * Should be used to create payload from arguments\n *\n * @method toPayload\n * @param {Array} solidity function params\n * @param {Object} optional payload options\n */\nSolidityFunction.prototype.toPayload = function (args) {\n var options = {};\n if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) {\n options = args[args.length - 1];\n }\n options.to = this._address;\n options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args);\n return options;\n};\n\n/**\n * Should be used to get function signature\n *\n * @method signature\n * @return {String} function signature\n */\nSolidityFunction.prototype.signature = function () {\n return web3.sha3(web3.fromAscii(this._name)).slice(2, 10);\n};\n\n\nSolidityFunction.prototype.unpackOutput = function (output) {\n if (output === null) {\n return;\n }\n\n output = output.length >= 2 ? output.slice(2) : output;\n var result = coder.decodeParams(this._outputTypes, output);\n return result.length === 1 ? result[0] : result;\n};\n\n/**\n * Calls a contract function.\n *\n * @method call\n * @param {...Object} Contract function arguments\n * @param {function} If the last argument is a function, the contract function\n * call will be asynchronous, and the callback will be passed the\n * error and result.\n * @return {String} output bytes\n */\nSolidityFunction.prototype.call = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n\n if (!callback) {\n var output = web3.eth.call(payload);\n return this.unpackOutput(output);\n } \n \n var self = this;\n web3.eth.call(payload, function (error, output) {\n callback(error, self.unpackOutput(output));\n });\n};\n\n/**\n * Should be used to sendTransaction to solidity function\n *\n * @method sendTransaction\n * @param {Object} options\n */\nSolidityFunction.prototype.sendTransaction = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n\n if (!callback) {\n web3.eth.sendTransaction(payload);\n return;\n }\n\n web3.eth.sendTransaction(payload, callback);\n};\n\n/**\n * Should be used to get function display name\n *\n * @method displayName\n * @return {String} display name of the function\n */\nSolidityFunction.prototype.displayName = function () {\n return utils.extractDisplayName(this._name);\n};\n\n/**\n * Should be used to get function type name\n *\n * @method typeName\n * @return {String} type name of the function\n */\nSolidityFunction.prototype.typeName = function () {\n return utils.extractTypeName(this._name);\n};\n\n/**\n * Should be called to get rpc requests from solidity function\n *\n * @method request\n * @returns {Object}\n */\nSolidityFunction.prototype.request = function () {\n var args = Array.prototype.slice.call(arguments);\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n var format = this.unpackOutput.bind(this);\n \n return {\n callback: callback,\n payload: payload, \n format: format\n };\n};\n\n/**\n * Should be called to execute function\n *\n * @method execute\n */\nSolidityFunction.prototype.execute = function () {\n var transaction = !this._constant;\n\n // send transaction\n if (transaction) {\n return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments));\n }\n\n // call\n return this.call.apply(this, Array.prototype.slice.call(arguments));\n};\n\n/**\n * Should be called to attach function to contract\n *\n * @method attachToContract\n * @param {Contract}\n */\nSolidityFunction.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n execute.request = this.request.bind(this);\n execute.call = this.call.bind(this);\n execute.sendTransaction = this.sendTransaction.bind(this);\n var displayName = this.displayName();\n if (!contract[displayName]) {\n contract[displayName] = execute;\n }\n contract[displayName][this.typeName()] = execute; // circular!!!!\n};\n\nmodule.exports = SolidityFunction;\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\n\"use strict\";\n\nvar XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\nvar errors = require('./errors');\n\nvar HttpProvider = function (host) {\n this.host = host || 'http://localhost:8545';\n};\n\nHttpProvider.prototype.send = function (payload) {\n var request = new XMLHttpRequest();\n\n request.open('POST', this.host, false);\n \n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n throw errors.InvalidConnection(this.host);\n }\n\n\n // check request.status\n // TODO: throw an error here! it cannot silently fail!!!\n //if (request.status !== 200) {\n //return;\n //}\n\n var result = request.responseText;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n throw errors.InvalidResponse(result); \n }\n\n return result;\n};\n\nHttpProvider.prototype.sendAsync = function (payload, callback) {\n var request = new XMLHttpRequest();\n request.onreadystatechange = function() {\n if (request.readyState === 4) {\n var result = request.responseText;\n var error = null;\n\n try {\n result = JSON.parse(result);\n } catch(e) {\n error = errors.InvalidResponse(result); \n }\n\n callback(error, result);\n }\n };\n\n request.open('POST', this.host, true);\n\n try {\n request.send(JSON.stringify(payload));\n } catch(error) {\n callback(errors.InvalidConnection(this.host));\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 Jsonrpc = function () {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.messageId = 1;\n};\n\n/**\n * @return {Jsonrpc} singleton\n */\nJsonrpc.getInstance = function () {\n var instance = new Jsonrpc();\n return instance;\n};\n\n/**\n * Should be called to valid json create payload object\n *\n * @method toPayload\n * @param {Function} method of jsonrpc call, required\n * @param {Array} params, an array of method params, optional\n * @returns {Object} valid jsonrpc payload object\n */\nJsonrpc.prototype.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: this.messageId++\n };\n};\n\n/**\n * Should be called to check if jsonrpc response is valid\n *\n * @method isValidResponse\n * @param {Object}\n * @returns {Boolean} true if response is valid, otherwise false\n */\nJsonrpc.prototype.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/**\n * Should be called to create batch payload object\n *\n * @method toBatchPayload\n * @param {Array} messages, an array of objects with method (required) and params (optional) fields\n * @returns {Array} batch payload\n */\nJsonrpc.prototype.toBatchPayload = function (messages) {\n var self = this;\n return messages.map(function (message) {\n return self.toPayload(message.method, message.params);\n });\n};\n\nmodule.exports = Jsonrpc;\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/**\n * @file method.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\nvar utils = require('../utils/utils');\nvar errors = require('./errors');\n\nvar Method = function (options) {\n this.name = options.name;\n this.call = options.call;\n this.params = options.params || 0;\n this.inputFormatter = options.inputFormatter;\n this.outputFormatter = options.outputFormatter;\n};\n\n/**\n * Should be used to determine name of the jsonrpc method based on arguments\n *\n * @method getCall\n * @param {Array} arguments\n * @return {String} name of jsonrpc method\n */\nMethod.prototype.getCall = function (args) {\n return utils.isFunction(this.call) ? this.call(args) : this.call;\n};\n\n/**\n * Should be used to extract callback from array of arguments. Modifies input param\n *\n * @method extractCallback\n * @param {Array} arguments\n * @return {Function|Null} callback, if exists\n */\nMethod.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n return null;\n};\n\n/**\n * Should be called to check if the number of arguments is correct\n * \n * @method validateArgs\n * @param {Array} arguments\n * @throws {Error} if it is not\n */\nMethod.prototype.validateArgs = function (args) {\n if (args.length !== this.params) {\n throw errors.InvalidNumberOfParams();\n }\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nMethod.prototype.formatInput = function (args) {\n if (!this.inputFormatter) {\n return args;\n }\n\n return this.inputFormatter.map(function (formatter, index) {\n return formatter ? formatter(args[index]) : args[index];\n });\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nMethod.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nMethod.prototype.attachToObject = function (obj) {\n var func = this.send.bind(this);\n func.call = this.call; // that's ugly. filter.js uses it\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n obj[name[0]][name[1]] = func;\n } else {\n obj[name[0]] = func; \n }\n};\n\n/**\n * Should create payload from given input args\n *\n * @method toPayload\n * @param {Array} args\n * @return {Object}\n */\nMethod.prototype.toPayload = function (args) {\n var call = this.getCall(args);\n var callback = this.extractCallback(args);\n var params = this.formatInput(args);\n this.validateArgs(params);\n\n return {\n method: call,\n params: params,\n callback: callback\n };\n};\n\n/**\n * Should send request to the API\n *\n * @method send\n * @param list of params\n * @return result\n */\nMethod.prototype.send = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n if (payload.callback) {\n var self = this;\n return RequestManager.getInstance().sendAsync(payload, function (err, result) {\n payload.callback(null, self.formatOutput(result));\n });\n }\n return this.formatOutput(RequestManager.getInstance().send(payload));\n};\n\nmodule.exports = Method;\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/**\n * @file method.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\nvar utils = require('../utils/utils');\nvar errors = require('./errors');\n\nvar Method = function (options) {\n this.name = options.name;\n this.call = options.call;\n this.params = options.params || 0;\n this.inputFormatter = options.inputFormatter;\n this.outputFormatter = options.outputFormatter;\n};\n\n/**\n * Should be used to determine name of the jsonrpc method based on arguments\n *\n * @method getCall\n * @param {Array} arguments\n * @return {String} name of jsonrpc method\n */\nMethod.prototype.getCall = function (args) {\n return utils.isFunction(this.call) ? this.call(args) : this.call;\n};\n\n/**\n * Should be used to extract callback from array of arguments. Modifies input param\n *\n * @method extractCallback\n * @param {Array} arguments\n * @return {Function|Null} callback, if exists\n */\nMethod.prototype.extractCallback = function (args) {\n if (utils.isFunction(args[args.length - 1])) {\n return args.pop(); // modify the args array!\n }\n};\n\n/**\n * Should be called to check if the number of arguments is correct\n * \n * @method validateArgs\n * @param {Array} arguments\n * @throws {Error} if it is not\n */\nMethod.prototype.validateArgs = function (args) {\n if (args.length !== this.params) {\n throw errors.InvalidNumberOfParams();\n }\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nMethod.prototype.formatInput = function (args) {\n if (!this.inputFormatter) {\n return args;\n }\n\n return this.inputFormatter.map(function (formatter, index) {\n return formatter ? formatter(args[index]) : args[index];\n });\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nMethod.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nMethod.prototype.attachToObject = function (obj) {\n var func = this.send.bind(this);\n func.request = this.request.bind(this);\n func.call = this.call; // that's ugly. filter.js uses it\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n obj[name[0]][name[1]] = func;\n } else {\n obj[name[0]] = func; \n }\n};\n\n/**\n * Should create payload from given input args\n *\n * @method toPayload\n * @param {Array} args\n * @return {Object}\n */\nMethod.prototype.toPayload = function (args) {\n var call = this.getCall(args);\n var callback = this.extractCallback(args);\n var params = this.formatInput(args);\n this.validateArgs(params);\n\n return {\n method: call,\n params: params,\n callback: callback\n };\n};\n\n/**\n * Should be called to create pure JSONRPC request which can be used in batch request\n *\n * @method request\n * @param {...} params\n * @return {Object} jsonrpc request\n */\nMethod.prototype.request = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n payload.format = this.formatOutput.bind(this);\n return payload;\n};\n\n/**\n * Should send request to the API\n *\n * @method send\n * @param list of params\n * @return result\n */\nMethod.prototype.send = function () {\n var payload = this.toPayload(Array.prototype.slice.call(arguments));\n if (payload.callback) {\n var self = this;\n return RequestManager.getInstance().sendAsync(payload, function (err, result) {\n payload.callback(err, self.formatOutput(result));\n });\n }\n return this.formatOutput(RequestManager.getInstance().send(payload));\n};\n\nmodule.exports = Method;\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');\nvar Property = require('./property');\n\n/// @returns an array of objects describing web3.eth api methods\nvar methods = [\n];\n\n/// @returns an array of objects describing web3.eth api properties\nvar properties = [\n new Property({\n name: 'listening',\n getter: 'net_listening'\n }),\n new Property({\n name: 'peerCount',\n getter: 'net_peerCount',\n outputFormatter: utils.toDecimal\n })\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/**\n * @file property.js\n * @author Fabian Vogelsteller \n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\n\nvar Property = function (options) {\n this.name = options.name;\n this.getter = options.getter;\n this.setter = options.setter;\n this.outputFormatter = options.outputFormatter;\n this.inputFormatter = options.inputFormatter;\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nProperty.prototype.formatInput = function (arg) {\n return this.inputFormatter ? this.inputFormatter(arg) : arg;\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nProperty.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nProperty.prototype.attachToObject = function (obj) {\n var proto = {\n get: this.get.bind(this),\n set: this.set.bind(this)\n };\n\n var name = this.name.split('.');\n if (name.length > 1) {\n obj[name[0]] = obj[name[0]] || {};\n Object.defineProperty(obj[name[0]], name[1], proto); \n } else {\n Object.defineProperty(obj, name[0], proto);\n }\n};\n\n/**\n * Should be used to get value of the property\n *\n * @method get\n * @return {Object} value of the property\n */\nProperty.prototype.get = function () {\n return this.formatOutput(RequestManager.getInstance().send({\n method: this.getter\n }));\n};\n\n/**\n * Should be used to set value of the property\n *\n * @method set\n * @param {Object} new value of the property\n */\nProperty.prototype.set = function (value) {\n return RequestManager.getInstance().send({\n method: this.setter,\n params: [this.formatInput(value)]\n });\n};\n\nmodule.exports = Property;\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/**\n * @file property.js\n * @author Fabian Vogelsteller \n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar RequestManager = require('./requestmanager');\n\nvar Property = function (options) {\n this.name = options.name;\n this.getter = options.getter;\n this.setter = options.setter;\n this.outputFormatter = options.outputFormatter;\n this.inputFormatter = options.inputFormatter;\n};\n\n/**\n * Should be called to format input args of method\n * \n * @method formatInput\n * @param {Array}\n * @return {Array}\n */\nProperty.prototype.formatInput = function (arg) {\n return this.inputFormatter ? this.inputFormatter(arg) : arg;\n};\n\n/**\n * Should be called to format output(result) of method\n *\n * @method formatOutput\n * @param {Object}\n * @return {Object}\n */\nProperty.prototype.formatOutput = function (result) {\n return this.outputFormatter && result !== null ? this.outputFormatter(result) : result;\n};\n\n/**\n * Should attach function to method\n * \n * @method attachToObject\n * @param {Object}\n * @param {Function}\n */\nProperty.prototype.attachToObject = function (obj) {\n var proto = {\n get: this.get.bind(this),\n };\n\n var names = this.name.split('.');\n var name = names[0];\n if (names.length > 1) {\n obj[names[0]] = obj[names[0]] || {};\n obj = obj[names[0]];\n name = names[1];\n }\n \n Object.defineProperty(obj, name, proto);\n\n var toAsyncName = function (prefix, name) {\n return prefix + name.charAt(0).toUpperCase() + name.slice(1);\n };\n\n obj[toAsyncName('get', name)] = this.getAsync.bind(this);\n};\n\n/**\n * Should be used to get value of the property\n *\n * @method get\n * @return {Object} value of the property\n */\nProperty.prototype.get = function () {\n return this.formatOutput(RequestManager.getInstance().send({\n method: this.getter\n }));\n};\n\n/**\n * Should be used to asynchrounously get value of property\n *\n * @method getAsync\n * @param {Function}\n */\nProperty.prototype.getAsync = function (callback) {\n var self = this;\n RequestManager.getInstance().sendAsync({\n method: this.getter\n }, function (err, result) {\n if (err) {\n return callback(err);\n }\n callback(err, self.formatOutput(result));\n });\n};\n\nmodule.exports = Property;\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/** \n * @file requestmanager.js\n * @author Jeffrey Wilcke \n * @author Marek Kotewicz \n * @author Marian Oancea \n * @author Fabian Vogelsteller \n * @author Gav Wood \n * @date 2014\n */\n\nvar Jsonrpc = require('./jsonrpc');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar errors = require('./errors');\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 * Singleton\n */\nvar RequestManager = function (provider) {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.provider = provider;\n this.polls = [];\n this.timeout = null;\n this.poll();\n};\n\n/**\n * @return {RequestManager} singleton\n */\nRequestManager.getInstance = function () {\n var instance = new RequestManager();\n return instance;\n};\n\n/**\n * Should be used to synchronously send request\n *\n * @method send\n * @param {Object} data\n * @return {Object}\n */\nRequestManager.prototype.send = function (data) {\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return null;\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n var result = this.provider.send(payload);\n\n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n throw errors.InvalidResponse(result);\n }\n\n return result.result;\n};\n\n/**\n * Should be used to asynchronously send request\n *\n * @method sendAsync\n * @param {Object} data\n * @param {Function} callback\n */\nRequestManager.prototype.sendAsync = function (data, callback) {\n if (!this.provider) {\n return callback(errors.InvalidProvider());\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n this.provider.sendAsync(payload, function (err, result) {\n if (err) {\n return callback(err);\n }\n \n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n return callback(errors.InvalidResponse(result));\n }\n\n callback(null, result.result);\n });\n};\n\n/**\n * Should be used to set provider of request manager\n *\n * @method setProvider\n * @param {Object}\n */\nRequestManager.prototype.setProvider = function (p) {\n this.provider = p;\n};\n\n/*jshint maxparams:4 */\n\n/**\n * Should be used to start polling\n *\n * @method startPolling\n * @param {Object} data\n * @param {Number} pollId\n * @param {Function} callback\n * @param {Function} uninstall\n *\n * @todo cleanup number of params\n */\nRequestManager.prototype.startPolling = function (data, pollId, callback, uninstall) {\n this.polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});\n};\n/*jshint maxparams:3 */\n\n/**\n * Should be used to stop polling for filter with given id\n *\n * @method stopPolling\n * @param {Number} pollId\n */\nRequestManager.prototype.stopPolling = function (pollId) {\n for (var i = this.polls.length; i--;) {\n var poll = this.polls[i];\n if (poll.id === pollId) {\n this.polls.splice(i, 1);\n }\n }\n};\n\n/**\n * Should be called to reset polling mechanism of request manager\n *\n * @method reset\n */\nRequestManager.prototype.reset = function () {\n this.polls.forEach(function (poll) {\n poll.uninstall(poll.id); \n });\n this.polls = [];\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n this.poll();\n};\n\n/**\n * Should be called to poll for changes on filter with given id\n *\n * @method poll\n */\nRequestManager.prototype.poll = function () {\n this.timeout = setTimeout(this.poll.bind(this), c.ETH_POLLING_TIMEOUT);\n\n if (!this.polls.length) {\n return;\n }\n\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return;\n }\n\n var payload = Jsonrpc.getInstance().toBatchPayload(this.polls.map(function (data) {\n return data.data;\n }));\n\n var self = this;\n this.provider.sendAsync(payload, function (error, results) {\n // TODO: console log?\n if (error) {\n return;\n }\n \n if (!utils.isArray(results)) {\n throw errors.InvalidResponse(results);\n }\n\n results.map(function (result, index) {\n result.callback = self.polls[index].callback;\n return result;\n }).filter(function (result) {\n var valid = Jsonrpc.getInstance().isValidResponse(result);\n if (!valid) {\n result.callback(errors.InvalidResponse(result));\n }\n return valid;\n }).filter(function (result) {\n return utils.isArray(result.result) && result.result.length > 0;\n }).forEach(function (result) {\n result.callback(null, result.result);\n });\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/** \n * @file requestmanager.js\n * @author Jeffrey Wilcke \n * @author Marek Kotewicz \n * @author Marian Oancea \n * @author Fabian Vogelsteller \n * @author Gav Wood \n * @date 2014\n */\n\nvar Jsonrpc = require('./jsonrpc');\nvar utils = require('../utils/utils');\nvar c = require('../utils/config');\nvar errors = require('./errors');\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 * Singleton\n */\nvar RequestManager = function (provider) {\n // singleton pattern\n if (arguments.callee._singletonInstance) {\n return arguments.callee._singletonInstance;\n }\n arguments.callee._singletonInstance = this;\n\n this.provider = provider;\n this.polls = [];\n this.timeout = null;\n this.poll();\n};\n\n/**\n * @return {RequestManager} singleton\n */\nRequestManager.getInstance = function () {\n var instance = new RequestManager();\n return instance;\n};\n\n/**\n * Should be used to synchronously send request\n *\n * @method send\n * @param {Object} data\n * @return {Object}\n */\nRequestManager.prototype.send = function (data) {\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return null;\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n var result = this.provider.send(payload);\n\n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n throw errors.InvalidResponse(result);\n }\n\n return result.result;\n};\n\n/**\n * Should be used to asynchronously send request\n *\n * @method sendAsync\n * @param {Object} data\n * @param {Function} callback\n */\nRequestManager.prototype.sendAsync = function (data, callback) {\n if (!this.provider) {\n return callback(errors.InvalidProvider());\n }\n\n var payload = Jsonrpc.getInstance().toPayload(data.method, data.params);\n this.provider.sendAsync(payload, function (err, result) {\n if (err) {\n return callback(err);\n }\n \n if (!Jsonrpc.getInstance().isValidResponse(result)) {\n return callback(errors.InvalidResponse(result));\n }\n\n callback(null, result.result);\n });\n};\n\n/**\n * Should be called to asynchronously send batch request\n *\n * @method sendBatch\n * @param {Array} batch data\n * @param {Function} callback\n */\nRequestManager.prototype.sendBatch = function (data, callback) {\n if (!this.provider) {\n return callback(errors.InvalidProvider());\n }\n\n var payload = Jsonrpc.getInstance().toBatchPayload(data);\n\n this.provider.sendAsync(payload, function (err, results) {\n if (err) {\n return callback(err);\n }\n\n if (!utils.isArray(results)) {\n return callback(errors.InvalidResponse(results));\n }\n\n callback(err, results);\n }); \n};\n\n/**\n * Should be used to set provider of request manager\n *\n * @method setProvider\n * @param {Object}\n */\nRequestManager.prototype.setProvider = function (p) {\n this.provider = p;\n};\n\n/*jshint maxparams:4 */\n\n/**\n * Should be used to start polling\n *\n * @method startPolling\n * @param {Object} data\n * @param {Number} pollId\n * @param {Function} callback\n * @param {Function} uninstall\n *\n * @todo cleanup number of params\n */\nRequestManager.prototype.startPolling = function (data, pollId, callback, uninstall) {\n this.polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});\n};\n/*jshint maxparams:3 */\n\n/**\n * Should be used to stop polling for filter with given id\n *\n * @method stopPolling\n * @param {Number} pollId\n */\nRequestManager.prototype.stopPolling = function (pollId) {\n for (var i = this.polls.length; i--;) {\n var poll = this.polls[i];\n if (poll.id === pollId) {\n this.polls.splice(i, 1);\n }\n }\n};\n\n/**\n * Should be called to reset polling mechanism of request manager\n *\n * @method reset\n */\nRequestManager.prototype.reset = function () {\n this.polls.forEach(function (poll) {\n poll.uninstall(poll.id); \n });\n this.polls = [];\n\n if (this.timeout) {\n clearTimeout(this.timeout);\n this.timeout = null;\n }\n this.poll();\n};\n\n/**\n * Should be called to poll for changes on filter with given id\n *\n * @method poll\n */\nRequestManager.prototype.poll = function () {\n this.timeout = setTimeout(this.poll.bind(this), c.ETH_POLLING_TIMEOUT);\n\n if (!this.polls.length) {\n return;\n }\n\n if (!this.provider) {\n console.error(errors.InvalidProvider());\n return;\n }\n\n var payload = Jsonrpc.getInstance().toBatchPayload(this.polls.map(function (data) {\n return data.data;\n }));\n\n var self = this;\n this.provider.sendAsync(payload, function (error, results) {\n // TODO: console log?\n if (error) {\n return;\n }\n \n if (!utils.isArray(results)) {\n throw errors.InvalidResponse(results);\n }\n\n results.map(function (result, index) {\n result.callback = self.polls[index].callback;\n return result;\n }).filter(function (result) {\n var valid = Jsonrpc.getInstance().isValidResponse(result);\n if (!valid) {\n result.callback(errors.InvalidResponse(result));\n }\n return valid;\n }).filter(function (result) {\n return utils.isArray(result.result) && result.result.length > 0;\n }).forEach(function (result) {\n result.callback(null, result.result);\n });\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 Method = require('./method');\nvar formatters = require('./formatters');\n\nvar post = new Method({\n name: 'post', \n call: 'shh_post', \n params: 1,\n inputFormatter: [formatters.inputPostFormatter]\n});\n\nvar newIdentity = new Method({\n name: 'newIdentity',\n call: 'shh_newIdentity',\n params: 0\n});\n\nvar hasIdentity = new Method({\n name: 'hasIdentity',\n call: 'shh_hasIdentity',\n params: 1\n});\n\nvar newGroup = new Method({\n name: 'newGroup',\n call: 'shh_newGroup',\n params: 0\n});\n\nvar addToGroup = new Method({\n name: 'addToGroup',\n call: 'shh_addToGroup',\n params: 0\n});\n\nvar methods = [\n post,\n newIdentity,\n hasIdentity,\n newGroup,\n addToGroup\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 watches.js\n * @authors:\n * Marek Kotewicz \n * @date 2015\n */\n\nvar Method = require('./method');\n\n/// @returns an array of objects describing web3.eth.filter api methods\nvar eth = function () {\n var newFilterCall = function (args) {\n return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter';\n };\n\n var newFilter = new Method({\n name: 'newFilter',\n call: newFilterCall,\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'eth_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'eth_getFilterLogs',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'eth_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\n/// @returns an array of objects describing web3.shh.watch api methods\nvar shh = function () {\n var newFilter = new Method({\n name: 'newFilter',\n call: 'shh_newFilter',\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'shh_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'shh_getMessages',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'shh_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\nmodule.exports = {\n eth: eth,\n shh: shh\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\nvar Method = require('./method');\n\n/// @returns an array of objects describing web3.eth.filter api methods\nvar eth = function () {\n var newFilterCall = function (args) {\n var type = args[0];\n\n switch(type) {\n case 'latest':\n args.pop();\n this.params = 0;\n return 'eth_newBlockFilter';\n case 'pending':\n args.pop();\n this.params = 0;\n return 'eth_newPendingTransactionFilter';\n default:\n return 'eth_newFilter';\n }\n };\n\n var newFilter = new Method({\n name: 'newFilter',\n call: newFilterCall,\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'eth_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'eth_getFilterLogs',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'eth_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\n/// @returns an array of objects describing web3.shh.watch api methods\nvar shh = function () {\n var newFilter = new Method({\n name: 'newFilter',\n call: 'shh_newFilter',\n params: 1\n });\n\n var uninstallFilter = new Method({\n name: 'uninstallFilter',\n call: 'shh_uninstallFilter',\n params: 1\n });\n\n var getLogs = new Method({\n name: 'getLogs',\n call: 'shh_getMessages',\n params: 1\n });\n\n var poll = new Method({\n name: 'poll',\n call: 'shh_getFilterChanges',\n params: 1\n });\n\n return [\n newFilter,\n uninstallFilter,\n getLogs,\n poll\n ];\n};\n\nmodule.exports = {\n eth: eth,\n shh: shh\n};\n\n", null, "/*! bignumber.js v2.0.7 https://github.com/MikeMcl/bignumber.js/LICENCE */\n\n;(function (global) {\n 'use strict';\n\n /*\n bignumber.js v2.0.7\n A JavaScript library for arbitrary-precision arithmetic.\n https://github.com/MikeMcl/bignumber.js\n Copyright (c) 2015 Michael Mclaughlin \n MIT Expat Licence\n */\n\n\n var BigNumber, crypto, parseNumeric,\n isNumeric = /^-?(\\d+(\\.\\d*)?|\\.\\d+)(e[+-]?\\d+)?$/i,\n mathceil = Math.ceil,\n mathfloor = Math.floor,\n notBool = ' not a boolean or binary digit',\n roundingMode = 'rounding mode',\n tooManyDigits = 'number type has more than 15 significant digits',\n ALPHABET = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_',\n BASE = 1e14,\n LOG_BASE = 14,\n MAX_SAFE_INTEGER = 0x1fffffffffffff, // 2^53 - 1\n // MAX_INT32 = 0x7fffffff, // 2^31 - 1\n POWS_TEN = [1, 10, 100, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13],\n SQRT_BASE = 1e7,\n\n /*\n * The limit on the value of DECIMAL_PLACES, TO_EXP_NEG, TO_EXP_POS, MIN_EXP, MAX_EXP, and\n * the arguments to toExponential, toFixed, toFormat, and toPrecision, beyond which an\n * exception is thrown (if ERRORS is true).\n */\n MAX = 1E9; // 0 to MAX_INT32\n\n\n /*\n * Create and return a BigNumber constructor.\n */\n function another(configObj) {\n var div,\n\n // id tracks the caller function, so its name can be included in error messages.\n id = 0,\n P = BigNumber.prototype,\n ONE = new BigNumber(1),\n\n\n /********************************* EDITABLE DEFAULTS **********************************/\n\n\n /*\n * The default values below must be integers within the inclusive ranges stated.\n * The values can also be changed at run-time using BigNumber.config.\n */\n\n // The maximum number of decimal places for operations involving division.\n DECIMAL_PLACES = 20, // 0 to MAX\n\n /*\n * The rounding mode used when rounding to the above decimal places, and when using\n * toExponential, toFixed, toFormat and toPrecision, and round (default value).\n * UP 0 Away from zero.\n * DOWN 1 Towards zero.\n * CEIL 2 Towards +Infinity.\n * FLOOR 3 Towards -Infinity.\n * HALF_UP 4 Towards nearest neighbour. If equidistant, up.\n * HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.\n * HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.\n * HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.\n * HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.\n */\n ROUNDING_MODE = 4, // 0 to 8\n\n // EXPONENTIAL_AT : [TO_EXP_NEG , TO_EXP_POS]\n\n // The exponent value at and beneath which toString returns exponential notation.\n // Number type: -7\n TO_EXP_NEG = -7, // 0 to -MAX\n\n // The exponent value at and above which toString returns exponential notation.\n // Number type: 21\n TO_EXP_POS = 21, // 0 to MAX\n\n // RANGE : [MIN_EXP, MAX_EXP]\n\n // The minimum exponent value, beneath which underflow to zero occurs.\n // Number type: -324 (5e-324)\n MIN_EXP = -1e7, // -1 to -MAX\n\n // The maximum exponent value, above which overflow to Infinity occurs.\n // Number type: 308 (1.7976931348623157e+308)\n // For MAX_EXP > 1e7, e.g. new BigNumber('1e100000000').plus(1) may be slow.\n MAX_EXP = 1e7, // 1 to MAX\n\n // Whether BigNumber Errors are ever thrown.\n ERRORS = true, // true or false\n\n // Change to intValidatorNoErrors if ERRORS is false.\n isValidInt = intValidatorWithErrors, // intValidatorWithErrors/intValidatorNoErrors\n\n // Whether to use cryptographically-secure random number generation, if available.\n CRYPTO = false, // true or false\n\n /*\n * The modulo mode used when calculating the modulus: a mod n.\n * The quotient (q = a / n) is calculated according to the corresponding rounding mode.\n * The remainder (r) is calculated as: r = a - n * q.\n *\n * UP 0 The remainder is positive if the dividend is negative, else is negative.\n * DOWN 1 The remainder has the same sign as the dividend.\n * This modulo mode is commonly known as 'truncated division' and is\n * equivalent to (a % n) in JavaScript.\n * FLOOR 3 The remainder has the same sign as the divisor (Python %).\n * HALF_EVEN 6 This modulo mode implements the IEEE 754 remainder function.\n * EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)).\n * The remainder is always positive.\n *\n * The truncated division, floored division, Euclidian division and IEEE 754 remainder\n * modes are commonly used for the modulus operation.\n * Although the other rounding modes can also be used, they may not give useful results.\n */\n MODULO_MODE = 1, // 0 to 9\n\n // The maximum number of significant digits of the result of the toPower operation.\n // If POW_PRECISION is 0, there will be unlimited significant digits.\n POW_PRECISION = 100, // 0 to MAX\n\n // The format specification used by the BigNumber.prototype.toFormat method.\n FORMAT = {\n decimalSeparator: '.',\n groupSeparator: ',',\n groupSize: 3,\n secondaryGroupSize: 0,\n fractionGroupSeparator: '\\xA0', // non-breaking space\n fractionGroupSize: 0\n };\n\n\n /******************************************************************************************/\n\n\n // CONSTRUCTOR\n\n\n /*\n * The BigNumber constructor and exported function.\n * Create and return a new instance of a BigNumber object.\n *\n * n {number|string|BigNumber} A numeric value.\n * [b] {number} The base of n. Integer, 2 to 64 inclusive.\n */\n function BigNumber( n, b ) {\n var c, e, i, num, len, str,\n x = this;\n\n // Enable constructor usage without new.\n if ( !( x instanceof BigNumber ) ) {\n\n // 'BigNumber() constructor call without new: {n}'\n if (ERRORS) raise( 26, 'constructor call without new', n );\n return new BigNumber( n, b );\n }\n\n // 'new BigNumber() base not an integer: {b}'\n // 'new BigNumber() base out of range: {b}'\n if ( b == null || !isValidInt( b, 2, 64, id, 'base' ) ) {\n\n // Duplicate.\n if ( n instanceof BigNumber ) {\n x.s = n.s;\n x.e = n.e;\n x.c = ( n = n.c ) ? n.slice() : n;\n id = 0;\n return;\n }\n\n if ( ( num = typeof n == 'number' ) && n * 0 == 0 ) {\n x.s = 1 / n < 0 ? ( n = -n, -1 ) : 1;\n\n // Fast path for integers.\n if ( n === ~~n ) {\n for ( e = 0, i = n; i >= 10; i /= 10, e++ );\n x.e = e;\n x.c = [n];\n id = 0;\n return;\n }\n\n str = n + '';\n } else {\n if ( !isNumeric.test( str = n + '' ) ) return parseNumeric( x, str, num );\n x.s = str.charCodeAt(0) === 45 ? ( str = str.slice(1), -1 ) : 1;\n }\n } else {\n b = b | 0;\n str = n + '';\n\n // Ensure return value is rounded to DECIMAL_PLACES as with other bases.\n // Allow exponential notation to be used with base 10 argument.\n if ( b == 10 ) {\n x = new BigNumber( n instanceof BigNumber ? n : str );\n return round( x, DECIMAL_PLACES + x.e + 1, ROUNDING_MODE );\n }\n\n // Avoid potential interpretation of Infinity and NaN as base 44+ values.\n // Any number in exponential form will fail due to the [Ee][+-].\n if ( ( num = typeof n == 'number' ) && n * 0 != 0 ||\n !( new RegExp( '^-?' + ( c = '[' + ALPHABET.slice( 0, b ) + ']+' ) +\n '(?:\\\\.' + c + ')?$',b < 37 ? 'i' : '' ) ).test(str) ) {\n return parseNumeric( x, str, num, b );\n }\n\n if (num) {\n x.s = 1 / n < 0 ? ( str = str.slice(1), -1 ) : 1;\n\n if ( ERRORS && str.replace( /^0\\.0*|\\./, '' ).length > 15 ) {\n\n // 'new BigNumber() number type has more than 15 significant digits: {n}'\n raise( id, tooManyDigits, n );\n }\n\n // Prevent later check for length on converted number.\n num = false;\n } else {\n x.s = str.charCodeAt(0) === 45 ? ( str = str.slice(1), -1 ) : 1;\n }\n\n str = convertBase( str, 10, b, x.s );\n }\n\n // Decimal point?\n if ( ( e = str.indexOf('.') ) > -1 ) str = str.replace( '.', '' );\n\n // Exponential form?\n if ( ( i = str.search( /e/i ) ) > 0 ) {\n\n // Determine exponent.\n if ( e < 0 ) e = i;\n e += +str.slice( i + 1 );\n str = str.substring( 0, i );\n } else if ( e < 0 ) {\n\n // Integer.\n e = str.length;\n }\n\n // Determine leading zeros.\n for ( i = 0; str.charCodeAt(i) === 48; i++ );\n\n // Determine trailing zeros.\n for ( len = str.length; str.charCodeAt(--len) === 48; );\n str = str.slice( i, len + 1 );\n\n if (str) {\n len = str.length;\n\n // Disallow numbers with over 15 significant digits if number type.\n // 'new BigNumber() number type has more than 15 significant digits: {n}'\n if ( num && ERRORS && len > 15 ) raise( id, tooManyDigits, x.s * n );\n\n e = e - i - 1;\n\n // Overflow?\n if ( e > MAX_EXP ) {\n\n // Infinity.\n x.c = x.e = null;\n\n // Underflow?\n } else if ( e < MIN_EXP ) {\n\n // Zero.\n x.c = [ x.e = 0 ];\n } else {\n x.e = e;\n x.c = [];\n\n // Transform base\n\n // e is the base 10 exponent.\n // i is where to slice str to get the first element of the coefficient array.\n i = ( e + 1 ) % LOG_BASE;\n if ( e < 0 ) i += LOG_BASE;\n\n if ( i < len ) {\n if (i) x.c.push( +str.slice( 0, i ) );\n\n for ( len -= LOG_BASE; i < len; ) {\n x.c.push( +str.slice( i, i += LOG_BASE ) );\n }\n\n str = str.slice(i);\n i = LOG_BASE - str.length;\n } else {\n i -= len;\n }\n\n for ( ; i--; str += '0' );\n x.c.push( +str );\n }\n } else {\n\n // Zero.\n x.c = [ x.e = 0 ];\n }\n\n id = 0;\n }\n\n\n // CONSTRUCTOR PROPERTIES\n\n\n BigNumber.another = another;\n\n BigNumber.ROUND_UP = 0;\n BigNumber.ROUND_DOWN = 1;\n BigNumber.ROUND_CEIL = 2;\n BigNumber.ROUND_FLOOR = 3;\n BigNumber.ROUND_HALF_UP = 4;\n BigNumber.ROUND_HALF_DOWN = 5;\n BigNumber.ROUND_HALF_EVEN = 6;\n BigNumber.ROUND_HALF_CEIL = 7;\n BigNumber.ROUND_HALF_FLOOR = 8;\n BigNumber.EUCLID = 9;\n\n\n /*\n * Configure infrequently-changing library-wide settings.\n *\n * Accept an object or an argument list, with one or many of the following properties or\n * parameters respectively:\n *\n * DECIMAL_PLACES {number} Integer, 0 to MAX inclusive\n * ROUNDING_MODE {number} Integer, 0 to 8 inclusive\n * EXPONENTIAL_AT {number|number[]} Integer, -MAX to MAX inclusive or\n * [integer -MAX to 0 incl., 0 to MAX incl.]\n * RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or\n * [integer -MAX to -1 incl., integer 1 to MAX incl.]\n * ERRORS {boolean|number} true, false, 1 or 0\n * CRYPTO {boolean|number} true, false, 1 or 0\n * MODULO_MODE {number} 0 to 9 inclusive\n * POW_PRECISION {number} 0 to MAX inclusive\n * FORMAT {object} See BigNumber.prototype.toFormat\n * decimalSeparator {string}\n * groupSeparator {string}\n * groupSize {number}\n * secondaryGroupSize {number}\n * fractionGroupSeparator {string}\n * fractionGroupSize {number}\n *\n * (The values assigned to the above FORMAT object properties are not checked for validity.)\n *\n * E.g.\n * BigNumber.config(20, 4) is equivalent to\n * BigNumber.config({ DECIMAL_PLACES : 20, ROUNDING_MODE : 4 })\n *\n * Ignore properties/parameters set to null or undefined.\n * Return an object with the properties current values.\n */\n BigNumber.config = function () {\n var v, p,\n i = 0,\n r = {},\n a = arguments,\n o = a[0],\n has = o && typeof o == 'object'\n ? function () { if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null; }\n : function () { if ( a.length > i ) return ( v = a[i++] ) != null; };\n\n // DECIMAL_PLACES {number} Integer, 0 to MAX inclusive.\n // 'config() DECIMAL_PLACES not an integer: {v}'\n // 'config() DECIMAL_PLACES out of range: {v}'\n if ( has( p = 'DECIMAL_PLACES' ) && isValidInt( v, 0, MAX, 2, p ) ) {\n DECIMAL_PLACES = v | 0;\n }\n r[p] = DECIMAL_PLACES;\n\n // ROUNDING_MODE {number} Integer, 0 to 8 inclusive.\n // 'config() ROUNDING_MODE not an integer: {v}'\n // 'config() ROUNDING_MODE out of range: {v}'\n if ( has( p = 'ROUNDING_MODE' ) && isValidInt( v, 0, 8, 2, p ) ) {\n ROUNDING_MODE = v | 0;\n }\n r[p] = ROUNDING_MODE;\n\n // EXPONENTIAL_AT {number|number[]}\n // Integer, -MAX to MAX inclusive or [integer -MAX to 0 inclusive, 0 to MAX inclusive].\n // 'config() EXPONENTIAL_AT not an integer: {v}'\n // 'config() EXPONENTIAL_AT out of range: {v}'\n if ( has( p = 'EXPONENTIAL_AT' ) ) {\n\n if ( isArray(v) ) {\n if ( isValidInt( v[0], -MAX, 0, 2, p ) && isValidInt( v[1], 0, MAX, 2, p ) ) {\n TO_EXP_NEG = v[0] | 0;\n TO_EXP_POS = v[1] | 0;\n }\n } else if ( isValidInt( v, -MAX, MAX, 2, p ) ) {\n TO_EXP_NEG = -( TO_EXP_POS = ( v < 0 ? -v : v ) | 0 );\n }\n }\n r[p] = [ TO_EXP_NEG, TO_EXP_POS ];\n\n // RANGE {number|number[]} Non-zero integer, -MAX to MAX inclusive or\n // [integer -MAX to -1 inclusive, integer 1 to MAX inclusive].\n // 'config() RANGE not an integer: {v}'\n // 'config() RANGE cannot be zero: {v}'\n // 'config() RANGE out of range: {v}'\n if ( has( p = 'RANGE' ) ) {\n\n if ( isArray(v) ) {\n if ( isValidInt( v[0], -MAX, -1, 2, p ) && isValidInt( v[1], 1, MAX, 2, p ) ) {\n MIN_EXP = v[0] | 0;\n MAX_EXP = v[1] | 0;\n }\n } else if ( isValidInt( v, -MAX, MAX, 2, p ) ) {\n if ( v | 0 ) MIN_EXP = -( MAX_EXP = ( v < 0 ? -v : v ) | 0 );\n else if (ERRORS) raise( 2, p + ' cannot be zero', v );\n }\n }\n r[p] = [ MIN_EXP, MAX_EXP ];\n\n // ERRORS {boolean|number} true, false, 1 or 0.\n // 'config() ERRORS not a boolean or binary digit: {v}'\n if ( has( p = 'ERRORS' ) ) {\n\n if ( v === !!v || v === 1 || v === 0 ) {\n id = 0;\n isValidInt = ( ERRORS = !!v ) ? intValidatorWithErrors : intValidatorNoErrors;\n } else if (ERRORS) {\n raise( 2, p + notBool, v );\n }\n }\n r[p] = ERRORS;\n\n // CRYPTO {boolean|number} true, false, 1 or 0.\n // 'config() CRYPTO not a boolean or binary digit: {v}'\n // 'config() crypto unavailable: {crypto}'\n if ( has( p = 'CRYPTO' ) ) {\n\n if ( v === !!v || v === 1 || v === 0 ) {\n CRYPTO = !!( v && crypto && typeof crypto == 'object' );\n if ( v && !CRYPTO && ERRORS ) raise( 2, 'crypto unavailable', crypto );\n } else if (ERRORS) {\n raise( 2, p + notBool, v );\n }\n }\n r[p] = CRYPTO;\n\n // MODULO_MODE {number} Integer, 0 to 9 inclusive.\n // 'config() MODULO_MODE not an integer: {v}'\n // 'config() MODULO_MODE out of range: {v}'\n if ( has( p = 'MODULO_MODE' ) && isValidInt( v, 0, 9, 2, p ) ) {\n MODULO_MODE = v | 0;\n }\n r[p] = MODULO_MODE;\n\n // POW_PRECISION {number} Integer, 0 to MAX inclusive.\n // 'config() POW_PRECISION not an integer: {v}'\n // 'config() POW_PRECISION out of range: {v}'\n if ( has( p = 'POW_PRECISION' ) && isValidInt( v, 0, MAX, 2, p ) ) {\n POW_PRECISION = v | 0;\n }\n r[p] = POW_PRECISION;\n\n // FORMAT {object}\n // 'config() FORMAT not an object: {v}'\n if ( has( p = 'FORMAT' ) ) {\n\n if ( typeof v == 'object' ) {\n FORMAT = v;\n } else if (ERRORS) {\n raise( 2, p + ' not an object', v );\n }\n }\n r[p] = FORMAT;\n\n return r;\n };\n\n\n /*\n * Return a new BigNumber whose value is the maximum of the arguments.\n *\n * arguments {number|string|BigNumber}\n */\n BigNumber.max = function () { return maxOrMin( arguments, P.lt ); };\n\n\n /*\n * Return a new BigNumber whose value is the minimum of the arguments.\n *\n * arguments {number|string|BigNumber}\n */\n BigNumber.min = function () { return maxOrMin( arguments, P.gt ); };\n\n\n /*\n * Return a new BigNumber with a random value equal to or greater than 0 and less than 1,\n * and with dp, or DECIMAL_PLACES if dp is omitted, decimal places (or less if trailing\n * zeros are produced).\n *\n * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.\n *\n * 'random() decimal places not an integer: {dp}'\n * 'random() decimal places out of range: {dp}'\n * 'random() crypto unavailable: {crypto}'\n */\n BigNumber.random = (function () {\n var pow2_53 = 0x20000000000000;\n\n // Return a 53 bit integer n, where 0 <= n < 9007199254740992.\n // Check if Math.random() produces more than 32 bits of randomness.\n // If it does, assume at least 53 bits are produced, otherwise assume at least 30 bits.\n // 0x40000000 is 2^30, 0x800000 is 2^23, 0x1fffff is 2^21 - 1.\n var random53bitInt = (Math.random() * pow2_53) & 0x1fffff\n ? function () { return mathfloor( Math.random() * pow2_53 ); }\n : function () { return ((Math.random() * 0x40000000 | 0) * 0x800000) +\n (Math.random() * 0x800000 | 0); };\n\n return function (dp) {\n var a, b, e, k, v,\n i = 0,\n c = [],\n rand = new BigNumber(ONE);\n\n dp = dp == null || !isValidInt( dp, 0, MAX, 14 ) ? DECIMAL_PLACES : dp | 0;\n k = mathceil( dp / LOG_BASE );\n\n if (CRYPTO) {\n\n // Browsers supporting crypto.getRandomValues.\n if ( crypto && crypto.getRandomValues ) {\n\n a = crypto.getRandomValues( new Uint32Array( k *= 2 ) );\n\n for ( ; i < k; ) {\n\n // 53 bits:\n // ((Math.pow(2, 32) - 1) * Math.pow(2, 21)).toString(2)\n // 11111 11111111 11111111 11111111 11100000 00000000 00000000\n // ((Math.pow(2, 32) - 1) >>> 11).toString(2)\n // 11111 11111111 11111111\n // 0x20000 is 2^21.\n v = a[i] * 0x20000 + (a[i + 1] >>> 11);\n\n // Rejection sampling:\n // 0 <= v < 9007199254740992\n // Probability that v >= 9e15, is\n // 7199254740992 / 9007199254740992 ~= 0.0008, i.e. 1 in 1251\n if ( v >= 9e15 ) {\n b = crypto.getRandomValues( new Uint32Array(2) );\n a[i] = b[0];\n a[i + 1] = b[1];\n } else {\n\n // 0 <= v <= 8999999999999999\n // 0 <= (v % 1e14) <= 99999999999999\n c.push( v % 1e14 );\n i += 2;\n }\n }\n i = k / 2;\n\n // Node.js supporting crypto.randomBytes.\n } else if ( crypto && crypto.randomBytes ) {\n\n // buffer\n a = crypto.randomBytes( k *= 7 );\n\n for ( ; i < k; ) {\n\n // 0x1000000000000 is 2^48, 0x10000000000 is 2^40\n // 0x100000000 is 2^32, 0x1000000 is 2^24\n // 11111 11111111 11111111 11111111 11111111 11111111 11111111\n // 0 <= v < 9007199254740992\n v = ( ( a[i] & 31 ) * 0x1000000000000 ) + ( a[i + 1] * 0x10000000000 ) +\n ( a[i + 2] * 0x100000000 ) + ( a[i + 3] * 0x1000000 ) +\n ( a[i + 4] << 16 ) + ( a[i + 5] << 8 ) + a[i + 6];\n\n if ( v >= 9e15 ) {\n crypto.randomBytes(7).copy( a, i );\n } else {\n\n // 0 <= (v % 1e14) <= 99999999999999\n c.push( v % 1e14 );\n i += 7;\n }\n }\n i = k / 7;\n } else if (ERRORS) {\n raise( 14, 'crypto unavailable', crypto );\n }\n }\n\n // Use Math.random: CRYPTO is false or crypto is unavailable and ERRORS is false.\n if (!i) {\n\n for ( ; i < k; ) {\n v = random53bitInt();\n if ( v < 9e15 ) c[i++] = v % 1e14;\n }\n }\n\n k = c[--i];\n dp %= LOG_BASE;\n\n // Convert trailing digits to zeros according to dp.\n if ( k && dp ) {\n v = POWS_TEN[LOG_BASE - dp];\n c[i] = mathfloor( k / v ) * v;\n }\n\n // Remove trailing elements which are zero.\n for ( ; c[i] === 0; c.pop(), i-- );\n\n // Zero?\n if ( i < 0 ) {\n c = [ e = 0 ];\n } else {\n\n // Remove leading elements which are zero and adjust exponent accordingly.\n for ( e = -1 ; c[0] === 0; c.shift(), e -= LOG_BASE);\n\n // Count the digits of the first element of c to determine leading zeros, and...\n for ( i = 1, v = c[0]; v >= 10; v /= 10, i++);\n\n // adjust the exponent accordingly.\n if ( i < LOG_BASE ) e -= LOG_BASE - i;\n }\n\n rand.e = e;\n rand.c = c;\n return rand;\n };\n })();\n\n\n // PRIVATE FUNCTIONS\n\n\n // Convert a numeric string of baseIn to a numeric string of baseOut.\n function convertBase( str, baseOut, baseIn, sign ) {\n var d, e, k, r, x, xc, y,\n i = str.indexOf( '.' ),\n dp = DECIMAL_PLACES,\n rm = ROUNDING_MODE;\n\n if ( baseIn < 37 ) str = str.toLowerCase();\n\n // Non-integer.\n if ( i >= 0 ) {\n k = POW_PRECISION;\n\n // Unlimited precision.\n POW_PRECISION = 0;\n str = str.replace( '.', '' );\n y = new BigNumber(baseIn);\n x = y.pow( str.length - i );\n POW_PRECISION = k;\n\n // Convert str as if an integer, then restore the fraction part by dividing the\n // result by its base raised to a power.\n y.c = toBaseOut( toFixedPoint( coeffToString( x.c ), x.e ), 10, baseOut );\n y.e = y.c.length;\n }\n\n // Convert the number as integer.\n xc = toBaseOut( str, baseIn, baseOut );\n e = k = xc.length;\n\n // Remove trailing zeros.\n for ( ; xc[--k] == 0; xc.pop() );\n if ( !xc[0] ) return '0';\n\n if ( i < 0 ) {\n --e;\n } else {\n x.c = xc;\n x.e = e;\n\n // sign is needed for correct rounding.\n x.s = sign;\n x = div( x, y, dp, rm, baseOut );\n xc = x.c;\n r = x.r;\n e = x.e;\n }\n\n d = e + dp + 1;\n\n // The rounding digit, i.e. the digit to the right of the digit that may be rounded up.\n i = xc[d];\n k = baseOut / 2;\n r = r || d < 0 || xc[d + 1] != null;\n\n r = rm < 4 ? ( i != null || r ) && ( rm == 0 || rm == ( x.s < 0 ? 3 : 2 ) )\n : i > k || i == k &&( rm == 4 || r || rm == 6 && xc[d - 1] & 1 ||\n rm == ( x.s < 0 ? 8 : 7 ) );\n\n if ( d < 1 || !xc[0] ) {\n\n // 1^-dp or 0.\n str = r ? toFixedPoint( '1', -dp ) : '0';\n } else {\n xc.length = d;\n\n if (r) {\n\n // Rounding up may mean the previous digit has to be rounded up and so on.\n for ( --baseOut; ++xc[--d] > baseOut; ) {\n xc[d] = 0;\n\n if ( !d ) {\n ++e;\n xc.unshift(1);\n }\n }\n }\n\n // Determine trailing zeros.\n for ( k = xc.length; !xc[--k]; );\n\n // E.g. [4, 11, 15] becomes 4bf.\n for ( i = 0, str = ''; i <= k; str += ALPHABET.charAt( xc[i++] ) );\n str = toFixedPoint( str, e );\n }\n\n // The caller will add the sign.\n return str;\n }\n\n\n // Perform division in the specified base. Called by div and convertBase.\n div = (function () {\n\n // Assume non-zero x and k.\n function multiply( x, k, base ) {\n var m, temp, xlo, xhi,\n carry = 0,\n i = x.length,\n klo = k % SQRT_BASE,\n khi = k / SQRT_BASE | 0;\n\n for ( x = x.slice(); i--; ) {\n xlo = x[i] % SQRT_BASE;\n xhi = x[i] / SQRT_BASE | 0;\n m = khi * xlo + xhi * klo;\n temp = klo * xlo + ( ( m % SQRT_BASE ) * SQRT_BASE ) + carry;\n carry = ( temp / base | 0 ) + ( m / SQRT_BASE | 0 ) + khi * xhi;\n x[i] = temp % base;\n }\n\n if (carry) x.unshift(carry);\n\n return x;\n }\n\n function compare( a, b, aL, bL ) {\n var i, cmp;\n\n if ( aL != bL ) {\n cmp = aL > bL ? 1 : -1;\n } else {\n\n for ( i = cmp = 0; i < aL; i++ ) {\n\n if ( a[i] != b[i] ) {\n cmp = a[i] > b[i] ? 1 : -1;\n break;\n }\n }\n }\n return cmp;\n }\n\n function subtract( a, b, aL, base ) {\n var i = 0;\n\n // Subtract b from a.\n for ( ; aL--; ) {\n a[aL] -= i;\n i = a[aL] < b[aL] ? 1 : 0;\n a[aL] = i * base + a[aL] - b[aL];\n }\n\n // Remove leading zeros.\n for ( ; !a[0] && a.length > 1; a.shift() );\n }\n\n // x: dividend, y: divisor.\n return function ( x, y, dp, rm, base ) {\n var cmp, e, i, more, n, prod, prodL, q, qc, rem, remL, rem0, xi, xL, yc0,\n yL, yz,\n s = x.s == y.s ? 1 : -1,\n xc = x.c,\n yc = y.c;\n\n // Either NaN, Infinity or 0?\n if ( !xc || !xc[0] || !yc || !yc[0] ) {\n\n return new BigNumber(\n\n // Return NaN if either NaN, or both Infinity or 0.\n !x.s || !y.s || ( xc ? yc && xc[0] == yc[0] : !yc ) ? NaN :\n\n // Return ±0 if x is ±0 or y is ±Infinity, or return ±Infinity as y is ±0.\n xc && xc[0] == 0 || !yc ? s * 0 : s / 0\n );\n }\n\n q = new BigNumber(s);\n qc = q.c = [];\n e = x.e - y.e;\n s = dp + e + 1;\n\n if ( !base ) {\n base = BASE;\n e = bitFloor( x.e / LOG_BASE ) - bitFloor( y.e / LOG_BASE );\n s = s / LOG_BASE | 0;\n }\n\n // Result exponent may be one less then the current value of e.\n // The coefficients of the BigNumbers from convertBase may have trailing zeros.\n for ( i = 0; yc[i] == ( xc[i] || 0 ); i++ );\n if ( yc[i] > ( xc[i] || 0 ) ) e--;\n\n if ( s < 0 ) {\n qc.push(1);\n more = true;\n } else {\n xL = xc.length;\n yL = yc.length;\n i = 0;\n s += 2;\n\n // Normalise xc and yc so highest order digit of yc is >= base / 2.\n\n n = mathfloor( base / ( yc[0] + 1 ) );\n\n // Not necessary, but to handle odd bases where yc[0] == ( base / 2 ) - 1.\n // if ( n > 1 || n++ == 1 && yc[0] < base / 2 ) {\n if ( n > 1 ) {\n yc = multiply( yc, n, base );\n xc = multiply( xc, n, base );\n yL = yc.length;\n xL = xc.length;\n }\n\n xi = yL;\n rem = xc.slice( 0, yL );\n remL = rem.length;\n\n // Add zeros to make remainder as long as divisor.\n for ( ; remL < yL; rem[remL++] = 0 );\n yz = yc.slice();\n yz.unshift(0);\n yc0 = yc[0];\n if ( yc[1] >= base / 2 ) yc0++;\n // Not necessary, but to prevent trial digit n > base, when using base 3.\n // else if ( base == 3 && yc0 == 1 ) yc0 = 1 + 1e-15;\n\n do {\n n = 0;\n\n // Compare divisor and remainder.\n cmp = compare( yc, rem, yL, remL );\n\n // If divisor < remainder.\n if ( cmp < 0 ) {\n\n // Calculate trial digit, n.\n\n rem0 = rem[0];\n if ( yL != remL ) rem0 = rem0 * base + ( rem[1] || 0 );\n\n // n is how many times the divisor goes into the current remainder.\n n = mathfloor( rem0 / yc0 );\n\n // Algorithm:\n // 1. product = divisor * trial digit (n)\n // 2. if product > remainder: product -= divisor, n--\n // 3. remainder -= product\n // 4. if product was < remainder at 2:\n // 5. compare new remainder and divisor\n // 6. If remainder > divisor: remainder -= divisor, n++\n\n if ( n > 1 ) {\n\n // n may be > base only when base is 3.\n if (n >= base) n = base - 1;\n\n // product = divisor * trial digit.\n prod = multiply( yc, n, base );\n prodL = prod.length;\n remL = rem.length;\n\n // Compare product and remainder.\n // If product > remainder.\n // Trial digit n too high.\n // n is 1 too high about 5% of the time, and is not known to have\n // ever been more than 1 too high.\n while ( compare( prod, rem, prodL, remL ) == 1 ) {\n n--;\n\n // Subtract divisor from product.\n subtract( prod, yL < prodL ? yz : yc, prodL, base );\n prodL = prod.length;\n cmp = 1;\n }\n } else {\n\n // n is 0 or 1, cmp is -1.\n // If n is 0, there is no need to compare yc and rem again below,\n // so change cmp to 1 to avoid it.\n // If n is 1, leave cmp as -1, so yc and rem are compared again.\n if ( n == 0 ) {\n\n // divisor < remainder, so n must be at least 1.\n cmp = n = 1;\n }\n\n // product = divisor\n prod = yc.slice();\n prodL = prod.length;\n }\n\n if ( prodL < remL ) prod.unshift(0);\n\n // Subtract product from remainder.\n subtract( rem, prod, remL, base );\n remL = rem.length;\n\n // If product was < remainder.\n if ( cmp == -1 ) {\n\n // Compare divisor and new remainder.\n // If divisor < new remainder, subtract divisor from remainder.\n // Trial digit n too low.\n // n is 1 too low about 5% of the time, and very rarely 2 too low.\n while ( compare( yc, rem, yL, remL ) < 1 ) {\n n++;\n\n // Subtract divisor from remainder.\n subtract( rem, yL < remL ? yz : yc, remL, base );\n remL = rem.length;\n }\n }\n } else if ( cmp === 0 ) {\n n++;\n rem = [0];\n } // else cmp === 1 and n will be 0\n\n // Add the next digit, n, to the result array.\n qc[i++] = n;\n\n // Update the remainder.\n if ( rem[0] ) {\n rem[remL++] = xc[xi] || 0;\n } else {\n rem = [ xc[xi] ];\n remL = 1;\n }\n } while ( ( xi++ < xL || rem[0] != null ) && s-- );\n\n more = rem[0] != null;\n\n // Leading zero?\n if ( !qc[0] ) qc.shift();\n }\n\n if ( base == BASE ) {\n\n // To calculate q.e, first get the number of digits of qc[0].\n for ( i = 1, s = qc[0]; s >= 10; s /= 10, i++ );\n round( q, dp + ( q.e = i + e * LOG_BASE - 1 ) + 1, rm, more );\n\n // Caller is convertBase.\n } else {\n q.e = e;\n q.r = +more;\n }\n\n return q;\n };\n })();\n\n\n /*\n * Return a string representing the value of BigNumber n in fixed-point or exponential\n * notation rounded to the specified decimal places or significant digits.\n *\n * n is a BigNumber.\n * i is the index of the last digit required (i.e. the digit that may be rounded up).\n * rm is the rounding mode.\n * caller is caller id: toExponential 19, toFixed 20, toFormat 21, toPrecision 24.\n */\n function format( n, i, rm, caller ) {\n var c0, e, ne, len, str;\n\n rm = rm != null && isValidInt( rm, 0, 8, caller, roundingMode )\n ? rm | 0 : ROUNDING_MODE;\n\n if ( !n.c ) return n.toString();\n c0 = n.c[0];\n ne = n.e;\n\n if ( i == null ) {\n str = coeffToString( n.c );\n str = caller == 19 || caller == 24 && ne <= TO_EXP_NEG\n ? toExponential( str, ne )\n : toFixedPoint( str, ne );\n } else {\n n = round( new BigNumber(n), i, rm );\n\n // n.e may have changed if the value was rounded up.\n e = n.e;\n\n str = coeffToString( n.c );\n len = str.length;\n\n // toPrecision returns exponential notation if the number of significant digits\n // specified is less than the number of digits necessary to represent the integer\n // part of the value in fixed-point notation.\n\n // Exponential notation.\n if ( caller == 19 || caller == 24 && ( i <= e || e <= TO_EXP_NEG ) ) {\n\n // Append zeros?\n for ( ; len < i; str += '0', len++ );\n str = toExponential( str, e );\n\n // Fixed-point notation.\n } else {\n i -= ne;\n str = toFixedPoint( str, e );\n\n // Append zeros?\n if ( e + 1 > len ) {\n if ( --i > 0 ) for ( str += '.'; i--; str += '0' );\n } else {\n i += e - len;\n if ( i > 0 ) {\n if ( e + 1 == len ) str += '.';\n for ( ; i--; str += '0' );\n }\n }\n }\n }\n\n return n.s < 0 && c0 ? '-' + str : str;\n }\n\n\n // Handle BigNumber.max and BigNumber.min.\n function maxOrMin( args, method ) {\n var m, n,\n i = 0;\n\n if ( isArray( args[0] ) ) args = args[0];\n m = new BigNumber( args[0] );\n\n for ( ; ++i < args.length; ) {\n n = new BigNumber( args[i] );\n\n // If any number is NaN, return NaN.\n if ( !n.s ) {\n m = n;\n break;\n } else if ( method.call( m, n ) ) {\n m = n;\n }\n }\n\n return m;\n }\n\n\n /*\n * Return true if n is an integer in range, otherwise throw.\n * Use for argument validation when ERRORS is true.\n */\n function intValidatorWithErrors( n, min, max, caller, name ) {\n if ( n < min || n > max || n != truncate(n) ) {\n raise( caller, ( name || 'decimal places' ) +\n ( n < min || n > max ? ' out of range' : ' not an integer' ), n );\n }\n\n return true;\n }\n\n\n /*\n * Strip trailing zeros, calculate base 10 exponent and check against MIN_EXP and MAX_EXP.\n * Called by minus, plus and times.\n */\n function normalise( n, c, e ) {\n var i = 1,\n j = c.length;\n\n // Remove trailing zeros.\n for ( ; !c[--j]; c.pop() );\n\n // Calculate the base 10 exponent. First get the number of digits of c[0].\n for ( j = c[0]; j >= 10; j /= 10, i++ );\n\n // Overflow?\n if ( ( e = i + e * LOG_BASE - 1 ) > MAX_EXP ) {\n\n // Infinity.\n n.c = n.e = null;\n\n // Underflow?\n } else if ( e < MIN_EXP ) {\n\n // Zero.\n n.c = [ n.e = 0 ];\n } else {\n n.e = e;\n n.c = c;\n }\n\n return n;\n }\n\n\n // Handle values that fail the validity test in BigNumber.\n parseNumeric = (function () {\n var basePrefix = /^(-?)0([xbo])/i,\n dotAfter = /^([^.]+)\\.$/,\n dotBefore = /^\\.([^.]+)$/,\n isInfinityOrNaN = /^-?(Infinity|NaN)$/,\n whitespaceOrPlus = /^\\s*\\+|^\\s+|\\s+$/g;\n\n return function ( x, str, num, b ) {\n var base,\n s = num ? str : str.replace( whitespaceOrPlus, '' );\n\n // No exception on ±Infinity or NaN.\n if ( isInfinityOrNaN.test(s) ) {\n x.s = isNaN(s) ? null : s < 0 ? -1 : 1;\n } else {\n if ( !num ) {\n\n // basePrefix = /^(-?)0([xbo])(?=\\w[\\w.]*$)/i\n s = s.replace( basePrefix, function ( m, p1, p2 ) {\n base = ( p2 = p2.toLowerCase() ) == 'x' ? 16 : p2 == 'b' ? 2 : 8;\n return !b || b == base ? p1 : m;\n });\n\n if (b) {\n base = b;\n\n // E.g. '1.' to '1', '.1' to '0.1'\n s = s.replace( dotAfter, '$1' ).replace( dotBefore, '0.$1' );\n }\n\n if ( str != s ) return new BigNumber( s, base );\n }\n\n // 'new BigNumber() not a number: {n}'\n // 'new BigNumber() not a base {b} number: {n}'\n if (ERRORS) raise( id, 'not a' + ( b ? ' base ' + b : '' ) + ' number', str );\n x.s = null;\n }\n\n x.c = x.e = null;\n id = 0;\n }\n })();\n\n\n // Throw a BigNumber Error.\n function raise( caller, msg, val ) {\n var error = new Error( [\n 'new BigNumber', // 0\n 'cmp', // 1\n 'config', // 2\n 'div', // 3\n 'divToInt', // 4\n 'eq', // 5\n 'gt', // 6\n 'gte', // 7\n 'lt', // 8\n 'lte', // 9\n 'minus', // 10\n 'mod', // 11\n 'plus', // 12\n 'precision', // 13\n 'random', // 14\n 'round', // 15\n 'shift', // 16\n 'times', // 17\n 'toDigits', // 18\n 'toExponential', // 19\n 'toFixed', // 20\n 'toFormat', // 21\n 'toFraction', // 22\n 'pow', // 23\n 'toPrecision', // 24\n 'toString', // 25\n 'BigNumber' // 26\n ][caller] + '() ' + msg + ': ' + val );\n\n error.name = 'BigNumber Error';\n id = 0;\n throw error;\n }\n\n\n /*\n * Round x to sd significant digits using rounding mode rm. Check for over/under-flow.\n * If r is truthy, it is known that there are more digits after the rounding digit.\n */\n function round( x, sd, rm, r ) {\n var d, i, j, k, n, ni, rd,\n xc = x.c,\n pows10 = POWS_TEN;\n\n // if x is not Infinity or NaN...\n if (xc) {\n\n // rd is the rounding digit, i.e. the digit after the digit that may be rounded up.\n // n is a base 1e14 number, the value of the element of array x.c containing rd.\n // ni is the index of n within x.c.\n // d is the number of digits of n.\n // i is the index of rd within n including leading zeros.\n // j is the actual index of rd within n (if < 0, rd is a leading zero).\n out: {\n\n // Get the number of digits of the first element of xc.\n for ( d = 1, k = xc[0]; k >= 10; k /= 10, d++ );\n i = sd - d;\n\n // If the rounding digit is in the first element of xc...\n if ( i < 0 ) {\n i += LOG_BASE;\n j = sd;\n n = xc[ ni = 0 ];\n\n // Get the rounding digit at index j of n.\n rd = n / pows10[ d - j - 1 ] % 10 | 0;\n } else {\n ni = mathceil( ( i + 1 ) / LOG_BASE );\n\n if ( ni >= xc.length ) {\n\n if (r) {\n\n // Needed by sqrt.\n for ( ; xc.length <= ni; xc.push(0) );\n n = rd = 0;\n d = 1;\n i %= LOG_BASE;\n j = i - LOG_BASE + 1;\n } else {\n break out;\n }\n } else {\n n = k = xc[ni];\n\n // Get the number of digits of n.\n for ( d = 1; k >= 10; k /= 10, d++ );\n\n // Get the index of rd within n.\n i %= LOG_BASE;\n\n // Get the index of rd within n, adjusted for leading zeros.\n // The number of leading zeros of n is given by LOG_BASE - d.\n j = i - LOG_BASE + d;\n\n // Get the rounding digit at index j of n.\n rd = j < 0 ? 0 : n / pows10[ d - j - 1 ] % 10 | 0;\n }\n }\n\n r = r || sd < 0 ||\n\n // Are there any non-zero digits after the rounding digit?\n // The expression n % pows10[ d - j - 1 ] returns all digits of n to the right\n // of the digit at j, e.g. if n is 908714 and j is 2, the expression gives 714.\n xc[ni + 1] != null || ( j < 0 ? n : n % pows10[ d - j - 1 ] );\n\n r = rm < 4\n ? ( rd || r ) && ( rm == 0 || rm == ( x.s < 0 ? 3 : 2 ) )\n : rd > 5 || rd == 5 && ( rm == 4 || r || rm == 6 &&\n\n // Check whether the digit to the left of the rounding digit is odd.\n ( ( i > 0 ? j > 0 ? n / pows10[ d - j ] : 0 : xc[ni - 1] ) % 10 ) & 1 ||\n rm == ( x.s < 0 ? 8 : 7 ) );\n\n if ( sd < 1 || !xc[0] ) {\n xc.length = 0;\n\n if (r) {\n\n // Convert sd to decimal places.\n sd -= x.e + 1;\n\n // 1, 0.1, 0.01, 0.001, 0.0001 etc.\n xc[0] = pows10[ sd % LOG_BASE ];\n x.e = -sd || 0;\n } else {\n\n // Zero.\n xc[0] = x.e = 0;\n }\n\n return x;\n }\n\n // Remove excess digits.\n if ( i == 0 ) {\n xc.length = ni;\n k = 1;\n ni--;\n } else {\n xc.length = ni + 1;\n k = pows10[ LOG_BASE - i ];\n\n // E.g. 56700 becomes 56000 if 7 is the rounding digit.\n // j > 0 means i > number of leading zeros of n.\n xc[ni] = j > 0 ? mathfloor( n / pows10[ d - j ] % pows10[j] ) * k : 0;\n }\n\n // Round up?\n if (r) {\n\n for ( ; ; ) {\n\n // If the digit to be rounded up is in the first element of xc...\n if ( ni == 0 ) {\n\n // i will be the length of xc[0] before k is added.\n for ( i = 1, j = xc[0]; j >= 10; j /= 10, i++ );\n j = xc[0] += k;\n for ( k = 1; j >= 10; j /= 10, k++ );\n\n // if i != k the length has increased.\n if ( i != k ) {\n x.e++;\n if ( xc[0] == BASE ) xc[0] = 1;\n }\n\n break;\n } else {\n xc[ni] += k;\n if ( xc[ni] != BASE ) break;\n xc[ni--] = 0;\n k = 1;\n }\n }\n }\n\n // Remove trailing zeros.\n for ( i = xc.length; xc[--i] === 0; xc.pop() );\n }\n\n // Overflow? Infinity.\n if ( x.e > MAX_EXP ) {\n x.c = x.e = null;\n\n // Underflow? Zero.\n } else if ( x.e < MIN_EXP ) {\n x.c = [ x.e = 0 ];\n }\n }\n\n return x;\n }\n\n\n // PROTOTYPE/INSTANCE METHODS\n\n\n /*\n * Return a new BigNumber whose value is the absolute value of this BigNumber.\n */\n P.absoluteValue = P.abs = function () {\n var x = new BigNumber(this);\n if ( x.s < 0 ) x.s = 1;\n return x;\n };\n\n\n /*\n * Return a new BigNumber whose value is the value of this BigNumber rounded to a whole\n * number in the direction of Infinity.\n */\n P.ceil = function () {\n return round( new BigNumber(this), this.e + 1, 2 );\n };\n\n\n /*\n * Return\n * 1 if the value of this BigNumber is greater than the value of BigNumber(y, b),\n * -1 if the value of this BigNumber is less than the value of BigNumber(y, b),\n * 0 if they have the same value,\n * or null if the value of either is NaN.\n */\n P.comparedTo = P.cmp = function ( y, b ) {\n id = 1;\n return compare( this, new BigNumber( y, b ) );\n };\n\n\n /*\n * Return the number of decimal places of the value of this BigNumber, or null if the value\n * of this BigNumber is ±Infinity or NaN.\n */\n P.decimalPlaces = P.dp = function () {\n var n, v,\n c = this.c;\n\n if ( !c ) return null;\n n = ( ( v = c.length - 1 ) - bitFloor( this.e / LOG_BASE ) ) * LOG_BASE;\n\n // Subtract the number of trailing zeros of the last number.\n if ( v = c[v] ) for ( ; v % 10 == 0; v /= 10, n-- );\n if ( n < 0 ) n = 0;\n\n return n;\n };\n\n\n /*\n * n / 0 = I\n * n / N = N\n * n / I = 0\n * 0 / n = 0\n * 0 / 0 = N\n * 0 / N = N\n * 0 / I = 0\n * N / n = N\n * N / 0 = N\n * N / N = N\n * N / I = N\n * I / n = I\n * I / 0 = I\n * I / N = N\n * I / I = N\n *\n * Return a new BigNumber whose value is the value of this BigNumber divided by the value of\n * BigNumber(y, b), rounded according to DECIMAL_PLACES and ROUNDING_MODE.\n */\n P.dividedBy = P.div = function ( y, b ) {\n id = 3;\n return div( this, new BigNumber( y, b ), DECIMAL_PLACES, ROUNDING_MODE );\n };\n\n\n /*\n * Return a new BigNumber whose value is the integer part of dividing the value of this\n * BigNumber by the value of BigNumber(y, b).\n */\n P.dividedToIntegerBy = P.divToInt = function ( y, b ) {\n id = 4;\n return div( this, new BigNumber( y, b ), 0, 1 );\n };\n\n\n /*\n * Return true if the value of this BigNumber is equal to the value of BigNumber(y, b),\n * otherwise returns false.\n */\n P.equals = P.eq = function ( y, b ) {\n id = 5;\n return compare( this, new BigNumber( y, b ) ) === 0;\n };\n\n\n /*\n * Return a new BigNumber whose value is the value of this BigNumber rounded to a whole\n * number in the direction of -Infinity.\n */\n P.floor = function () {\n return round( new BigNumber(this), this.e + 1, 3 );\n };\n\n\n /*\n * Return true if the value of this BigNumber is greater than the value of BigNumber(y, b),\n * otherwise returns false.\n */\n P.greaterThan = P.gt = function ( y, b ) {\n id = 6;\n return compare( this, new BigNumber( y, b ) ) > 0;\n };\n\n\n /*\n * Return true if the value of this BigNumber is greater than or equal to the value of\n * BigNumber(y, b), otherwise returns false.\n */\n P.greaterThanOrEqualTo = P.gte = function ( y, b ) {\n id = 7;\n return ( b = compare( this, new BigNumber( y, b ) ) ) === 1 || b === 0;\n\n };\n\n\n /*\n * Return true if the value of this BigNumber is a finite number, otherwise returns false.\n */\n P.isFinite = function () {\n return !!this.c;\n };\n\n\n /*\n * Return true if the value of this BigNumber is an integer, otherwise return false.\n */\n P.isInteger = P.isInt = function () {\n return !!this.c && bitFloor( this.e / LOG_BASE ) > this.c.length - 2;\n };\n\n\n /*\n * Return true if the value of this BigNumber is NaN, otherwise returns false.\n */\n P.isNaN = function () {\n return !this.s;\n };\n\n\n /*\n * Return true if the value of this BigNumber is negative, otherwise returns false.\n */\n P.isNegative = P.isNeg = function () {\n return this.s < 0;\n };\n\n\n /*\n * Return true if the value of this BigNumber is 0 or -0, otherwise returns false.\n */\n P.isZero = function () {\n return !!this.c && this.c[0] == 0;\n };\n\n\n /*\n * Return true if the value of this BigNumber is less than the value of BigNumber(y, b),\n * otherwise returns false.\n */\n P.lessThan = P.lt = function ( y, b ) {\n id = 8;\n return compare( this, new BigNumber( y, b ) ) < 0;\n };\n\n\n /*\n * Return true if the value of this BigNumber is less than or equal to the value of\n * BigNumber(y, b), otherwise returns false.\n */\n P.lessThanOrEqualTo = P.lte = function ( y, b ) {\n id = 9;\n return ( b = compare( this, new BigNumber( y, b ) ) ) === -1 || b === 0;\n };\n\n\n /*\n * n - 0 = n\n * n - N = N\n * n - I = -I\n * 0 - n = -n\n * 0 - 0 = 0\n * 0 - N = N\n * 0 - I = -I\n * N - n = N\n * N - 0 = N\n * N - N = N\n * N - I = N\n * I - n = I\n * I - 0 = I\n * I - N = N\n * I - I = N\n *\n * Return a new BigNumber whose value is the value of this BigNumber minus the value of\n * BigNumber(y, b).\n */\n P.minus = P.sub = function ( y, b ) {\n var i, j, t, xLTy,\n x = this,\n a = x.s;\n\n id = 10;\n y = new BigNumber( y, b );\n b = y.s;\n\n // Either NaN?\n if ( !a || !b ) return new BigNumber(NaN);\n\n // Signs differ?\n if ( a != b ) {\n y.s = -b;\n return x.plus(y);\n }\n\n var xe = x.e / LOG_BASE,\n ye = y.e / LOG_BASE,\n xc = x.c,\n yc = y.c;\n\n if ( !xe || !ye ) {\n\n // Either Infinity?\n if ( !xc || !yc ) return xc ? ( y.s = -b, y ) : new BigNumber( yc ? x : NaN );\n\n // Either zero?\n if ( !xc[0] || !yc[0] ) {\n\n // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.\n return yc[0] ? ( y.s = -b, y ) : new BigNumber( xc[0] ? x :\n\n // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity\n ROUNDING_MODE == 3 ? -0 : 0 );\n }\n }\n\n xe = bitFloor(xe);\n ye = bitFloor(ye);\n xc = xc.slice();\n\n // Determine which is the bigger number.\n if ( a = xe - ye ) {\n\n if ( xLTy = a < 0 ) {\n a = -a;\n t = xc;\n } else {\n ye = xe;\n t = yc;\n }\n\n t.reverse();\n\n // Prepend zeros to equalise exponents.\n for ( b = a; b--; t.push(0) );\n t.reverse();\n } else {\n\n // Exponents equal. Check digit by digit.\n j = ( xLTy = ( a = xc.length ) < ( b = yc.length ) ) ? a : b;\n\n for ( a = b = 0; b < j; b++ ) {\n\n if ( xc[b] != yc[b] ) {\n xLTy = xc[b] < yc[b];\n break;\n }\n }\n }\n\n // x < y? Point xc to the array of the bigger number.\n if (xLTy) t = xc, xc = yc, yc = t, y.s = -y.s;\n\n b = ( j = yc.length ) - ( i = xc.length );\n\n // Append zeros to xc if shorter.\n // No need to add zeros to yc if shorter as subtract only needs to start at yc.length.\n if ( b > 0 ) for ( ; b--; xc[i++] = 0 );\n b = BASE - 1;\n\n // Subtract yc from xc.\n for ( ; j > a; ) {\n\n if ( xc[--j] < yc[j] ) {\n for ( i = j; i && !xc[--i]; xc[i] = b );\n --xc[i];\n xc[j] += BASE;\n }\n\n xc[j] -= yc[j];\n }\n\n // Remove leading zeros and adjust exponent accordingly.\n for ( ; xc[0] == 0; xc.shift(), --ye );\n\n // Zero?\n if ( !xc[0] ) {\n\n // Following IEEE 754 (2008) 6.3,\n // n - n = +0 but n - n = -0 when rounding towards -Infinity.\n y.s = ROUNDING_MODE == 3 ? -1 : 1;\n y.c = [ y.e = 0 ];\n return y;\n }\n\n // No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity\n // for finite x and y.\n return normalise( y, xc, ye );\n };\n\n\n /*\n * n % 0 = N\n * n % N = N\n * n % I = n\n * 0 % n = 0\n * -0 % n = -0\n * 0 % 0 = N\n * 0 % N = N\n * 0 % I = 0\n * N % n = N\n * N % 0 = N\n * N % N = N\n * N % I = N\n * I % n = N\n * I % 0 = N\n * I % N = N\n * I % I = N\n *\n * Return a new BigNumber whose value is the value of this BigNumber modulo the value of\n * BigNumber(y, b). The result depends on the value of MODULO_MODE.\n */\n P.modulo = P.mod = function ( y, b ) {\n var q, s,\n x = this;\n\n id = 11;\n y = new BigNumber( y, b );\n\n // Return NaN if x is Infinity or NaN, or y is NaN or zero.\n if ( !x.c || !y.s || y.c && !y.c[0] ) {\n return new BigNumber(NaN);\n\n // Return x if y is Infinity or x is zero.\n } else if ( !y.c || x.c && !x.c[0] ) {\n return new BigNumber(x);\n }\n\n if ( MODULO_MODE == 9 ) {\n\n // Euclidian division: q = sign(y) * floor(x / abs(y))\n // r = x - qy where 0 <= r < abs(y)\n s = y.s;\n y.s = 1;\n q = div( x, y, 0, 3 );\n y.s = s;\n q.s *= s;\n } else {\n q = div( x, y, 0, MODULO_MODE );\n }\n\n return x.minus( q.times(y) );\n };\n\n\n /*\n * Return a new BigNumber whose value is the value of this BigNumber negated,\n * i.e. multiplied by -1.\n */\n P.negated = P.neg = function () {\n var x = new BigNumber(this);\n x.s = -x.s || null;\n return x;\n };\n\n\n /*\n * n + 0 = n\n * n + N = N\n * n + I = I\n * 0 + n = n\n * 0 + 0 = 0\n * 0 + N = N\n * 0 + I = I\n * N + n = N\n * N + 0 = N\n * N + N = N\n * N + I = N\n * I + n = I\n * I + 0 = I\n * I + N = N\n * I + I = I\n *\n * Return a new BigNumber whose value is the value of this BigNumber plus the value of\n * BigNumber(y, b).\n */\n P.plus = P.add = function ( y, b ) {\n var t,\n x = this,\n a = x.s;\n\n id = 12;\n y = new BigNumber( y, b );\n b = y.s;\n\n // Either NaN?\n if ( !a || !b ) return new BigNumber(NaN);\n\n // Signs differ?\n if ( a != b ) {\n y.s = -b;\n return x.minus(y);\n }\n\n var xe = x.e / LOG_BASE,\n ye = y.e / LOG_BASE,\n xc = x.c,\n yc = y.c;\n\n if ( !xe || !ye ) {\n\n // Return ±Infinity if either ±Infinity.\n if ( !xc || !yc ) return new BigNumber( a / 0 );\n\n // Either zero?\n // Return y if y is non-zero, x if x is non-zero, or zero if both are zero.\n if ( !xc[0] || !yc[0] ) return yc[0] ? y : new BigNumber( xc[0] ? x : a * 0 );\n }\n\n xe = bitFloor(xe);\n ye = bitFloor(ye);\n xc = xc.slice();\n\n // Prepend zeros to equalise exponents. Faster to use reverse then do unshifts.\n if ( a = xe - ye ) {\n if ( a > 0 ) {\n ye = xe;\n t = yc;\n } else {\n a = -a;\n t = xc;\n }\n\n t.reverse();\n for ( ; a--; t.push(0) );\n t.reverse();\n }\n\n a = xc.length;\n b = yc.length;\n\n // Point xc to the longer array, and b to the shorter length.\n if ( a - b < 0 ) t = yc, yc = xc, xc = t, b = a;\n\n // Only start adding at yc.length - 1 as the further digits of xc can be ignored.\n for ( a = 0; b; ) {\n a = ( xc[--b] = xc[b] + yc[b] + a ) / BASE | 0;\n xc[b] %= BASE;\n }\n\n if (a) {\n xc.unshift(a);\n ++ye;\n }\n\n // No need to check for zero, as +x + +y != 0 && -x + -y != 0\n // ye = MAX_EXP + 1 possible\n return normalise( y, xc, ye );\n };\n\n\n /*\n * Return the number of significant digits of the value of this BigNumber.\n *\n * [z] {boolean|number} Whether to count integer-part trailing zeros: true, false, 1 or 0.\n */\n P.precision = P.sd = function (z) {\n var n, v,\n x = this,\n c = x.c;\n\n // 'precision() argument not a boolean or binary digit: {z}'\n if ( z != null && z !== !!z && z !== 1 && z !== 0 ) {\n if (ERRORS) raise( 13, 'argument' + notBool, z );\n if ( z != !!z ) z = null;\n }\n\n if ( !c ) return null;\n v = c.length - 1;\n n = v * LOG_BASE + 1;\n\n if ( v = c[v] ) {\n\n // Subtract the number of trailing zeros of the last element.\n for ( ; v % 10 == 0; v /= 10, n-- );\n\n // Add the number of digits of the first element.\n for ( v = c[0]; v >= 10; v /= 10, n++ );\n }\n\n if ( z && x.e + 1 > n ) n = x.e + 1;\n\n return n;\n };\n\n\n /*\n * Return a new BigNumber whose value is the value of this BigNumber rounded to a maximum of\n * dp decimal places using rounding mode rm, or to 0 and ROUNDING_MODE respectively if\n * omitted.\n *\n * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\n *\n * 'round() decimal places out of range: {dp}'\n * 'round() decimal places not an integer: {dp}'\n * 'round() rounding mode not an integer: {rm}'\n * 'round() rounding mode out of range: {rm}'\n */\n P.round = function ( dp, rm ) {\n var n = new BigNumber(this);\n\n if ( dp == null || isValidInt( dp, 0, MAX, 15 ) ) {\n round( n, ~~dp + this.e + 1, rm == null ||\n !isValidInt( rm, 0, 8, 15, roundingMode ) ? ROUNDING_MODE : rm | 0 );\n }\n\n return n;\n };\n\n\n /*\n * Return a new BigNumber whose value is the value of this BigNumber shifted by k places\n * (powers of 10). Shift to the right if n > 0, and to the left if n < 0.\n *\n * k {number} Integer, -MAX_SAFE_INTEGER to MAX_SAFE_INTEGER inclusive.\n *\n * If k is out of range and ERRORS is false, the result will be ±0 if k < 0, or ±Infinity\n * otherwise.\n *\n * 'shift() argument not an integer: {k}'\n * 'shift() argument out of range: {k}'\n */\n P.shift = function (k) {\n var n = this;\n return isValidInt( k, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 16, 'argument' )\n\n // k < 1e+21, or truncate(k) will produce exponential notation.\n ? n.times( '1e' + truncate(k) )\n : new BigNumber( n.c && n.c[0] && ( k < -MAX_SAFE_INTEGER || k > MAX_SAFE_INTEGER )\n ? n.s * ( k < 0 ? 0 : 1 / 0 )\n : n );\n };\n\n\n /*\n * sqrt(-n) = N\n * sqrt( N) = N\n * sqrt(-I) = N\n * sqrt( I) = I\n * sqrt( 0) = 0\n * sqrt(-0) = -0\n *\n * Return a new BigNumber whose value is the square root of the value of this BigNumber,\n * rounded according to DECIMAL_PLACES and ROUNDING_MODE.\n */\n P.squareRoot = P.sqrt = function () {\n var m, n, r, rep, t,\n x = this,\n c = x.c,\n s = x.s,\n e = x.e,\n dp = DECIMAL_PLACES + 4,\n half = new BigNumber('0.5');\n\n // Negative/NaN/Infinity/zero?\n if ( s !== 1 || !c || !c[0] ) {\n return new BigNumber( !s || s < 0 && ( !c || c[0] ) ? NaN : c ? x : 1 / 0 );\n }\n\n // Initial estimate.\n s = Math.sqrt( +x );\n\n // Math.sqrt underflow/overflow?\n // Pass x to Math.sqrt as integer, then adjust the exponent of the result.\n if ( s == 0 || s == 1 / 0 ) {\n n = coeffToString(c);\n if ( ( n.length + e ) % 2 == 0 ) n += '0';\n s = Math.sqrt(n);\n e = bitFloor( ( e + 1 ) / 2 ) - ( e < 0 || e % 2 );\n\n if ( s == 1 / 0 ) {\n n = '1e' + e;\n } else {\n n = s.toExponential();\n n = n.slice( 0, n.indexOf('e') + 1 ) + e;\n }\n\n r = new BigNumber(n);\n } else {\n r = new BigNumber( s + '' );\n }\n\n // Check for zero.\n // r could be zero if MIN_EXP is changed after the this value was created.\n // This would cause a division by zero (x/t) and hence Infinity below, which would cause\n // coeffToString to throw.\n if ( r.c[0] ) {\n e = r.e;\n s = e + dp;\n if ( s < 3 ) s = 0;\n\n // Newton-Raphson iteration.\n for ( ; ; ) {\n t = r;\n r = half.times( t.plus( div( x, t, dp, 1 ) ) );\n\n if ( coeffToString( t.c ).slice( 0, s ) === ( n =\n coeffToString( r.c ) ).slice( 0, s ) ) {\n\n // The exponent of r may here be one less than the final result exponent,\n // e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits\n // are indexed correctly.\n if ( r.e < e ) --s;\n n = n.slice( s - 3, s + 1 );\n\n // The 4th rounding digit may be in error by -1 so if the 4 rounding digits\n // are 9999 or 4999 (i.e. approaching a rounding boundary) continue the\n // iteration.\n if ( n == '9999' || !rep && n == '4999' ) {\n\n // On the first iteration only, check to see if rounding up gives the\n // exact result as the nines may infinitely repeat.\n if ( !rep ) {\n round( t, t.e + DECIMAL_PLACES + 2, 0 );\n\n if ( t.times(t).eq(x) ) {\n r = t;\n break;\n }\n }\n\n dp += 4;\n s += 4;\n rep = 1;\n } else {\n\n // If rounding digits are null, 0{0,4} or 50{0,3}, check for exact\n // result. If not, then there are further digits and m will be truthy.\n if ( !+n || !+n.slice(1) && n.charAt(0) == '5' ) {\n\n // Truncate to the first rounding digit.\n round( r, r.e + DECIMAL_PLACES + 2, 1 );\n m = !r.times(r).eq(x);\n }\n\n break;\n }\n }\n }\n }\n\n return round( r, r.e + DECIMAL_PLACES + 1, ROUNDING_MODE, m );\n };\n\n\n /*\n * n * 0 = 0\n * n * N = N\n * n * I = I\n * 0 * n = 0\n * 0 * 0 = 0\n * 0 * N = N\n * 0 * I = N\n * N * n = N\n * N * 0 = N\n * N * N = N\n * N * I = N\n * I * n = I\n * I * 0 = N\n * I * N = N\n * I * I = I\n *\n * Return a new BigNumber whose value is the value of this BigNumber times the value of\n * BigNumber(y, b).\n */\n P.times = P.mul = function ( y, b ) {\n var c, e, i, j, k, m, xcL, xlo, xhi, ycL, ylo, yhi, zc,\n base, sqrtBase,\n x = this,\n xc = x.c,\n yc = ( id = 17, y = new BigNumber( y, b ) ).c;\n\n // Either NaN, ±Infinity or ±0?\n if ( !xc || !yc || !xc[0] || !yc[0] ) {\n\n // Return NaN if either is NaN, or one is 0 and the other is Infinity.\n if ( !x.s || !y.s || xc && !xc[0] && !yc || yc && !yc[0] && !xc ) {\n y.c = y.e = y.s = null;\n } else {\n y.s *= x.s;\n\n // Return ±Infinity if either is ±Infinity.\n if ( !xc || !yc ) {\n y.c = y.e = null;\n\n // Return ±0 if either is ±0.\n } else {\n y.c = [0];\n y.e = 0;\n }\n }\n\n return y;\n }\n\n e = bitFloor( x.e / LOG_BASE ) + bitFloor( y.e / LOG_BASE );\n y.s *= x.s;\n xcL = xc.length;\n ycL = yc.length;\n\n // Ensure xc points to longer array and xcL to its length.\n if ( xcL < ycL ) zc = xc, xc = yc, yc = zc, i = xcL, xcL = ycL, ycL = i;\n\n // Initialise the result array with zeros.\n for ( i = xcL + ycL, zc = []; i--; zc.push(0) );\n\n base = BASE;\n sqrtBase = SQRT_BASE;\n\n for ( i = ycL; --i >= 0; ) {\n c = 0;\n ylo = yc[i] % sqrtBase;\n yhi = yc[i] / sqrtBase | 0;\n\n for ( k = xcL, j = i + k; j > i; ) {\n xlo = xc[--k] % sqrtBase;\n xhi = xc[k] / sqrtBase | 0;\n m = yhi * xlo + xhi * ylo;\n xlo = ylo * xlo + ( ( m % sqrtBase ) * sqrtBase ) + zc[j] + c;\n c = ( xlo / base | 0 ) + ( m / sqrtBase | 0 ) + yhi * xhi;\n zc[j--] = xlo % base;\n }\n\n zc[j] = c;\n }\n\n if (c) {\n ++e;\n } else {\n zc.shift();\n }\n\n return normalise( y, zc, e );\n };\n\n\n /*\n * Return a new BigNumber whose value is the value of this BigNumber rounded to a maximum of\n * sd significant digits using rounding mode rm, or ROUNDING_MODE if rm is omitted.\n *\n * [sd] {number} Significant digits. Integer, 1 to MAX inclusive.\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\n *\n * 'toDigits() precision out of range: {sd}'\n * 'toDigits() precision not an integer: {sd}'\n * 'toDigits() rounding mode not an integer: {rm}'\n * 'toDigits() rounding mode out of range: {rm}'\n */\n P.toDigits = function ( sd, rm ) {\n var n = new BigNumber(this);\n sd = sd == null || !isValidInt( sd, 1, MAX, 18, 'precision' ) ? null : sd | 0;\n rm = rm == null || !isValidInt( rm, 0, 8, 18, roundingMode ) ? ROUNDING_MODE : rm | 0;\n return sd ? round( n, sd, rm ) : n;\n };\n\n\n /*\n * Return a string representing the value of this BigNumber in exponential notation and\n * rounded using ROUNDING_MODE to dp fixed decimal places.\n *\n * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\n *\n * 'toExponential() decimal places not an integer: {dp}'\n * 'toExponential() decimal places out of range: {dp}'\n * 'toExponential() rounding mode not an integer: {rm}'\n * 'toExponential() rounding mode out of range: {rm}'\n */\n P.toExponential = function ( dp, rm ) {\n return format( this,\n dp != null && isValidInt( dp, 0, MAX, 19 ) ? ~~dp + 1 : null, rm, 19 );\n };\n\n\n /*\n * Return a string representing the value of this BigNumber in fixed-point notation rounding\n * to dp fixed decimal places using rounding mode rm, or ROUNDING_MODE if rm is omitted.\n *\n * Note: as with JavaScript's number type, (-0).toFixed(0) is '0',\n * but e.g. (-0.00001).toFixed(0) is '-0'.\n *\n * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\n *\n * 'toFixed() decimal places not an integer: {dp}'\n * 'toFixed() decimal places out of range: {dp}'\n * 'toFixed() rounding mode not an integer: {rm}'\n * 'toFixed() rounding mode out of range: {rm}'\n */\n P.toFixed = function ( dp, rm ) {\n return format( this, dp != null && isValidInt( dp, 0, MAX, 20 )\n ? ~~dp + this.e + 1 : null, rm, 20 );\n };\n\n\n /*\n * Return a string representing the value of this BigNumber in fixed-point notation rounded\n * using rm or ROUNDING_MODE to dp decimal places, and formatted according to the properties\n * of the FORMAT object (see BigNumber.config).\n *\n * FORMAT = {\n * decimalSeparator : '.',\n * groupSeparator : ',',\n * groupSize : 3,\n * secondaryGroupSize : 0,\n * fractionGroupSeparator : '\\xA0', // non-breaking space\n * fractionGroupSize : 0\n * };\n *\n * [dp] {number} Decimal places. Integer, 0 to MAX inclusive.\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\n *\n * 'toFormat() decimal places not an integer: {dp}'\n * 'toFormat() decimal places out of range: {dp}'\n * 'toFormat() rounding mode not an integer: {rm}'\n * 'toFormat() rounding mode out of range: {rm}'\n */\n P.toFormat = function ( dp, rm ) {\n var str = format( this, dp != null && isValidInt( dp, 0, MAX, 21 )\n ? ~~dp + this.e + 1 : null, rm, 21 );\n\n if ( this.c ) {\n var i,\n arr = str.split('.'),\n g1 = +FORMAT.groupSize,\n g2 = +FORMAT.secondaryGroupSize,\n groupSeparator = FORMAT.groupSeparator,\n intPart = arr[0],\n fractionPart = arr[1],\n isNeg = this.s < 0,\n intDigits = isNeg ? intPart.slice(1) : intPart,\n len = intDigits.length;\n\n if (g2) i = g1, g1 = g2, g2 = i, len -= i;\n\n if ( g1 > 0 && len > 0 ) {\n i = len % g1 || g1;\n intPart = intDigits.substr( 0, i );\n\n for ( ; i < len; i += g1 ) {\n intPart += groupSeparator + intDigits.substr( i, g1 );\n }\n\n if ( g2 > 0 ) intPart += groupSeparator + intDigits.slice(i);\n if (isNeg) intPart = '-' + intPart;\n }\n\n str = fractionPart\n ? intPart + FORMAT.decimalSeparator + ( ( g2 = +FORMAT.fractionGroupSize )\n ? fractionPart.replace( new RegExp( '\\\\d{' + g2 + '}\\\\B', 'g' ),\n '$&' + FORMAT.fractionGroupSeparator )\n : fractionPart )\n : intPart;\n }\n\n return str;\n };\n\n\n /*\n * Return a string array representing the value of this BigNumber as a simple fraction with\n * an integer numerator and an integer denominator. The denominator will be a positive\n * non-zero value less than or equal to the specified maximum denominator. If a maximum\n * denominator is not specified, the denominator will be the lowest value necessary to\n * represent the number exactly.\n *\n * [md] {number|string|BigNumber} Integer >= 1 and < Infinity. The maximum denominator.\n *\n * 'toFraction() max denominator not an integer: {md}'\n * 'toFraction() max denominator out of range: {md}'\n */\n P.toFraction = function (md) {\n var arr, d0, d2, e, exp, n, n0, q, s,\n k = ERRORS,\n x = this,\n xc = x.c,\n d = new BigNumber(ONE),\n n1 = d0 = new BigNumber(ONE),\n d1 = n0 = new BigNumber(ONE);\n\n if ( md != null ) {\n ERRORS = false;\n n = new BigNumber(md);\n ERRORS = k;\n\n if ( !( k = n.isInt() ) || n.lt(ONE) ) {\n\n if (ERRORS) {\n raise( 22,\n 'max denominator ' + ( k ? 'out of range' : 'not an integer' ), md );\n }\n\n // ERRORS is false:\n // If md is a finite non-integer >= 1, round it to an integer and use it.\n md = !k && n.c && round( n, n.e + 1, 1 ).gte(ONE) ? n : null;\n }\n }\n\n if ( !xc ) return x.toString();\n s = coeffToString(xc);\n\n // Determine initial denominator.\n // d is a power of 10 and the minimum max denominator that specifies the value exactly.\n e = d.e = s.length - x.e - 1;\n d.c[0] = POWS_TEN[ ( exp = e % LOG_BASE ) < 0 ? LOG_BASE + exp : exp ];\n md = !md || n.cmp(d) > 0 ? ( e > 0 ? d : n1 ) : n;\n\n exp = MAX_EXP;\n MAX_EXP = 1 / 0;\n n = new BigNumber(s);\n\n // n0 = d1 = 0\n n0.c[0] = 0;\n\n for ( ; ; ) {\n q = div( n, d, 0, 1 );\n d2 = d0.plus( q.times(d1) );\n if ( d2.cmp(md) == 1 ) break;\n d0 = d1;\n d1 = d2;\n n1 = n0.plus( q.times( d2 = n1 ) );\n n0 = d2;\n d = n.minus( q.times( d2 = d ) );\n n = d2;\n }\n\n d2 = div( md.minus(d0), d1, 0, 1 );\n n0 = n0.plus( d2.times(n1) );\n d0 = d0.plus( d2.times(d1) );\n n0.s = n1.s = x.s;\n e *= 2;\n\n // Determine which fraction is closer to x, n0/d0 or n1/d1\n arr = div( n1, d1, e, ROUNDING_MODE ).minus(x).abs().cmp(\n div( n0, d0, e, ROUNDING_MODE ).minus(x).abs() ) < 1\n ? [ n1.toString(), d1.toString() ]\n : [ n0.toString(), d0.toString() ];\n\n MAX_EXP = exp;\n return arr;\n };\n\n\n /*\n * Return the value of this BigNumber converted to a number primitive.\n */\n P.toNumber = function () {\n var x = this;\n\n // Ensure zero has correct sign.\n return +x || ( x.s ? x.s * 0 : NaN );\n };\n\n\n /*\n * Return a BigNumber whose value is the value of this BigNumber raised to the power n.\n * If n is negative round according to DECIMAL_PLACES and ROUNDING_MODE.\n * If POW_PRECISION is not 0, round to POW_PRECISION using ROUNDING_MODE.\n *\n * n {number} Integer, -9007199254740992 to 9007199254740992 inclusive.\n * (Performs 54 loop iterations for n of 9007199254740992.)\n *\n * 'pow() exponent not an integer: {n}'\n * 'pow() exponent out of range: {n}'\n */\n P.toPower = P.pow = function (n) {\n var k, y,\n i = mathfloor( n < 0 ? -n : +n ),\n x = this;\n\n // Pass ±Infinity to Math.pow if exponent is out of range.\n if ( !isValidInt( n, -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, 23, 'exponent' ) &&\n ( !isFinite(n) || i > MAX_SAFE_INTEGER && ( n /= 0 ) ||\n parseFloat(n) != n && !( n = NaN ) ) ) {\n return new BigNumber( Math.pow( +x, n ) );\n }\n\n // Truncating each coefficient array to a length of k after each multiplication equates\n // to truncating significant digits to POW_PRECISION + [28, 41], i.e. there will be a\n // minimum of 28 guard digits retained. (Using + 1.5 would give [9, 21] guard digits.)\n k = POW_PRECISION ? mathceil( POW_PRECISION / LOG_BASE + 2 ) : 0;\n y = new BigNumber(ONE);\n\n for ( ; ; ) {\n\n if ( i % 2 ) {\n y = y.times(x);\n if ( !y.c ) break;\n if ( k && y.c.length > k ) y.c.length = k;\n }\n\n i = mathfloor( i / 2 );\n if ( !i ) break;\n\n x = x.times(x);\n if ( k && x.c && x.c.length > k ) x.c.length = k;\n }\n\n if ( n < 0 ) y = ONE.div(y);\n return k ? round( y, POW_PRECISION, ROUNDING_MODE ) : y;\n };\n\n\n /*\n * Return a string representing the value of this BigNumber rounded to sd significant digits\n * using rounding mode rm or ROUNDING_MODE. If sd is less than the number of digits\n * necessary to represent the integer part of the value in fixed-point notation, then use\n * exponential notation.\n *\n * [sd] {number} Significant digits. Integer, 1 to MAX inclusive.\n * [rm] {number} Rounding mode. Integer, 0 to 8 inclusive.\n *\n * 'toPrecision() precision not an integer: {sd}'\n * 'toPrecision() precision out of range: {sd}'\n * 'toPrecision() rounding mode not an integer: {rm}'\n * 'toPrecision() rounding mode out of range: {rm}'\n */\n P.toPrecision = function ( sd, rm ) {\n return format( this, sd != null && isValidInt( sd, 1, MAX, 24, 'precision' )\n ? sd | 0 : null, rm, 24 );\n };\n\n\n /*\n * Return a string representing the value of this BigNumber in base b, or base 10 if b is\n * omitted. If a base is specified, including base 10, round according to DECIMAL_PLACES and\n * ROUNDING_MODE. If a base is not specified, and this BigNumber has a positive exponent\n * that is equal to or greater than TO_EXP_POS, or a negative exponent equal to or less than\n * TO_EXP_NEG, return exponential notation.\n *\n * [b] {number} Integer, 2 to 64 inclusive.\n *\n * 'toString() base not an integer: {b}'\n * 'toString() base out of range: {b}'\n */\n P.toString = function (b) {\n var str,\n n = this,\n s = n.s,\n e = n.e;\n\n // Infinity or NaN?\n if ( e === null ) {\n\n if (s) {\n str = 'Infinity';\n if ( s < 0 ) str = '-' + str;\n } else {\n str = 'NaN';\n }\n } else {\n str = coeffToString( n.c );\n\n if ( b == null || !isValidInt( b, 2, 64, 25, 'base' ) ) {\n str = e <= TO_EXP_NEG || e >= TO_EXP_POS\n ? toExponential( str, e )\n : toFixedPoint( str, e );\n } else {\n str = convertBase( toFixedPoint( str, e ), b | 0, 10, s );\n }\n\n if ( s < 0 && n.c[0] ) str = '-' + str;\n }\n\n return str;\n };\n\n\n /*\n * Return a new BigNumber whose value is the value of this BigNumber truncated to a whole\n * number.\n */\n P.truncated = P.trunc = function () {\n return round( new BigNumber(this), this.e + 1, 1 );\n };\n\n\n\n /*\n * Return as toString, but do not accept a base argument.\n */\n P.valueOf = P.toJSON = function () {\n return this.toString();\n };\n\n\n // Aliases for BigDecimal methods.\n //P.add = P.plus; // P.add included above\n //P.subtract = P.minus; // P.sub included above\n //P.multiply = P.times; // P.mul included above\n //P.divide = P.div;\n //P.remainder = P.mod;\n //P.compareTo = P.cmp;\n //P.negate = P.neg;\n\n\n if ( configObj != null ) BigNumber.config(configObj);\n\n return BigNumber;\n }\n\n\n // PRIVATE HELPER FUNCTIONS\n\n\n function bitFloor(n) {\n var i = n | 0;\n return n > 0 || n === i ? i : i - 1;\n }\n\n\n // Return a coefficient array as a string of base 10 digits.\n function coeffToString(a) {\n var s, z,\n i = 1,\n j = a.length,\n r = a[0] + '';\n\n for ( ; i < j; ) {\n s = a[i++] + '';\n z = LOG_BASE - s.length;\n for ( ; z--; s = '0' + s );\n r += s;\n }\n\n // Determine trailing zeros.\n for ( j = r.length; r.charCodeAt(--j) === 48; );\n return r.slice( 0, j + 1 || 1 );\n }\n\n\n // Compare the value of BigNumbers x and y.\n function compare( x, y ) {\n var a, b,\n xc = x.c,\n yc = y.c,\n i = x.s,\n j = y.s,\n k = x.e,\n l = y.e;\n\n // Either NaN?\n if ( !i || !j ) return null;\n\n a = xc && !xc[0];\n b = yc && !yc[0];\n\n // Either zero?\n if ( a || b ) return a ? b ? 0 : -j : i;\n\n // Signs differ?\n if ( i != j ) return i;\n\n a = i < 0;\n b = k == l;\n\n // Either Infinity?\n if ( !xc || !yc ) return b ? 0 : !xc ^ a ? 1 : -1;\n\n // Compare exponents.\n if ( !b ) return k > l ^ a ? 1 : -1;\n\n j = ( k = xc.length ) < ( l = yc.length ) ? k : l;\n\n // Compare digit by digit.\n for ( i = 0; i < j; i++ ) if ( xc[i] != yc[i] ) return xc[i] > yc[i] ^ a ? 1 : -1;\n\n // Compare lengths.\n return k == l ? 0 : k > l ^ a ? 1 : -1;\n }\n\n\n /*\n * Return true if n is a valid number in range, otherwise false.\n * Use for argument validation when ERRORS is false.\n * Note: parseInt('1e+1') == 1 but parseFloat('1e+1') == 10.\n */\n function intValidatorNoErrors( n, min, max ) {\n return ( n = truncate(n) ) >= min && n <= max;\n }\n\n\n function isArray(obj) {\n return Object.prototype.toString.call(obj) == '[object Array]';\n }\n\n\n /*\n * Convert string of baseIn to an array of numbers of baseOut.\n * Eg. convertBase('255', 10, 16) returns [15, 15].\n * Eg. convertBase('ff', 16, 10) returns [2, 5, 5].\n */\n function toBaseOut( str, baseIn, baseOut ) {\n var j,\n arr = [0],\n arrL,\n i = 0,\n len = str.length;\n\n for ( ; i < len; ) {\n for ( arrL = arr.length; arrL--; arr[arrL] *= baseIn );\n arr[ j = 0 ] += ALPHABET.indexOf( str.charAt( i++ ) );\n\n for ( ; j < arr.length; j++ ) {\n\n if ( arr[j] > baseOut - 1 ) {\n if ( arr[j + 1] == null ) arr[j + 1] = 0;\n arr[j + 1] += arr[j] / baseOut | 0;\n arr[j] %= baseOut;\n }\n }\n }\n\n return arr.reverse();\n }\n\n\n function toExponential( str, e ) {\n return ( str.length > 1 ? str.charAt(0) + '.' + str.slice(1) : str ) +\n ( e < 0 ? 'e' : 'e+' ) + e;\n }\n\n\n function toFixedPoint( str, e ) {\n var len, z;\n\n // Negative exponent?\n if ( e < 0 ) {\n\n // Prepend zeros.\n for ( z = '0.'; ++e; z += '0' );\n str = z + str;\n\n // Positive exponent\n } else {\n len = str.length;\n\n // Append zeros.\n if ( ++e > len ) {\n for ( z = '0', e -= len; --e; z += '0' );\n str += z;\n } else if ( e < len ) {\n str = str.slice( 0, e ) + '.' + str.slice(e);\n }\n }\n\n return str;\n }\n\n\n function truncate(n) {\n n = parseFloat(n);\n return n < 0 ? mathceil(n) : mathfloor(n);\n }\n\n\n // EXPORT\n\n\n BigNumber = another();\n\n // AMD.\n if ( typeof define == 'function' && define.amd ) {\n define( function () { return BigNumber; } );\n\n // Node and other environments that support module.exports.\n } else if ( typeof module != 'undefined' && module.exports ) {\n module.exports = BigNumber;\n if ( !crypto ) try { crypto = require('crypto'); } catch (e) {}\n\n // Browser.\n } else {\n global.BigNumber = BigNumber;\n }\n})(this);\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\n// dont override global variable\nif (typeof window !== 'undefined' && typeof window.web3 === 'undefined') {\n window.web3 = web3;\n}\n\nmodule.exports = web3;\n\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');\n\n// dont override global variable\nif (typeof window !== 'undefined' && typeof window.web3 === 'undefined') {\n window.web3 = web3;\n}\n\nmodule.exports = web3;\n\n" ] } \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/web3.min.js b/libjsqrc/ethereumjs/dist/web3.min.js index b02f1f966..eb4052b6c 100644 --- a/libjsqrc/ethereumjs/dist/web3.min.js +++ b/libjsqrc/ethereumjs/dist/web3.min.js @@ -1,2 +1,2 @@ -require=function t(e,n,r){function o(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a0&&console.warn("didn't found matching constructor, using default one"),"")};e.exports={formatConstructorParams:i}},{"./coder":2,"./utils":5}],2:[function(t,e,n){var r=t("bignumber.js"),o=t("../utils/utils"),i=t("./formatters"),a=t("./param"),s=function(t){return"[]"===t.slice(-2)},u=function(t){this._name=t.name,this._match=t.match,this._mode=t.mode,this._inputFormatter=t.inputFormatter,this._outputFormatter=t.outputFormatter};u.prototype.isType=function(t){return"strict"===this._match?this._name===t||0===t.indexOf(this._name)&&"[]"===t.slice(this._name.length):"prefix"===this._match?0===t.indexOf(this._name):void 0},u.prototype.formatInput=function(t,e){if(o.isArray(t)&&e){var n=this;return t.map(function(t){return n._inputFormatter(t)}).reduce(function(t,e){return t.combine(e)},i.formatInputInt(t.length)).withOffset(32)}return this._inputFormatter(t)},u.prototype.formatOutput=function(t,e){if(e){for(var n=[],o=new r(t.dynamicPart().slice(0,64),16),i=0;64*o>i;i+=64)n.push(this._outputFormatter(new a(t.dynamicPart().substr(i+64,64))));return n}return this._outputFormatter(t)},u.prototype.sliceParam=function(t,e,n){return"bytes"===this._mode?a.decodeBytes(t,e):s(n)?a.decodeArray(t,e):a.decodeParam(t,e)};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var n=this,r=t.map(function(t,r){return n._formatInput(t,e[r])});return a.encodeList(r)},c.prototype.decodeParam=function(t,e){return this.decodeParams([t],e)[0]},c.prototype.decodeParams=function(t,e){var n=this;return t.map(function(t,r){var o=n._requireType(t),i=o.sliceParam(e,r,t);return o.formatOutput(i,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:i.formatInputBool,outputFormatter:i.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:i.formatInputDynamicBytes,outputFormatter:i.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:i.formatInputBytes,outputFormatter:i.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputUReal})]);e.exports=l},{"../utils/utils":8,"./formatters":3,"./param":4,"bignumber.js":"bignumber.js"}],3:[function(t,e,n){var r=t("bignumber.js"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./param"),s=function(t){var e=2*i.ETH_PADDING;r.config(i.ETH_BIGNUMBER_ROUNDING_MODE);var n=o.padLeft(o.toTwosComplement(t).round().toString(16),e);return new a(n)},u=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(s(t.length).value+e,32)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},f=function(t){return s(new r(t).times(new r(2).pow(128)))},p=function(t){return"1"===new r(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.staticPart()||"0";return p(e)?new r(e,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(e,16)},h=function(t){var e=t.staticPart()||"0";return new r(e,16)},d=function(t){return m(t).dividedBy(new r(2).pow(128))},g=function(t){return h(t).dividedBy(new r(2).pow(128))},y=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},v=function(t){return o.toAscii(t.staticPart())},b=function(t){return o.toAscii(t.dynamicPart().slice(64))},w=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:f,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:g,formatOutputBool:y,formatOutputBytes:v,formatOutputDynamicBytes:b,formatOutputAddress:w}},{"../utils/config":7,"../utils/utils":8,"./param":4,"bignumber.js":"bignumber.js"}],4:[function(t,e,n){var r=t("../utils/utils"),o=function(t,e){this.value=t||"",this.offset=e};o.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},o.prototype.withOffset=function(t){return new o(this.value,t)},o.prototype.combine=function(t){return new o(this.value+t.value)},o.prototype.isDynamic=function(){return this.value.length>64},o.prototype.offsetAsBytes=function(){return this.isDynamic()?r.padLeft(r.toTwosComplement(this.offset).toString(16),64):""},o.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},o.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},o.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},o.encodeList=function(t){var e=32*t.length,n=t.map(function(t){if(!t.isDynamic())return t;var n=e;return e+=t.dynamicPartLength(),t.withOffset(n)});return n.reduce(function(t,e){return t+e.dynamicPart()},n.reduce(function(t,e){return t+e.staticPart()},""))},o.decodeParam=function(t,e){return e=e||0,new o(t.substr(64*e,64))};var i=function(t,e){return parseInt("0x"+t.substr(64*e,64))};o.decodeBytes=function(t,e){e=e||0;var n=i(t,e);return new o(t.substr(2*n,128))},o.decodeArray=function(t,e){e=e||0;var n=i(t,e),r=parseInt("0x"+t.substr(2*n,64));return new o(t.substr(2*n,64*(r+1)))},e.exports=o},{"../utils/utils":8}],5:[function(t,e,n){var r=function(t,e){return t.filter(function(t){return"constructor"===t.type&&t.inputs.length===e})[0]};e.exports={getConstructor:r}},{}],6:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],7:[function(t,e,n){var r=t("bignumber.js"),o=["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:o,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],8:[function(t,e,n){var r=t("bignumber.js"),o={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"},i=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t){var e="",n=0,r=t.length;for("0x"===t.substring(0,2)&&(n=2);r>n;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",n=0;nthis._inputTypes.length&&i.isObject(t[t.length-1])&&(e=t.pop()),e.to=this._address,e.data="0x"+this.signature()+o.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return r.sha3(r.fromAscii(this._name)).slice(2,10)},a.prototype.call=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments)),e=r.eth.call(t);e=e.length>=2?e.slice(2):e;var n=o.decodeParams(this._outputTypes,e);return 1===n.length?n[0]:n},a.prototype.sendTransaction=function(){var t=this.toPayload.apply(this,Array.prototype.slice.call(arguments));r.eth.sendTransaction(t)},a.prototype.displayName=function(){return i.extractDisplayName(this._name)},a.prototype.typeName=function(){return i.extractTypeName(this._name)},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=a},{"../solidity/coder":2,"../utils/utils":8,"../web3":10}],19:[function(t,e,n){"use strict";var r=t("xmlhttprequest").XMLHttpRequest,o=t("./errors"),i=function(t){this.host=t||"http://localhost:8545"};i.prototype.send=function(t){var e=new r;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(n){throw o.InvalidConnection(this.host)}var i=e.responseText;try{i=JSON.parse(i)}catch(a){throw o.InvalidResponse(i)}return i},i.prototype.sendAsync=function(t,e){var n=new r;n.onreadystatechange=function(){if(4===n.readyState){var t=n.responseText,r=null;try{t=JSON.parse(t)}catch(i){r=o.InvalidResponse(t)}e(r,t)}},n.open("POST",this.host,!0);try{n.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":13,xmlhttprequest:6}],20:[function(t,e,n){var r=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};r.getInstance=function(){var t=new r;return t},r.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},r.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},r.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=r},{}],21:[function(t,e,n){var r=t("./requestmanager"),o=t("../utils/utils"),i=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return o.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():null},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw i.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,n){return e?e(t[n]):t[n]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.call=this.call;var n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},t[n[0]][n[1]]=e):t[n[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),n=this.extractCallback(t),r=this.formatInput(t);return this.validateArgs(r),{method:e,params:r,callback:n}},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return r.getInstance().sendAsync(t,function(n,r){t.callback(null,e.formatOutput(r))})}return this.formatOutput(r.getInstance().send(t))},e.exports=a},{"../utils/utils":8,"./errors":13,"./requestmanager":25}],22:[function(t,e,n){var r=t("../utils/utils"),o=t("./property"),i=[],a=[new o({name:"listening",getter:"net_listening"}),new o({name:"peerCount",getter:"net_peerCount",outputFormatter:r.toDecimal})];e.exports={methods:i,properties:a}},{"../utils/utils":8,"./property":23}],23:[function(t,e,n){var r=t("./requestmanager"),o=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};o.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},o.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},o.prototype.attachToObject=function(t){var e={get:this.get.bind(this),set:this.set.bind(this)},n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},Object.defineProperty(t[n[0]],n[1],e)):Object.defineProperty(t,n[0],e)},o.prototype.get=function(){return this.formatOutput(r.getInstance().send({method:this.getter}))},o.prototype.set=function(t){return r.getInstance().send({method:this.setter,params:[this.formatInput(t)]})},e.exports=o},{"./requestmanager":25}],24:[function(t,e,n){var r=function(){};r.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=r},{}],25:[function(t,e,n){var r=t("./jsonrpc"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=r.getInstance().toPayload(t.method,t.params),n=this.provider.send(e);if(!r.getInstance().isValidResponse(n))throw a.InvalidResponse(n);return n.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var n=r.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(n,function(t,n){return t?e(t):r.getInstance().isValidResponse(n)?void e(null,n.result):e(a.InvalidResponse(n))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,n,r){this.polls.push({data:t,id:e,callback:n,uninstall:r})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var n=this.polls[e];n.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),i.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=r.getInstance().toBatchPayload(this.polls.map(function(t){return t.data})),e=this;this.provider.sendAsync(t,function(t,n){if(!t){if(!o.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){return t.callback=e.polls[n].callback,t}).filter(function(t){var e=r.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return o.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":7,"../utils/utils":8,"./errors":13,"./jsonrpc":20}],26:[function(t,e,n){var r=t("./method"),o=t("./formatters"),i=new r({name:"post",call:"shh_post",params:1,inputFormatter:[o.inputPostFormatter]}),a=new r({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new r({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new r({name:"newGroup",call:"shh_newGroup",params:0}),c=new r({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[i,a,s,u,c];e.exports={methods:l}},{"./formatters":17,"./method":21}],27:[function(t,e,n){var r=t("./method"),o=function(){var t=function(t){return"string"==typeof t[0]?"eth_newBlockFilter":"eth_newFilter"},e=new r({name:"newFilter",call:t,params:1}),n=new r({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new r({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new r({name:"poll",call:"eth_getFilterChanges",params:1});return[e,n,o,i]},i=function(){var t=new r({name:"newFilter",call:"shh_newFilter",params:1}),e=new r({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),n=new r({name:"getLogs",call:"shh_getMessages",params:1}),o=new r({name:"poll",call:"shh_getFilterChanges",params:1 -});return[t,e,n,o]};e.exports={eth:o,shh:i}},{"./method":21}],28:[function(t,e,n){},{}],"bignumber.js":[function(t,e,n){!function(n){"use strict";function r(t){function e(t,r){var o,i,a,s,u,c,l=this;if(!(l instanceof e))return J&&k(26,"constructor call without new",t),new e(t,r);if(null!=r&&V(r,2,64,R,"base")){if(r=0|r,c=t+"",10==r)return l=new e(t instanceof e?t:c),S(l,j+l.e+1,U);if((s="number"==typeof t)&&0*t!=0||!new RegExp("^-?"+(o="["+F.slice(0,r)+"]+")+"(?:\\."+o+")?$",37>r?"i":"").test(c))return d(l,c,s,r);s?(l.s=0>1/t?(c=c.slice(1),-1):1,J&&c.replace(/^0\.0*|\./,"").length>15&&k(R,_,t),s=!1):l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1,c=n(c,10,r,l.s)}else{if(t instanceof e)return l.s=t.s,l.e=t.e,l.c=(t=t.c)?t.slice():t,void(R=0);if((s="number"==typeof t)&&0*t==0){if(l.s=0>1/t?(t=-t,-1):1,t===~~t){for(i=0,a=t;a>=10;a/=10,i++);return l.e=i,l.c=[t],void(R=0)}c=t+""}else{if(!g.test(c=t+""))return d(l,c,s);l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1}}for((i=c.indexOf("."))>-1&&(c=c.replace(".","")),(a=c.search(/e/i))>0?(0>i&&(i=a),i+=+c.slice(a+1),c=c.substring(0,a)):0>i&&(i=c.length),a=0;48===c.charCodeAt(a);a++);for(u=c.length;48===c.charCodeAt(--u););if(c=c.slice(a,u+1))if(u=c.length,s&&J&&u>15&&k(R,_,l.s*t),i=i-a-1,i>G)l.c=l.e=null;else if(M>i)l.c=[l.e=0];else{if(l.e=i,l.c=[],a=(i+1)%I,0>i&&(a+=I),u>a){for(a&&l.c.push(+c.slice(0,a)),u-=I;u>a;)l.c.push(+c.slice(a,a+=I));c=c.slice(a),a=I-c.length}else a-=u;for(;a--;c+="0");l.c.push(+c)}else l.c=[l.e=0];R=0}function n(t,n,r,o){var a,s,u,l,p,m,h,d=t.indexOf("."),g=j,y=U;for(37>r&&(t=t.toLowerCase()),d>=0&&(u=z,z=0,t=t.replace(".",""),h=new e(r),p=h.pow(t.length-d),z=u,h.c=c(f(i(p.c),p.e),10,n),h.e=h.c.length),m=c(t,r,n),s=u=m.length;0==m[--u];m.pop());if(!m[0])return"0";if(0>d?--s:(p.c=m,p.e=s,p.s=o,p=E(p,h,g,y,n),m=p.c,l=p.r,s=p.e),a=s+g+1,d=m[a],u=n/2,l=l||0>a||null!=m[a+1],l=4>y?(null!=d||l)&&(0==y||y==(p.s<0?3:2)):d>u||d==u&&(4==y||l||6==y&&1&m[a-1]||y==(p.s<0?8:7)),1>a||!m[0])t=l?f("1",-g):"0";else{if(m.length=a,l)for(--n;++m[--a]>n;)m[a]=0,a||(++s,m.unshift(1));for(u=m.length;!m[--u];);for(d=0,t="";u>=d;t+=F.charAt(m[d++]));t=f(t,s)}return t}function m(t,n,r,o){var a,s,u,c,p;if(r=null!=r&&V(r,0,8,o,w)?0|r:U,!t.c)return t.toString();if(a=t.c[0],u=t.e,null==n)p=i(t.c),p=19==o||24==o&&H>=u?l(p,u):f(p,u);else if(t=S(new e(t),n,r),s=t.e,p=i(t.c),c=p.length,19==o||24==o&&(s>=n||H>=s)){for(;n>c;p+="0",c++);p=l(p,s)}else if(n-=u,p=f(p,s),s+1>c){if(--n>0)for(p+=".";n--;p+="0");}else if(n+=s-c,n>0)for(s+1==c&&(p+=".");n--;p+="0");return t.s<0&&a?"-"+p:p}function T(t,n){var r,o,i=0;for(u(t[0])&&(t=t[0]),r=new e(t[0]);++it||t>n||t!=p(t))&&k(r,(o||"decimal places")+(e>t||t>n?" out of range":" not an integer"),t),!0}function D(t,e,n){for(var r=1,o=e.length;!e[--o];e.pop());for(o=e[0];o>=10;o/=10,r++);return(n=r+n*I-1)>G?t.c=t.e=null:M>n?t.c=[t.e=0]:(t.e=n,t.c=e),t}function k(t,e,n){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][t]+"() "+e+": "+n);throw r.name="BigNumber Error",R=0,r}function S(t,e,n,r){var o,i,a,s,u,c,l,f=t.c,p=O;if(f){t:{for(o=1,s=f[0];s>=10;s/=10,o++);if(i=e-o,0>i)i+=I,a=e,u=f[c=0],l=u/p[o-a-1]%10|0;else if(c=y((i+1)/I),c>=f.length){if(!r)break t;for(;f.length<=c;f.push(0));u=l=0,o=1,i%=I,a=i-I+1}else{for(u=s=f[c],o=1;s>=10;s/=10,o++);i%=I,a=i-I+o,l=0>a?0:u/p[o-a-1]%10|0}if(r=r||0>e||null!=f[c+1]||(0>a?u:u%p[o-a-1]),r=4>n?(l||r)&&(0==n||n==(t.s<0?3:2)):l>5||5==l&&(4==n||r||6==n&&(i>0?a>0?u/p[o-a]:0:f[c-1])%10&1||n==(t.s<0?8:7)),1>e||!f[0])return f.length=0,r?(e-=t.e+1,f[0]=p[e%I],t.e=-e||0):f[0]=t.e=0,t;if(0==i?(f.length=c,s=1,c--):(f.length=c+1,s=p[I-i],f[c]=a>0?v(u/p[o-a]%p[a])*s:0),r)for(;;){if(0==c){for(i=1,a=f[0];a>=10;a/=10,i++);for(a=f[0]+=s,s=1;a>=10;a/=10,s++);i!=s&&(t.e++,f[0]==x&&(f[0]=1));break}if(f[c]+=s,f[c]!=x)break;f[c--]=0,s=1}for(i=f.length;0===f[--i];f.pop());}t.e>G?t.c=t.e=null:t.en?null!=(t=o[n++]):void 0};return a(e="DECIMAL_PLACES")&&V(t,0,P,2,e)&&(j=0|t),r[e]=j,a(e="ROUNDING_MODE")&&V(t,0,8,2,e)&&(U=0|t),r[e]=U,a(e="EXPONENTIAL_AT")&&(u(t)?V(t[0],-P,0,2,e)&&V(t[1],0,P,2,e)&&(H=0|t[0],q=0|t[1]):V(t,-P,P,2,e)&&(H=-(q=0|(0>t?-t:t)))),r[e]=[H,q],a(e="RANGE")&&(u(t)?V(t[0],-P,-1,2,e)&&V(t[1],1,P,2,e)&&(M=0|t[0],G=0|t[1]):V(t,-P,P,2,e)&&(0|t?M=-(G=0|(0>t?-t:t)):J&&k(2,e+" cannot be zero",t))),r[e]=[M,G],a(e="ERRORS")&&(t===!!t||1===t||0===t?(R=0,V=(J=!!t)?A:s):J&&k(2,e+b,t)),r[e]=J,a(e="CRYPTO")&&(t===!!t||1===t||0===t?(W=!(!t||!h||"object"!=typeof h),t&&!W&&J&&k(2,"crypto unavailable",h)):J&&k(2,e+b,t)),r[e]=W,a(e="MODULO_MODE")&&V(t,0,9,2,e)&&($=0|t),r[e]=$,a(e="POW_PRECISION")&&V(t,0,P,2,e)&&(z=0|t),r[e]=z,a(e="FORMAT")&&("object"==typeof t?X=t:J&&k(2,e+" not an object",t)),r[e]=X,r},e.max=function(){return T(arguments,C.lt)},e.min=function(){return T(arguments,C.gt)},e.random=function(){var t=9007199254740992,n=Math.random()*t&2097151?function(){return v(Math.random()*t)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(t){var r,o,i,a,s,u=0,c=[],l=new e(L);if(t=null!=t&&V(t,0,P,14)?0|t:j,a=y(t/I),W)if(h&&h.getRandomValues){for(r=h.getRandomValues(new Uint32Array(a*=2));a>u;)s=131072*r[u]+(r[u+1]>>>11),s>=9e15?(o=h.getRandomValues(new Uint32Array(2)),r[u]=o[0],r[u+1]=o[1]):(c.push(s%1e14),u+=2);u=a/2}else if(h&&h.randomBytes){for(r=h.randomBytes(a*=7);a>u;)s=281474976710656*(31&r[u])+1099511627776*r[u+1]+4294967296*r[u+2]+16777216*r[u+3]+(r[u+4]<<16)+(r[u+5]<<8)+r[u+6],s>=9e15?h.randomBytes(7).copy(r,u):(c.push(s%1e14),u+=7);u=a/7}else J&&k(14,"crypto unavailable",h);if(!u)for(;a>u;)s=n(),9e15>s&&(c[u++]=s%1e14);for(a=c[--u],t%=I,a&&t&&(s=O[I-t],c[u]=v(a/s)*s);0===c[u];c.pop(),u--);if(0>u)c=[i=0];else{for(i=-1;0===c[0];c.shift(),i-=I);for(u=1,s=c[0];s>=10;s/=10,u++);I>u&&(i-=I-u)}return l.e=i,l.c=c,l}}(),E=function(){function t(t,e,n){var r,o,i,a,s=0,u=t.length,c=e%B,l=e/B|0;for(t=t.slice();u--;)i=t[u]%B,a=t[u]/B|0,r=l*i+a*c,o=c*i+r%B*B+s,s=(o/n|0)+(r/B|0)+l*a,t[u]=o%n;return s&&t.unshift(s),t}function n(t,e,n,r){var o,i;if(n!=r)i=n>r?1:-1;else for(o=i=0;n>o;o++)if(t[o]!=e[o]){i=t[o]>e[o]?1:-1;break}return i}function r(t,e,n,r){for(var o=0;n--;)t[n]-=o,o=t[n]1;t.shift());}return function(i,a,s,u,c){var l,f,p,m,h,d,g,y,b,w,_,F,N,O,B,P,T,A=i.s==a.s?1:-1,D=i.c,k=a.c;if(!(D&&D[0]&&k&&k[0]))return new e(i.s&&a.s&&(D?!k||D[0]!=k[0]:k)?D&&0==D[0]||!k?0*A:A/0:0/0);for(y=new e(A),b=y.c=[],f=i.e-a.e,A=s+f+1,c||(c=x,f=o(i.e/I)-o(a.e/I),A=A/I|0),p=0;k[p]==(D[p]||0);p++);if(k[p]>(D[p]||0)&&f--,0>A)b.push(1),m=!0;else{for(O=D.length,P=k.length,p=0,A+=2,h=v(c/(k[0]+1)),h>1&&(k=t(k,h,c),D=t(D,h,c),P=k.length,O=D.length),N=P,w=D.slice(0,P),_=w.length;P>_;w[_++]=0);T=k.slice(),T.unshift(0),B=k[0],k[1]>=c/2&&B++;do{if(h=0,l=n(k,w,P,_),0>l){if(F=w[0],P!=_&&(F=F*c+(w[1]||0)),h=v(F/B),h>1)for(h>=c&&(h=c-1),d=t(k,h,c),g=d.length,_=w.length;1==n(d,w,g,_);)h--,r(d,g>P?T:k,g,c),g=d.length,l=1;else 0==h&&(l=h=1),d=k.slice(),g=d.length;if(_>g&&d.unshift(0),r(w,d,_,c),_=w.length,-1==l)for(;n(k,w,P,_)<1;)h++,r(w,_>P?T:k,_,c),_=w.length}else 0===l&&(h++,w=[0]);b[p++]=h,w[0]?w[_++]=D[N]||0:(w=[D[N]],_=1)}while((N++=10;A/=10,p++);S(y,s+(y.e=p+f*I-1)+1,u,m)}else y.e=f,y.r=+m;return y}}(),d=function(){var t=/^(-?)0([xbo])/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,o=/^-?(Infinity|NaN)$/,i=/^\s*\+|^\s+|\s+$/g;return function(a,s,u,c){var l,f=u?s:s.replace(i,"");if(o.test(f))a.s=isNaN(f)?null:0>f?-1:1;else{if(!u&&(f=f.replace(t,function(t,e,n){return l="x"==(n=n.toLowerCase())?16:"b"==n?2:8,c&&c!=l?t:e}),c&&(l=c,f=f.replace(n,"$1").replace(r,"0.$1")),s!=f))return new e(f,l);J&&k(R,"not a"+(c?" base "+c:"")+" number",s),a.s=null}a.c=a.e=null,R=0}}(),C.absoluteValue=C.abs=function(){var t=new e(this);return t.s<0&&(t.s=1),t},C.ceil=function(){return S(new e(this),this.e+1,2)},C.comparedTo=C.cmp=function(t,n){return R=1,a(this,new e(t,n))},C.decimalPlaces=C.dp=function(){var t,e,n=this.c;if(!n)return null;if(t=((e=n.length-1)-o(this.e/I))*I,e=n[e])for(;e%10==0;e/=10,t--);return 0>t&&(t=0),t},C.dividedBy=C.div=function(t,n){return R=3,E(this,new e(t,n),j,U)},C.dividedToIntegerBy=C.divToInt=function(t,n){return R=4,E(this,new e(t,n),0,1)},C.equals=C.eq=function(t,n){return R=5,0===a(this,new e(t,n))},C.floor=function(){return S(new e(this),this.e+1,3)},C.greaterThan=C.gt=function(t,n){return R=6,a(this,new e(t,n))>0},C.greaterThanOrEqualTo=C.gte=function(t,n){return R=7,1===(n=a(this,new e(t,n)))||0===n},C.isFinite=function(){return!!this.c},C.isInteger=C.isInt=function(){return!!this.c&&o(this.e/I)>this.c.length-2},C.isNaN=function(){return!this.s},C.isNegative=C.isNeg=function(){return this.s<0},C.isZero=function(){return!!this.c&&0==this.c[0]},C.lessThan=C.lt=function(t,n){return R=8,a(this,new e(t,n))<0},C.lessThanOrEqualTo=C.lte=function(t,n){return R=9,-1===(n=a(this,new e(t,n)))||0===n},C.minus=C.sub=function(t,n){var r,i,a,s,u=this,c=u.s;if(R=10,t=new e(t,n),n=t.s,!c||!n)return new e(0/0);if(c!=n)return t.s=-n,u.plus(t);var l=u.e/I,f=t.e/I,p=u.c,m=t.c;if(!l||!f){if(!p||!m)return p?(t.s=-n,t):new e(m?u:0/0);if(!p[0]||!m[0])return m[0]?(t.s=-n,t):new e(p[0]?u:3==U?-0:0)}if(l=o(l),f=o(f),p=p.slice(),c=l-f){for((s=0>c)?(c=-c,a=p):(f=l,a=m),a.reverse(),n=c;n--;a.push(0));a.reverse()}else for(i=(s=(c=p.length)<(n=m.length))?c:n,c=n=0;i>n;n++)if(p[n]!=m[n]){s=p[n]0)for(;n--;p[r++]=0);for(n=x-1;i>c;){if(p[--i]0?(u=s,r=l):(a=-a,r=c),r.reverse();a--;r.push(0));r.reverse()}for(a=c.length,n=l.length,0>a-n&&(r=l,l=c,c=r,n=a),a=0;n;)a=(c[--n]=c[n]+l[n]+a)/x|0,c[n]%=x;return a&&(c.unshift(a),++u),D(t,c,u)},C.precision=C.sd=function(t){var e,n,r=this,o=r.c;if(null!=t&&t!==!!t&&1!==t&&0!==t&&(J&&k(13,"argument"+b,t),t!=!!t&&(t=null)),!o)return null;if(n=o.length-1,e=n*I+1,n=o[n]){for(;n%10==0;n/=10,e--);for(n=o[0];n>=10;n/=10,e++);}return t&&r.e+1>e&&(e=r.e+1),e},C.round=function(t,n){var r=new e(this);return(null==t||V(t,0,P,15))&&S(r,~~t+this.e+1,null!=n&&V(n,0,8,15,w)?0|n:U),r},C.shift=function(t){var n=this;return V(t,-N,N,16,"argument")?n.times("1e"+p(t)):new e(n.c&&n.c[0]&&(-N>t||t>N)?n.s*(0>t?0:1/0):n)},C.squareRoot=C.sqrt=function(){var t,n,r,a,s,u=this,c=u.c,l=u.s,f=u.e,p=j+4,m=new e("0.5");if(1!==l||!c||!c[0])return new e(!l||0>l&&(!c||c[0])?0/0:c?u:1/0);if(l=Math.sqrt(+u),0==l||l==1/0?(n=i(c),(n.length+f)%2==0&&(n+="0"),l=Math.sqrt(n),f=o((f+1)/2)-(0>f||f%2),l==1/0?n="1e"+f:(n=l.toExponential(),n=n.slice(0,n.indexOf("e")+1)+f),r=new e(n)):r=new e(l+""),r.c[0])for(f=r.e,l=f+p,3>l&&(l=0);;)if(s=r,r=m.times(s.plus(E(u,s,p,1))),i(s.c).slice(0,l)===(n=i(r.c)).slice(0,l)){if(r.el&&(g=w,w=_,_=g,a=l,l=m,m=a),a=l+m,g=[];a--;g.push(0));for(y=x,v=B,a=m;--a>=0;){for(r=0,h=_[a]%v,d=_[a]/v|0,u=l,s=a+u;s>a;)f=w[--u]%v,p=w[u]/v|0,c=d*f+p*h,f=h*f+c%v*v+g[s]+r,r=(f/y|0)+(c/v|0)+d*p,g[s--]=f%y;g[s]=r}return r?++i:g.shift(),D(t,g,i)},C.toDigits=function(t,n){var r=new e(this);return t=null!=t&&V(t,1,P,18,"precision")?0|t:null,n=null!=n&&V(n,0,8,18,w)?0|n:U,t?S(r,t,n):r},C.toExponential=function(t,e){return m(this,null!=t&&V(t,0,P,19)?~~t+1:null,e,19)},C.toFixed=function(t,e){return m(this,null!=t&&V(t,0,P,20)?~~t+this.e+1:null,e,20)},C.toFormat=function(t,e){var n=m(this,null!=t&&V(t,0,P,21)?~~t+this.e+1:null,e,21);if(this.c){var r,o=n.split("."),i=+X.groupSize,a=+X.secondaryGroupSize,s=X.groupSeparator,u=o[0],c=o[1],l=this.s<0,f=l?u.slice(1):u,p=f.length;if(a&&(r=i,i=a,a=r,p-=r),i>0&&p>0){for(r=p%i||i,u=f.substr(0,r);p>r;r+=i)u+=s+f.substr(r,i);a>0&&(u+=s+f.slice(r)),l&&(u="-"+u)}n=c?u+X.decimalSeparator+((a=+X.fractionGroupSize)?c.replace(new RegExp("\\d{"+a+"}\\B","g"),"$&"+X.fractionGroupSeparator):c):u}return n},C.toFraction=function(t){var n,r,o,a,s,u,c,l,f,p=J,m=this,h=m.c,d=new e(L),g=r=new e(L),y=c=new e(L);if(null!=t&&(J=!1,u=new e(t),J=p,(!(p=u.isInt())||u.lt(L))&&(J&&k(22,"max denominator "+(p?"out of range":"not an integer"),t),t=!p&&u.c&&S(u,u.e+1,1).gte(L)?u:null)),!h)return m.toString();for(f=i(h),a=d.e=f.length-m.e-1,d.c[0]=O[(s=a%I)<0?I+s:s],t=!t||u.cmp(d)>0?a>0?d:g:u,s=G,G=1/0,u=new e(f),c.c[0]=0;l=E(u,d,0,1),o=r.plus(l.times(y)),1!=o.cmp(t);)r=y,y=o,g=c.plus(l.times(o=g)),c=o,d=u.minus(l.times(o=d)),u=o;return o=E(t.minus(r),y,0,1),c=c.plus(o.times(g)),r=r.plus(o.times(y)),c.s=g.s=m.s,a*=2,n=E(g,y,a,U).minus(m).abs().cmp(E(c,r,a,U).minus(m).abs())<1?[g.toString(),y.toString()]:[c.toString(),r.toString()],G=s,n},C.toNumber=function(){var t=this;return+t||(t.s?0*t.s:0/0)},C.toPower=C.pow=function(t){var n,r,o=v(0>t?-t:+t),i=this;if(!V(t,-N,N,23,"exponent")&&(!isFinite(t)||o>N&&(t/=0)||parseFloat(t)!=t&&!(t=0/0)))return new e(Math.pow(+i,t));for(n=z?y(z/I+2):0,r=new e(L);;){if(o%2){if(r=r.times(i),!r.c)break;n&&r.c.length>n&&(r.c.length=n)}if(o=v(o/2),!o)break;i=i.times(i),n&&i.c&&i.c.length>n&&(i.c.length=n)}return 0>t&&(r=L.div(r)),n?S(r,z,U):r},C.toPrecision=function(t,e){return m(this,null!=t&&V(t,1,P,24,"precision")?0|t:null,e,24)},C.toString=function(t){var e,r=this,o=r.s,a=r.e;return null===a?o?(e="Infinity",0>o&&(e="-"+e)):e="NaN":(e=i(r.c),e=null!=t&&V(t,2,64,25,"base")?n(f(e,a),0|t,10,o):H>=a||a>=q?l(e,a):f(e,a),0>o&&r.c[0]&&(e="-"+e)),e},C.truncated=C.trunc=function(){return S(new e(this),this.e+1,1)},C.valueOf=C.toJSON=function(){return this.toString()},null!=t&&e.config(t),e}function o(t){var e=0|t;return t>0||t===e?e:e-1}function i(t){for(var e,n,r=1,o=t.length,i=t[0]+"";o>r;){for(e=t[r++]+"",n=I-e.length;n--;e="0"+e);i+=e}for(o=i.length;48===i.charCodeAt(--o););return i.slice(0,o+1||1)}function a(t,e){var n,r,o=t.c,i=e.c,a=t.s,s=e.s,u=t.e,c=e.e;if(!a||!s)return null;if(n=o&&!o[0],r=i&&!i[0],n||r)return n?r?0:-s:a;if(a!=s)return a;if(n=0>a,r=u==c,!o||!i)return r?0:!o^n?1:-1;if(!r)return u>c^n?1:-1;for(s=(u=o.length)<(c=i.length)?u:c,a=0;s>a;a++)if(o[a]!=i[a])return o[a]>i[a]^n?1:-1;return u==c?0:u>c^n?1:-1}function s(t,e,n){return(t=p(t))>=e&&n>=t}function u(t){return"[object Array]"==Object.prototype.toString.call(t)}function c(t,e,n){for(var r,o,i=[0],a=0,s=t.length;s>a;){for(o=i.length;o--;i[o]*=e);for(i[r=0]+=F.indexOf(t.charAt(a++));rn-1&&(null==i[r+1]&&(i[r+1]=0),i[r+1]+=i[r]/n|0,i[r]%=n)}return i.reverse()}function l(t,e){return(t.length>1?t.charAt(0)+"."+t.slice(1):t)+(0>e?"e":"e+")+e}function f(t,e){var n,r;if(0>e){for(r="0.";++e;r+="0");t=r+t}else if(n=t.length,++e>n){for(r="0",e-=n;--e;r+="0");t+=r}else n>e&&(t=t.slice(0,e)+"."+t.slice(e));return t}function p(t){return t=parseFloat(t),0>t?y(t):v(t)}var m,h,d,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,y=Math.ceil,v=Math.floor,b=" not a boolean or binary digit",w="rounding mode",_="number type has more than 15 significant digits",F="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",x=1e14,I=14,N=9007199254740991,O=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],B=1e7,P=1e9;if(m=r(),"function"==typeof define&&define.amd)define(function(){return m});else if("undefined"!=typeof e&&e.exports){if(e.exports=m,!h)try{h=t("crypto")}catch(T){}}else n.BigNumber=m}(this)},{crypto:28}],web3:[function(t,e,n){var r=t("./lib/web3");r.providers.HttpProvider=t("./lib/web3/httpprovider"),r.providers.QtSyncProvider=t("./lib/web3/qtsync"),r.eth.contract=t("./lib/web3/contract"),r.abi=t("./lib/solidity/abi"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/solidity/abi":1,"./lib/web3":10,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/qtsync":24}]},{},["web3"]); \ No newline at end of file +require=function t(e,n,r){function o(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var c=new Error("Cannot find module '"+a+"'");throw c.code="MODULE_NOT_FOUND",c}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ai;i+=64)n.push(this._outputFormatter(new a(t.dynamicPart().substr(i+64,64))));return n}return this._outputFormatter(t)},u.prototype.sliceParam=function(t,e,n){return"bytes"===this._mode?a.decodeBytes(t,e):s(n)?a.decodeArray(t,e):a.decodeParam(t,e)};var c=function(t){this._types=t};c.prototype._requireType=function(t){var e=this._types.filter(function(e){return e.isType(t)})[0];if(!e)throw Error("invalid solidity type!: "+t);return e},c.prototype._formatInput=function(t,e){return this._requireType(t).formatInput(e,s(t))},c.prototype.encodeParam=function(t,e){return this._formatInput(t,e).encode()},c.prototype.encodeParams=function(t,e){var n=this,r=t.map(function(t,r){return n._formatInput(t,e[r])});return a.encodeList(r)},c.prototype.decodeParam=function(t,e){return this.decodeParams([t],e)[0]},c.prototype.decodeParams=function(t,e){var n=this;return t.map(function(t,r){var o=n._requireType(t),i=o.sliceParam(e,r,t);return o.formatOutput(i,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:i.formatInputBool,outputFormatter:i.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:i.formatInputInt,outputFormatter:i.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:i.formatInputDynamicBytes,outputFormatter:i.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:i.formatInputBytes,outputFormatter:i.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:i.formatInputReal,outputFormatter:i.formatOutputUReal})]);e.exports=l},{"../utils/utils":6,"./formatters":2,"./param":3,"bignumber.js":"bignumber.js"}],2:[function(t,e,n){var r=t("bignumber.js"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./param"),s=function(t){var e=2*i.ETH_PADDING;r.config(i.ETH_BIGNUMBER_ROUNDING_MODE);var n=o.padLeft(o.toTwosComplement(t).round().toString(16),e);return new a(n)},u=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=o.fromAscii(t,i.ETH_PADDING).substr(2);return new a(s(t.length).value+e,32)},l=function(t){var e="000000000000000000000000000000000000000000000000000000000000000"+(t?"1":"0");return new a(e)},f=function(t){return s(new r(t).times(new r(2).pow(128)))},p=function(t){return"1"===new r(t.substr(0,1),16).toString(2).substr(0,1)},m=function(t){var e=t.staticPart()||"0";return p(e)?new r(e,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(e,16)},h=function(t){var e=t.staticPart()||"0";return new r(e,16)},d=function(t){return m(t).dividedBy(new r(2).pow(128))},g=function(t){return h(t).dividedBy(new r(2).pow(128))},y=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},v=function(t){return o.toAscii(t.staticPart())},b=function(t){return o.toAscii(t.dynamicPart().slice(64))},w=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputBool:l,formatInputReal:f,formatOutputInt:m,formatOutputUInt:h,formatOutputReal:d,formatOutputUReal:g,formatOutputBool:y,formatOutputBytes:v,formatOutputDynamicBytes:b,formatOutputAddress:w}},{"../utils/config":5,"../utils/utils":6,"./param":3,"bignumber.js":"bignumber.js"}],3:[function(t,e,n){var r=t("../utils/utils"),o=function(t,e){this.value=t||"",this.offset=e};o.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},o.prototype.withOffset=function(t){return new o(this.value,t)},o.prototype.combine=function(t){return new o(this.value+t.value)},o.prototype.isDynamic=function(){return this.value.length>64},o.prototype.offsetAsBytes=function(){return this.isDynamic()?r.padLeft(r.toTwosComplement(this.offset).toString(16),64):""},o.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},o.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},o.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},o.encodeList=function(t){var e=32*t.length,n=t.map(function(t){if(!t.isDynamic())return t;var n=e;return e+=t.dynamicPartLength(),t.withOffset(n)});return n.reduce(function(t,e){return t+e.dynamicPart()},n.reduce(function(t,e){return t+e.staticPart()},""))},o.decodeParam=function(t,e){return e=e||0,new o(t.substr(64*e,64))};var i=function(t,e){return parseInt("0x"+t.substr(64*e,64))};o.decodeBytes=function(t,e){e=e||0;var n=i(t,e);return new o(t.substr(2*n,128))},o.decodeArray=function(t,e){e=e||0;var n=i(t,e),r=parseInt("0x"+t.substr(2*n,64));return new o(t.substr(2*n,64*(r+1)))},e.exports=o},{"../utils/utils":6}],4:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],5:[function(t,e,n){var r=t("bignumber.js"),o=["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:o,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:1e3,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],6:[function(t,e,n){var r=t("bignumber.js"),o={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"},i=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t){var e="",n=0,r=t.length;for("0x"===t.substring(0,2)&&(n=2);r>n;n+=2){var o=parseInt(t.substr(n,2),16);if(0===o)break;e+=String.fromCharCode(o)}return e},s=function(t){for(var e="",n=0;nthis._inputTypes.length&&i.isObject(t[t.length-1])&&(e=t[t.length-1]),e.to=this._address,e.data="0x"+this.signature()+o.encodeParams(this._inputTypes,t),e},a.prototype.signature=function(){return r.sha3(r.fromAscii(this._name)).slice(2,10)},a.prototype.unpackOutput=function(t){if(null!==t){t=t.length>=2?t.slice(2):t;var e=o.decodeParams(this._outputTypes,t);return 1===e.length?e[0]:e}},a.prototype.call=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);if(!e){var o=r.eth.call(n);return this.unpackOutput(o)}var i=this;r.eth.call(n,function(t,n){e(t,i.unpackOutput(n))})},a.prototype.sendTransaction=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.sendTransaction(n,e):void r.eth.sendTransaction(n)},a.prototype.displayName=function(){return i.extractDisplayName(this._name)},a.prototype.typeName=function(){return i.extractTypeName(this._name)},a.prototype.request=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t),r=this.unpackOutput.bind(this);return{callback:e,payload:n,format:r}},a.prototype.execute=function(){var t=!this._constant;return t?this.sendTransaction.apply(this,Array.prototype.slice.call(arguments)):this.call.apply(this,Array.prototype.slice.call(arguments))},a.prototype.attachToContract=function(t){var e=this.execute.bind(this);e.request=this.request.bind(this),e.call=this.call.bind(this),e.sendTransaction=this.sendTransaction.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=a},{"../solidity/coder":1,"../utils/utils":6,"../web3":8}],18:[function(t,e,n){"use strict";var r=t("xmlhttprequest").XMLHttpRequest,o=t("./errors"),i=function(t){this.host=t||"http://localhost:8545"};i.prototype.send=function(t){var e=new r;e.open("POST",this.host,!1);try{e.send(JSON.stringify(t))}catch(n){throw o.InvalidConnection(this.host)}var i=e.responseText;try{i=JSON.parse(i)}catch(a){throw o.InvalidResponse(i)}return i},i.prototype.sendAsync=function(t,e){var n=new r;n.onreadystatechange=function(){if(4===n.readyState){var t=n.responseText,r=null;try{t=JSON.parse(t)}catch(i){r=o.InvalidResponse(t)}e(r,t)}},n.open("POST",this.host,!0);try{n.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":12,xmlhttprequest:4}],19:[function(t,e,n){var r=function(){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,void(this.messageId=1))};r.getInstance=function(){var t=new r;return t},r.prototype.toPayload=function(t,e){return t||console.error("jsonrpc method should be specified!"),{jsonrpc:"2.0",method:t,params:e||[],id:this.messageId++}},r.prototype.isValidResponse=function(t){return!!t&&!t.error&&"2.0"===t.jsonrpc&&"number"==typeof t.id&&void 0!==t.result},r.prototype.toBatchPayload=function(t){var e=this;return t.map(function(t){return e.toPayload(t.method,t.params)})},e.exports=r},{}],20:[function(t,e,n){var r=t("./requestmanager"),o=t("../utils/utils"),i=t("./errors"),a=function(t){this.name=t.name,this.call=t.call,this.params=t.params||0,this.inputFormatter=t.inputFormatter,this.outputFormatter=t.outputFormatter};a.prototype.getCall=function(t){return o.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():void 0},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw i.InvalidNumberOfParams()},a.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter.map(function(e,n){return e?e(t[n]):t[n]}):t},a.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},a.prototype.attachToObject=function(t){var e=this.send.bind(this);e.request=this.request.bind(this),e.call=this.call;var n=this.name.split(".");n.length>1?(t[n[0]]=t[n[0]]||{},t[n[0]][n[1]]=e):t[n[0]]=e},a.prototype.toPayload=function(t){var e=this.getCall(t),n=this.extractCallback(t),r=this.formatInput(t);return this.validateArgs(r),{method:e,params:r,callback:n}},a.prototype.request=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));return t.format=this.formatOutput.bind(this),t},a.prototype.send=function(){var t=this.toPayload(Array.prototype.slice.call(arguments));if(t.callback){var e=this;return r.getInstance().sendAsync(t,function(n,r){t.callback(n,e.formatOutput(r))})}return this.formatOutput(r.getInstance().send(t))},e.exports=a},{"../utils/utils":6,"./errors":12,"./requestmanager":24}],21:[function(t,e,n){var r=t("../utils/utils"),o=t("./property"),i=[],a=[new o({name:"listening",getter:"net_listening"}),new o({name:"peerCount",getter:"net_peerCount",outputFormatter:r.toDecimal})];e.exports={methods:i,properties:a}},{"../utils/utils":6,"./property":22}],22:[function(t,e,n){var r=t("./requestmanager"),o=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};o.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},o.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},o.prototype.attachToObject=function(t){var e={get:this.get.bind(this)},n=this.name.split("."),r=n[0];n.length>1&&(t[n[0]]=t[n[0]]||{},t=t[n[0]],r=n[1]),Object.defineProperty(t,r,e);var o=function(t,e){return t+e.charAt(0).toUpperCase()+e.slice(1)};t[o("get",r)]=this.getAsync.bind(this)},o.prototype.get=function(){return this.formatOutput(r.getInstance().send({method:this.getter}))},o.prototype.getAsync=function(t){var e=this;r.getInstance().sendAsync({method:this.getter},function(n,r){return n?t(n):void t(n,e.formatOutput(r))})},e.exports=o},{"./requestmanager":24}],23:[function(t,e,n){var r=function(){};r.prototype.send=function(t){var e=navigator.qt.callMethod(JSON.stringify(t));return JSON.parse(e)},e.exports=r},{}],24:[function(t,e,n){var r=t("./jsonrpc"),o=t("../utils/utils"),i=t("../utils/config"),a=t("./errors"),s=function(t){return arguments.callee._singletonInstance?arguments.callee._singletonInstance:(arguments.callee._singletonInstance=this,this.provider=t,this.polls=[],this.timeout=null,void this.poll())};s.getInstance=function(){var t=new s;return t},s.prototype.send=function(t){if(!this.provider)return console.error(a.InvalidProvider()),null;var e=r.getInstance().toPayload(t.method,t.params),n=this.provider.send(e);if(!r.getInstance().isValidResponse(n))throw a.InvalidResponse(n);return n.result},s.prototype.sendAsync=function(t,e){if(!this.provider)return e(a.InvalidProvider());var n=r.getInstance().toPayload(t.method,t.params);this.provider.sendAsync(n,function(t,n){return t?e(t):r.getInstance().isValidResponse(n)?void e(null,n.result):e(a.InvalidResponse(n))})},s.prototype.sendBatch=function(t,e){if(!this.provider)return e(a.InvalidProvider());var n=r.getInstance().toBatchPayload(t);this.provider.sendAsync(n,function(t,n){return t?e(t):o.isArray(n)?void e(t,n):e(a.InvalidResponse(n))})},s.prototype.setProvider=function(t){this.provider=t},s.prototype.startPolling=function(t,e,n,r){this.polls.push({data:t,id:e,callback:n,uninstall:r})},s.prototype.stopPolling=function(t){for(var e=this.polls.length;e--;){var n=this.polls[e];n.id===t&&this.polls.splice(e,1)}},s.prototype.reset=function(){this.polls.forEach(function(t){t.uninstall(t.id)}),this.polls=[],this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),i.ETH_POLLING_TIMEOUT),this.polls.length){if(!this.provider)return void console.error(a.InvalidProvider());var t=r.getInstance().toBatchPayload(this.polls.map(function(t){ +return t.data})),e=this;this.provider.sendAsync(t,function(t,n){if(!t){if(!o.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){return t.callback=e.polls[n].callback,t}).filter(function(t){var e=r.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return o.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}},e.exports=s},{"../utils/config":5,"../utils/utils":6,"./errors":12,"./jsonrpc":19}],25:[function(t,e,n){var r=t("./method"),o=t("./formatters"),i=new r({name:"post",call:"shh_post",params:1,inputFormatter:[o.inputPostFormatter]}),a=new r({name:"newIdentity",call:"shh_newIdentity",params:0}),s=new r({name:"hasIdentity",call:"shh_hasIdentity",params:1}),u=new r({name:"newGroup",call:"shh_newGroup",params:0}),c=new r({name:"addToGroup",call:"shh_addToGroup",params:0}),l=[i,a,s,u,c];e.exports={methods:l}},{"./formatters":16,"./method":20}],26:[function(t,e,n){var r=t("./method"),o=function(){var t=function(t){var e=t[0];switch(e){case"latest":return t.pop(),this.params=0,"eth_newBlockFilter";case"pending":return t.pop(),this.params=0,"eth_newPendingTransactionFilter";default:return"eth_newFilter"}},e=new r({name:"newFilter",call:t,params:1}),n=new r({name:"uninstallFilter",call:"eth_uninstallFilter",params:1}),o=new r({name:"getLogs",call:"eth_getFilterLogs",params:1}),i=new r({name:"poll",call:"eth_getFilterChanges",params:1});return[e,n,o,i]},i=function(){var t=new r({name:"newFilter",call:"shh_newFilter",params:1}),e=new r({name:"uninstallFilter",call:"shh_uninstallFilter",params:1}),n=new r({name:"getLogs",call:"shh_getMessages",params:1}),o=new r({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,n,o]};e.exports={eth:o,shh:i}},{"./method":20}],27:[function(t,e,n){},{}],"bignumber.js":[function(t,e,n){!function(n){"use strict";function r(t){function e(t,r){var o,i,a,s,u,c,l=this;if(!(l instanceof e))return W&&D(26,"constructor call without new",t),new e(t,r);if(null!=r&&J(r,2,64,R,"base")){if(r=0|r,c=t+"",10==r)return l=new e(t instanceof e?t:c),S(l,L+l.e+1,U);if((s="number"==typeof t)&&0*t!=0||!new RegExp("^-?"+(o="["+F.slice(0,r)+"]+")+"(?:\\."+o+")?$",37>r?"i":"").test(c))return d(l,c,s,r);s?(l.s=0>1/t?(c=c.slice(1),-1):1,W&&c.replace(/^0\.0*|\./,"").length>15&&D(R,_,t),s=!1):l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1,c=n(c,10,r,l.s)}else{if(t instanceof e)return l.s=t.s,l.e=t.e,l.c=(t=t.c)?t.slice():t,void(R=0);if((s="number"==typeof t)&&0*t==0){if(l.s=0>1/t?(t=-t,-1):1,t===~~t){for(i=0,a=t;a>=10;a/=10,i++);return l.e=i,l.c=[t],void(R=0)}c=t+""}else{if(!g.test(c=t+""))return d(l,c,s);l.s=45===c.charCodeAt(0)?(c=c.slice(1),-1):1}}for((i=c.indexOf("."))>-1&&(c=c.replace(".","")),(a=c.search(/e/i))>0?(0>i&&(i=a),i+=+c.slice(a+1),c=c.substring(0,a)):0>i&&(i=c.length),a=0;48===c.charCodeAt(a);a++);for(u=c.length;48===c.charCodeAt(--u););if(c=c.slice(a,u+1))if(u=c.length,s&&W&&u>15&&D(R,_,l.s*t),i=i-a-1,i>G)l.c=l.e=null;else if(M>i)l.c=[l.e=0];else{if(l.e=i,l.c=[],a=(i+1)%I,0>i&&(a+=I),u>a){for(a&&l.c.push(+c.slice(0,a)),u-=I;u>a;)l.c.push(+c.slice(a,a+=I));c=c.slice(a),a=I-c.length}else a-=u;for(;a--;c+="0");l.c.push(+c)}else l.c=[l.e=0];R=0}function n(t,n,r,o){var a,s,u,l,p,m,h,d=t.indexOf("."),g=L,y=U;for(37>r&&(t=t.toLowerCase()),d>=0&&(u=z,z=0,t=t.replace(".",""),h=new e(r),p=h.pow(t.length-d),z=u,h.c=c(f(i(p.c),p.e),10,n),h.e=h.c.length),m=c(t,r,n),s=u=m.length;0==m[--u];m.pop());if(!m[0])return"0";if(0>d?--s:(p.c=m,p.e=s,p.s=o,p=E(p,h,g,y,n),m=p.c,l=p.r,s=p.e),a=s+g+1,d=m[a],u=n/2,l=l||0>a||null!=m[a+1],l=4>y?(null!=d||l)&&(0==y||y==(p.s<0?3:2)):d>u||d==u&&(4==y||l||6==y&&1&m[a-1]||y==(p.s<0?8:7)),1>a||!m[0])t=l?f("1",-g):"0";else{if(m.length=a,l)for(--n;++m[--a]>n;)m[a]=0,a||(++s,m.unshift(1));for(u=m.length;!m[--u];);for(d=0,t="";u>=d;t+=F.charAt(m[d++]));t=f(t,s)}return t}function m(t,n,r,o){var a,s,u,c,p;if(r=null!=r&&J(r,0,8,o,w)?0|r:U,!t.c)return t.toString();if(a=t.c[0],u=t.e,null==n)p=i(t.c),p=19==o||24==o&&j>=u?l(p,u):f(p,u);else if(t=S(new e(t),n,r),s=t.e,p=i(t.c),c=p.length,19==o||24==o&&(s>=n||j>=s)){for(;n>c;p+="0",c++);p=l(p,s)}else if(n-=u,p=f(p,s),s+1>c){if(--n>0)for(p+=".";n--;p+="0");}else if(n+=s-c,n>0)for(s+1==c&&(p+=".");n--;p+="0");return t.s<0&&a?"-"+p:p}function T(t,n){var r,o,i=0;for(u(t[0])&&(t=t[0]),r=new e(t[0]);++it||t>n||t!=p(t))&&D(r,(o||"decimal places")+(e>t||t>n?" out of range":" not an integer"),t),!0}function k(t,e,n){for(var r=1,o=e.length;!e[--o];e.pop());for(o=e[0];o>=10;o/=10,r++);return(n=r+n*I-1)>G?t.c=t.e=null:M>n?t.c=[t.e=0]:(t.e=n,t.c=e),t}function D(t,e,n){var r=new Error(["new BigNumber","cmp","config","div","divToInt","eq","gt","gte","lt","lte","minus","mod","plus","precision","random","round","shift","times","toDigits","toExponential","toFixed","toFormat","toFraction","pow","toPrecision","toString","BigNumber"][t]+"() "+e+": "+n);throw r.name="BigNumber Error",R=0,r}function S(t,e,n,r){var o,i,a,s,u,c,l,f=t.c,p=O;if(f){t:{for(o=1,s=f[0];s>=10;s/=10,o++);if(i=e-o,0>i)i+=I,a=e,u=f[c=0],l=u/p[o-a-1]%10|0;else if(c=y((i+1)/I),c>=f.length){if(!r)break t;for(;f.length<=c;f.push(0));u=l=0,o=1,i%=I,a=i-I+1}else{for(u=s=f[c],o=1;s>=10;s/=10,o++);i%=I,a=i-I+o,l=0>a?0:u/p[o-a-1]%10|0}if(r=r||0>e||null!=f[c+1]||(0>a?u:u%p[o-a-1]),r=4>n?(l||r)&&(0==n||n==(t.s<0?3:2)):l>5||5==l&&(4==n||r||6==n&&(i>0?a>0?u/p[o-a]:0:f[c-1])%10&1||n==(t.s<0?8:7)),1>e||!f[0])return f.length=0,r?(e-=t.e+1,f[0]=p[e%I],t.e=-e||0):f[0]=t.e=0,t;if(0==i?(f.length=c,s=1,c--):(f.length=c+1,s=p[I-i],f[c]=a>0?v(u/p[o-a]%p[a])*s:0),r)for(;;){if(0==c){for(i=1,a=f[0];a>=10;a/=10,i++);for(a=f[0]+=s,s=1;a>=10;a/=10,s++);i!=s&&(t.e++,f[0]==x&&(f[0]=1));break}if(f[c]+=s,f[c]!=x)break;f[c--]=0,s=1}for(i=f.length;0===f[--i];f.pop());}t.e>G?t.c=t.e=null:t.en?null!=(t=o[n++]):void 0};return a(e="DECIMAL_PLACES")&&J(t,0,P,2,e)&&(L=0|t),r[e]=L,a(e="ROUNDING_MODE")&&J(t,0,8,2,e)&&(U=0|t),r[e]=U,a(e="EXPONENTIAL_AT")&&(u(t)?J(t[0],-P,0,2,e)&&J(t[1],0,P,2,e)&&(j=0|t[0],H=0|t[1]):J(t,-P,P,2,e)&&(j=-(H=0|(0>t?-t:t)))),r[e]=[j,H],a(e="RANGE")&&(u(t)?J(t[0],-P,-1,2,e)&&J(t[1],1,P,2,e)&&(M=0|t[0],G=0|t[1]):J(t,-P,P,2,e)&&(0|t?M=-(G=0|(0>t?-t:t)):W&&D(2,e+" cannot be zero",t))),r[e]=[M,G],a(e="ERRORS")&&(t===!!t||1===t||0===t?(R=0,J=(W=!!t)?A:s):W&&D(2,e+b,t)),r[e]=W,a(e="CRYPTO")&&(t===!!t||1===t||0===t?(V=!(!t||!h||"object"!=typeof h),t&&!V&&W&&D(2,"crypto unavailable",h)):W&&D(2,e+b,t)),r[e]=V,a(e="MODULO_MODE")&&J(t,0,9,2,e)&&($=0|t),r[e]=$,a(e="POW_PRECISION")&&J(t,0,P,2,e)&&(z=0|t),r[e]=z,a(e="FORMAT")&&("object"==typeof t?X=t:W&&D(2,e+" not an object",t)),r[e]=X,r},e.max=function(){return T(arguments,C.lt)},e.min=function(){return T(arguments,C.gt)},e.random=function(){var t=9007199254740992,n=Math.random()*t&2097151?function(){return v(Math.random()*t)}:function(){return 8388608*(1073741824*Math.random()|0)+(8388608*Math.random()|0)};return function(t){var r,o,i,a,s,u=0,c=[],l=new e(q);if(t=null!=t&&J(t,0,P,14)?0|t:L,a=y(t/I),V)if(h&&h.getRandomValues){for(r=h.getRandomValues(new Uint32Array(a*=2));a>u;)s=131072*r[u]+(r[u+1]>>>11),s>=9e15?(o=h.getRandomValues(new Uint32Array(2)),r[u]=o[0],r[u+1]=o[1]):(c.push(s%1e14),u+=2);u=a/2}else if(h&&h.randomBytes){for(r=h.randomBytes(a*=7);a>u;)s=281474976710656*(31&r[u])+1099511627776*r[u+1]+4294967296*r[u+2]+16777216*r[u+3]+(r[u+4]<<16)+(r[u+5]<<8)+r[u+6],s>=9e15?h.randomBytes(7).copy(r,u):(c.push(s%1e14),u+=7);u=a/7}else W&&D(14,"crypto unavailable",h);if(!u)for(;a>u;)s=n(),9e15>s&&(c[u++]=s%1e14);for(a=c[--u],t%=I,a&&t&&(s=O[I-t],c[u]=v(a/s)*s);0===c[u];c.pop(),u--);if(0>u)c=[i=0];else{for(i=-1;0===c[0];c.shift(),i-=I);for(u=1,s=c[0];s>=10;s/=10,u++);I>u&&(i-=I-u)}return l.e=i,l.c=c,l}}(),E=function(){function t(t,e,n){var r,o,i,a,s=0,u=t.length,c=e%B,l=e/B|0;for(t=t.slice();u--;)i=t[u]%B,a=t[u]/B|0,r=l*i+a*c,o=c*i+r%B*B+s,s=(o/n|0)+(r/B|0)+l*a,t[u]=o%n;return s&&t.unshift(s),t}function n(t,e,n,r){var o,i;if(n!=r)i=n>r?1:-1;else for(o=i=0;n>o;o++)if(t[o]!=e[o]){i=t[o]>e[o]?1:-1;break}return i}function r(t,e,n,r){for(var o=0;n--;)t[n]-=o,o=t[n]1;t.shift());}return function(i,a,s,u,c){var l,f,p,m,h,d,g,y,b,w,_,F,N,O,B,P,T,A=i.s==a.s?1:-1,k=i.c,D=a.c;if(!(k&&k[0]&&D&&D[0]))return new e(i.s&&a.s&&(k?!D||k[0]!=D[0]:D)?k&&0==k[0]||!D?0*A:A/0:0/0);for(y=new e(A),b=y.c=[],f=i.e-a.e,A=s+f+1,c||(c=x,f=o(i.e/I)-o(a.e/I),A=A/I|0),p=0;D[p]==(k[p]||0);p++);if(D[p]>(k[p]||0)&&f--,0>A)b.push(1),m=!0;else{for(O=k.length,P=D.length,p=0,A+=2,h=v(c/(D[0]+1)),h>1&&(D=t(D,h,c),k=t(k,h,c),P=D.length,O=k.length),N=P,w=k.slice(0,P),_=w.length;P>_;w[_++]=0);T=D.slice(),T.unshift(0),B=D[0],D[1]>=c/2&&B++;do{if(h=0,l=n(D,w,P,_),0>l){if(F=w[0],P!=_&&(F=F*c+(w[1]||0)),h=v(F/B),h>1)for(h>=c&&(h=c-1),d=t(D,h,c),g=d.length,_=w.length;1==n(d,w,g,_);)h--,r(d,g>P?T:D,g,c),g=d.length,l=1;else 0==h&&(l=h=1),d=D.slice(),g=d.length;if(_>g&&d.unshift(0),r(w,d,_,c),_=w.length,-1==l)for(;n(D,w,P,_)<1;)h++,r(w,_>P?T:D,_,c),_=w.length}else 0===l&&(h++,w=[0]);b[p++]=h,w[0]?w[_++]=k[N]||0:(w=[k[N]],_=1)}while((N++=10;A/=10,p++);S(y,s+(y.e=p+f*I-1)+1,u,m)}else y.e=f,y.r=+m;return y}}(),d=function(){var t=/^(-?)0([xbo])/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,o=/^-?(Infinity|NaN)$/,i=/^\s*\+|^\s+|\s+$/g;return function(a,s,u,c){var l,f=u?s:s.replace(i,"");if(o.test(f))a.s=isNaN(f)?null:0>f?-1:1;else{if(!u&&(f=f.replace(t,function(t,e,n){return l="x"==(n=n.toLowerCase())?16:"b"==n?2:8,c&&c!=l?t:e}),c&&(l=c,f=f.replace(n,"$1").replace(r,"0.$1")),s!=f))return new e(f,l);W&&D(R,"not a"+(c?" base "+c:"")+" number",s),a.s=null}a.c=a.e=null,R=0}}(),C.absoluteValue=C.abs=function(){var t=new e(this);return t.s<0&&(t.s=1),t},C.ceil=function(){return S(new e(this),this.e+1,2)},C.comparedTo=C.cmp=function(t,n){return R=1,a(this,new e(t,n))},C.decimalPlaces=C.dp=function(){var t,e,n=this.c;if(!n)return null;if(t=((e=n.length-1)-o(this.e/I))*I,e=n[e])for(;e%10==0;e/=10,t--);return 0>t&&(t=0),t},C.dividedBy=C.div=function(t,n){return R=3,E(this,new e(t,n),L,U)},C.dividedToIntegerBy=C.divToInt=function(t,n){return R=4,E(this,new e(t,n),0,1)},C.equals=C.eq=function(t,n){return R=5,0===a(this,new e(t,n))},C.floor=function(){return S(new e(this),this.e+1,3)},C.greaterThan=C.gt=function(t,n){return R=6,a(this,new e(t,n))>0},C.greaterThanOrEqualTo=C.gte=function(t,n){return R=7,1===(n=a(this,new e(t,n)))||0===n},C.isFinite=function(){return!!this.c},C.isInteger=C.isInt=function(){return!!this.c&&o(this.e/I)>this.c.length-2},C.isNaN=function(){return!this.s},C.isNegative=C.isNeg=function(){return this.s<0},C.isZero=function(){return!!this.c&&0==this.c[0]},C.lessThan=C.lt=function(t,n){return R=8,a(this,new e(t,n))<0},C.lessThanOrEqualTo=C.lte=function(t,n){return R=9,-1===(n=a(this,new e(t,n)))||0===n},C.minus=C.sub=function(t,n){var r,i,a,s,u=this,c=u.s;if(R=10,t=new e(t,n),n=t.s,!c||!n)return new e(0/0);if(c!=n)return t.s=-n,u.plus(t);var l=u.e/I,f=t.e/I,p=u.c,m=t.c;if(!l||!f){if(!p||!m)return p?(t.s=-n,t):new e(m?u:0/0);if(!p[0]||!m[0])return m[0]?(t.s=-n,t):new e(p[0]?u:3==U?-0:0)}if(l=o(l),f=o(f),p=p.slice(),c=l-f){for((s=0>c)?(c=-c,a=p):(f=l,a=m),a.reverse(),n=c;n--;a.push(0));a.reverse()}else for(i=(s=(c=p.length)<(n=m.length))?c:n,c=n=0;i>n;n++)if(p[n]!=m[n]){s=p[n]0)for(;n--;p[r++]=0);for(n=x-1;i>c;){if(p[--i]0?(u=s,r=l):(a=-a,r=c),r.reverse();a--;r.push(0));r.reverse()}for(a=c.length,n=l.length,0>a-n&&(r=l,l=c,c=r,n=a),a=0;n;)a=(c[--n]=c[n]+l[n]+a)/x|0,c[n]%=x;return a&&(c.unshift(a),++u),k(t,c,u)},C.precision=C.sd=function(t){var e,n,r=this,o=r.c;if(null!=t&&t!==!!t&&1!==t&&0!==t&&(W&&D(13,"argument"+b,t),t!=!!t&&(t=null)),!o)return null;if(n=o.length-1,e=n*I+1,n=o[n]){for(;n%10==0;n/=10,e--);for(n=o[0];n>=10;n/=10,e++);}return t&&r.e+1>e&&(e=r.e+1),e},C.round=function(t,n){var r=new e(this);return(null==t||J(t,0,P,15))&&S(r,~~t+this.e+1,null!=n&&J(n,0,8,15,w)?0|n:U),r},C.shift=function(t){var n=this;return J(t,-N,N,16,"argument")?n.times("1e"+p(t)):new e(n.c&&n.c[0]&&(-N>t||t>N)?n.s*(0>t?0:1/0):n)},C.squareRoot=C.sqrt=function(){var t,n,r,a,s,u=this,c=u.c,l=u.s,f=u.e,p=L+4,m=new e("0.5");if(1!==l||!c||!c[0])return new e(!l||0>l&&(!c||c[0])?0/0:c?u:1/0);if(l=Math.sqrt(+u),0==l||l==1/0?(n=i(c),(n.length+f)%2==0&&(n+="0"),l=Math.sqrt(n),f=o((f+1)/2)-(0>f||f%2),l==1/0?n="1e"+f:(n=l.toExponential(),n=n.slice(0,n.indexOf("e")+1)+f),r=new e(n)):r=new e(l+""),r.c[0])for(f=r.e,l=f+p,3>l&&(l=0);;)if(s=r,r=m.times(s.plus(E(u,s,p,1))),i(s.c).slice(0,l)===(n=i(r.c)).slice(0,l)){if(r.el&&(g=w,w=_,_=g,a=l,l=m,m=a),a=l+m,g=[];a--;g.push(0));for(y=x,v=B,a=m;--a>=0;){for(r=0,h=_[a]%v,d=_[a]/v|0,u=l,s=a+u;s>a;)f=w[--u]%v,p=w[u]/v|0,c=d*f+p*h,f=h*f+c%v*v+g[s]+r,r=(f/y|0)+(c/v|0)+d*p,g[s--]=f%y;g[s]=r}return r?++i:g.shift(),k(t,g,i)},C.toDigits=function(t,n){var r=new e(this);return t=null!=t&&J(t,1,P,18,"precision")?0|t:null,n=null!=n&&J(n,0,8,18,w)?0|n:U,t?S(r,t,n):r},C.toExponential=function(t,e){return m(this,null!=t&&J(t,0,P,19)?~~t+1:null,e,19)},C.toFixed=function(t,e){return m(this,null!=t&&J(t,0,P,20)?~~t+this.e+1:null,e,20)},C.toFormat=function(t,e){var n=m(this,null!=t&&J(t,0,P,21)?~~t+this.e+1:null,e,21);if(this.c){var r,o=n.split("."),i=+X.groupSize,a=+X.secondaryGroupSize,s=X.groupSeparator,u=o[0],c=o[1],l=this.s<0,f=l?u.slice(1):u,p=f.length;if(a&&(r=i,i=a,a=r,p-=r),i>0&&p>0){for(r=p%i||i,u=f.substr(0,r);p>r;r+=i)u+=s+f.substr(r,i);a>0&&(u+=s+f.slice(r)),l&&(u="-"+u)}n=c?u+X.decimalSeparator+((a=+X.fractionGroupSize)?c.replace(new RegExp("\\d{"+a+"}\\B","g"),"$&"+X.fractionGroupSeparator):c):u}return n},C.toFraction=function(t){var n,r,o,a,s,u,c,l,f,p=W,m=this,h=m.c,d=new e(q),g=r=new e(q),y=c=new e(q);if(null!=t&&(W=!1,u=new e(t),W=p,(!(p=u.isInt())||u.lt(q))&&(W&&D(22,"max denominator "+(p?"out of range":"not an integer"),t),t=!p&&u.c&&S(u,u.e+1,1).gte(q)?u:null)),!h)return m.toString();for(f=i(h),a=d.e=f.length-m.e-1,d.c[0]=O[(s=a%I)<0?I+s:s],t=!t||u.cmp(d)>0?a>0?d:g:u,s=G,G=1/0,u=new e(f),c.c[0]=0;l=E(u,d,0,1),o=r.plus(l.times(y)),1!=o.cmp(t);)r=y,y=o,g=c.plus(l.times(o=g)),c=o,d=u.minus(l.times(o=d)),u=o;return o=E(t.minus(r),y,0,1),c=c.plus(o.times(g)),r=r.plus(o.times(y)),c.s=g.s=m.s,a*=2,n=E(g,y,a,U).minus(m).abs().cmp(E(c,r,a,U).minus(m).abs())<1?[g.toString(),y.toString()]:[c.toString(),r.toString()],G=s,n},C.toNumber=function(){var t=this;return+t||(t.s?0*t.s:0/0)},C.toPower=C.pow=function(t){var n,r,o=v(0>t?-t:+t),i=this;if(!J(t,-N,N,23,"exponent")&&(!isFinite(t)||o>N&&(t/=0)||parseFloat(t)!=t&&!(t=0/0)))return new e(Math.pow(+i,t));for(n=z?y(z/I+2):0,r=new e(q);;){if(o%2){if(r=r.times(i),!r.c)break;n&&r.c.length>n&&(r.c.length=n)}if(o=v(o/2),!o)break;i=i.times(i),n&&i.c&&i.c.length>n&&(i.c.length=n)}return 0>t&&(r=q.div(r)),n?S(r,z,U):r},C.toPrecision=function(t,e){return m(this,null!=t&&J(t,1,P,24,"precision")?0|t:null,e,24)},C.toString=function(t){var e,r=this,o=r.s,a=r.e;return null===a?o?(e="Infinity",0>o&&(e="-"+e)):e="NaN":(e=i(r.c),e=null!=t&&J(t,2,64,25,"base")?n(f(e,a),0|t,10,o):j>=a||a>=H?l(e,a):f(e,a),0>o&&r.c[0]&&(e="-"+e)),e},C.truncated=C.trunc=function(){return S(new e(this),this.e+1,1)},C.valueOf=C.toJSON=function(){return this.toString()},null!=t&&e.config(t),e}function o(t){var e=0|t;return t>0||t===e?e:e-1}function i(t){for(var e,n,r=1,o=t.length,i=t[0]+"";o>r;){for(e=t[r++]+"",n=I-e.length;n--;e="0"+e);i+=e}for(o=i.length;48===i.charCodeAt(--o););return i.slice(0,o+1||1)}function a(t,e){var n,r,o=t.c,i=e.c,a=t.s,s=e.s,u=t.e,c=e.e;if(!a||!s)return null;if(n=o&&!o[0],r=i&&!i[0],n||r)return n?r?0:-s:a;if(a!=s)return a;if(n=0>a,r=u==c,!o||!i)return r?0:!o^n?1:-1;if(!r)return u>c^n?1:-1;for(s=(u=o.length)<(c=i.length)?u:c,a=0;s>a;a++)if(o[a]!=i[a])return o[a]>i[a]^n?1:-1;return u==c?0:u>c^n?1:-1}function s(t,e,n){return(t=p(t))>=e&&n>=t}function u(t){return"[object Array]"==Object.prototype.toString.call(t)}function c(t,e,n){for(var r,o,i=[0],a=0,s=t.length;s>a;){for(o=i.length;o--;i[o]*=e);for(i[r=0]+=F.indexOf(t.charAt(a++));rn-1&&(null==i[r+1]&&(i[r+1]=0),i[r+1]+=i[r]/n|0,i[r]%=n)}return i.reverse()}function l(t,e){return(t.length>1?t.charAt(0)+"."+t.slice(1):t)+(0>e?"e":"e+")+e}function f(t,e){var n,r;if(0>e){for(r="0.";++e;r+="0");t=r+t}else if(n=t.length,++e>n){for(r="0",e-=n;--e;r+="0");t+=r}else n>e&&(t=t.slice(0,e)+"."+t.slice(e));return t}function p(t){return t=parseFloat(t),0>t?y(t):v(t)}var m,h,d,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,y=Math.ceil,v=Math.floor,b=" not a boolean or binary digit",w="rounding mode",_="number type has more than 15 significant digits",F="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",x=1e14,I=14,N=9007199254740991,O=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],B=1e7,P=1e9;if(m=r(),"function"==typeof define&&define.amd)define(function(){return m});else if("undefined"!=typeof e&&e.exports){if(e.exports=m,!h)try{h=t("crypto")}catch(T){}}else n.BigNumber=m}(this)},{crypto:27}],web3:[function(t,e,n){var r=t("./lib/web3");r.providers.HttpProvider=t("./lib/web3/httpprovider"),r.providers.QtSyncProvider=t("./lib/web3/qtsync"),r.eth.contract=t("./lib/web3/contract"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/web3":8,"./lib/web3/contract":10,"./lib/web3/httpprovider":18,"./lib/web3/qtsync":23}]},{},["web3"]); \ No newline at end of file diff --git a/libjsqrc/ethereumjs/example/contract.html b/libjsqrc/ethereumjs/example/contract.html index a32098536..3b83d37b1 100644 --- a/libjsqrc/ethereumjs/example/contract.html +++ b/libjsqrc/ethereumjs/example/contract.html @@ -8,14 +8,16 @@ var web3 = require('web3'); web3.setProvider(new web3.providers.HttpProvider("http://localhost:8545")); - // solidity source code - /*var source = "" +*/ - /*"contract test {\n" +*/ - /*" function multiply(uint a) constant returns(uint d) {\n" +*/ - /*" return a * 7;\n" +*/ - /*" }\n" +*/ - /*"}\n";*/ - var source = "605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056"; + // solidity code code + var source = "" + + "contract test {\n" + + " function multiply(uint a) constant returns(uint d) {\n" + + " return a * 7;\n" + + " }\n" + + "}\n"; + + var code = web3.eth.compile.solidity(source).code; + /*var code = "605280600c6000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063c6888fa114602e57005b60376004356041565b8060005260206000f35b6000600782029050604d565b91905056";*/ // contract description, this is autogenerated using solc CLI var desc = [{ @@ -37,15 +39,30 @@ function createExampleContract() { // hide create button document.getElementById('create').style.visibility = 'hidden'; - document.getElementById('source').innerText = source; + document.getElementById('code').innerText = code; // let's assume that coinbase is our account web3.eth.defaultAccount = web3.eth.coinbase; + var watch = web3.eth.filter('latest'); + // create contract - var Contract = web3.eth.contract(desc); - myContract = new Contract({data: source}); - document.getElementById('call').style.visibility = 'visible'; + myContract = web3.eth.contract(desc).new({data: code}); + console.log('address: ' + myContract.address); + document.getElementById('status').innerText = "transaction sent, waiting for confirmation"; + watch.watch(function (err, hash) { + var block = web3.eth.getBlock(hash, true); + var contractMined = block.transactions.reduce(function (mined, th) { + // TODO: compiled code do not have 0x prefix + return mined || (th.from === web3.eth.defaultAccount && th.input.indexOf(code) !== -1); + }, false); + + if (contractMined) { + document.getElementById('status').innerText = 'Mined!'; + document.getElementById('call').style.visibility = 'visible'; + } + }); + } function callExampleContract() { @@ -61,7 +78,8 @@

contract

-
+
+
diff --git a/libjsqrc/ethereumjs/example/event_inc.html b/libjsqrc/ethereumjs/example/event_inc.html index ac12c6447..16eaa046f 100644 --- a/libjsqrc/ethereumjs/example/event_inc.html +++ b/libjsqrc/ethereumjs/example/event_inc.html @@ -6,19 +6,20 @@ var web3 = require('web3'); web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); - /*var source = "" + */ - /*"contract Contract { " +*/ - /*" event Incremented(bool indexed odd, uint x); " +*/ - /*" function Contract() { " +*/ - /*" x = 69; " +*/ - /*" } " +*/ - /*" function inc() { " +*/ - /*" ++x; " +*/ - /*" Incremented(x % 2 == 1, x); " +*/ - /*" } " +*/ - /*" uint x; " +*/ - /*"}";*/ - var source = "5b60456000600050819055505b608c8060196000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063371303c014602e57005b6034603a565b60006000f35b6000600081815054600101919050819055506001600260006000505406147f6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad600060006000505481526020016000a25b56"; + var source = "" + + "contract Contract { " + + " event Incremented(bool indexed odd, uint x); " + + " function Contract() { " + + " x = 70; " + + " } " + + " function inc() { " + + " ++x; " + + " Incremented(x % 2 == 1, x); " + + " } " + + " uint x; " + + "}"; + var code = web3.eth.compile.solidity(source).code; + /*var code = "5b60456000600050819055505b608c8060196000396000f3006000357c010000000000000000000000000000000000000000000000000000000090048063371303c014602e57005b6034603a565b60006000f35b6000600081815054600101919050819055506001600260006000505406147f6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad600060006000505481526020016000a25b56";*/ var desc = [{ "constant" : false, @@ -51,13 +52,40 @@ var createContract = function () { // let's assume that we have a private key to coinbase ;) web3.eth.defaultAccount = web3.eth.coinbase; - var Contract = web3.eth.contract(desc); - contract = new Contract({data: source}); + + var watch = web3.eth.filter('latest'); + + contract = web3.eth.contract(desc).new({data: code}); + + console.log('address: ' + contract.address); + + document.getElementById('create').style.visibility = 'hidden'; + document.getElementById('status').innerText = "transaction sent, waiting for confirmation"; + watch.watch(function (err, hash) { + var block = web3.eth.getBlock(hash, true); + var contractMined = block.transactions.reduce(function (mined, th) { + // TODO: compiled code do not have 0x prefix + return mined || (th.from === web3.eth.defaultAccount && th.input.indexOf(code) !== -1); + }, false); + + if (contractMined) { + document.getElementById('status').innerText = 'Mined!'; + document.getElementById('call').style.visibility = 'visible'; + } + }); + contract.Incremented({odd: true}).watch(update); }; + var counter = 0; var callContract = function () { + counter++; + var all = 70 + counter; + document.getElementById('count').innerText = 'Transaction sent ' + counter + ' times. ' + + 'Expected x value is: ' + (all - (all % 2 ? 0 : 1)) + ' ' + + 'Waiting for the blocks to be mined...'; + contract.inc(); }; @@ -66,12 +94,14 @@ +
- +
- +
+
diff --git a/libjsqrc/ethereumjs/example/node-app.js b/libjsqrc/ethereumjs/example/node-app.js index 72b3986da..909c9d275 100644 --- a/libjsqrc/ethereumjs/example/node-app.js +++ b/libjsqrc/ethereumjs/example/node-app.js @@ -2,11 +2,11 @@ var web3 = require("../index.js"); -web3.setProvider(new web3.providers.HttpProvider('http://localhost:8080')); +web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545')); var coinbase = web3.eth.coinbase; console.log(coinbase); var balance = web3.eth.getBalance(coinbase); -console.log(balance); +console.log(balance.toString(10)); diff --git a/libjsqrc/ethereumjs/index.js b/libjsqrc/ethereumjs/index.js index ae231d7d9..7a1c06902 100644 --- a/libjsqrc/ethereumjs/index.js +++ b/libjsqrc/ethereumjs/index.js @@ -2,7 +2,6 @@ var web3 = require('./lib/web3'); web3.providers.HttpProvider = require('./lib/web3/httpprovider'); web3.providers.QtSyncProvider = require('./lib/web3/qtsync'); web3.eth.contract = require('./lib/web3/contract'); -web3.abi = require('./lib/solidity/abi'); // dont override global variable if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { diff --git a/libjsqrc/ethereumjs/lib/solidity/abi.js b/libjsqrc/ethereumjs/lib/solidity/abi.js deleted file mode 100644 index feb139ed4..000000000 --- a/libjsqrc/ethereumjs/lib/solidity/abi.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - This file is part of ethereum.js. - - ethereum.js is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethereum.js 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with ethereum.js. If not, see . -*/ -/** - * @file abi.js - * @author Marek Kotewicz - * @author Gav Wood - * @date 2014 - */ - -var coder = require('./coder'); -var utils = require('./utils'); - -var formatConstructorParams = function (abi, params) { - var constructor = utils.getConstructor(abi, params.length); - if (!constructor) { - if (params.length > 0) { - console.warn("didn't found matching constructor, using default one"); - } - return ''; - } - - return coder.encodeParams(constructor.inputs.map(function (input) { - return input.type; - }), params); -}; - -module.exports = { - formatConstructorParams: formatConstructorParams -}; - diff --git a/libjsqrc/ethereumjs/lib/solidity/utils.js b/libjsqrc/ethereumjs/lib/solidity/utils.js deleted file mode 100644 index 23566f74a..000000000 --- a/libjsqrc/ethereumjs/lib/solidity/utils.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - This file is part of ethereum.js. - - ethereum.js is free software: you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - ethereum.js 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with ethereum.js. If not, see . -*/ -/** - * @file utils.js - * @author Marek Kotewicz - * @date 2015 - */ - -/** - * Returns the contstructor with matching number of arguments - * - * @method getConstructor - * @param {Array} abi - * @param {Number} numberOfArgs - * @returns {Object} constructor function abi - */ -var getConstructor = function (abi, numberOfArgs) { - return abi.filter(function (f) { - return f.type === 'constructor' && f.inputs.length === numberOfArgs; - })[0]; -}; - -//var getSupremeType = function (type) { - //return type.substr(0, type.indexOf('[')) + ']'; -//}; - - -module.exports = { - getConstructor: getConstructor -}; - diff --git a/libjsqrc/ethereumjs/lib/utils/utils.js b/libjsqrc/ethereumjs/lib/utils/utils.js index baaaa7d48..91964c333 100644 --- a/libjsqrc/ethereumjs/lib/utils/utils.js +++ b/libjsqrc/ethereumjs/lib/utils/utils.js @@ -363,6 +363,7 @@ var toAddress = function (address) { return '0x' + padLeft(toHex(address).substr(2), 40); }; + /** * Returns true if object is BigNumber, otherwise false * diff --git a/libjsqrc/ethereumjs/lib/version.json b/libjsqrc/ethereumjs/lib/version.json index e5c97ebab..70753fc9d 100644 --- a/libjsqrc/ethereumjs/lib/version.json +++ b/libjsqrc/ethereumjs/lib/version.json @@ -1,3 +1,3 @@ { - "version": "0.3.6" + "version": "0.4.2" } diff --git a/libjsqrc/ethereumjs/lib/web3.js b/libjsqrc/ethereumjs/lib/web3.js index 47db94278..98460fea4 100644 --- a/libjsqrc/ethereumjs/lib/web3.js +++ b/libjsqrc/ethereumjs/lib/web3.js @@ -37,6 +37,7 @@ var RequestManager = require('./web3/requestmanager'); var c = require('./utils/config'); var Method = require('./web3/method'); var Property = require('./web3/property'); +var Batch = require('./web3/batch'); var web3Methods = [ new Method({ @@ -129,6 +130,9 @@ web3.toBigNumber = utils.toBigNumber; web3.toWei = utils.toWei; web3.fromWei = utils.fromWei; web3.isAddress = utils.isAddress; +web3.createBatch = function () { + return new Batch(); +}; // ADD defaultblock Object.defineProperty(web3.eth, 'defaultBlock', { diff --git a/libjsqrc/ethereumjs/lib/web3/batch.js b/libjsqrc/ethereumjs/lib/web3/batch.js new file mode 100644 index 000000000..ca32bf725 --- /dev/null +++ b/libjsqrc/ethereumjs/lib/web3/batch.js @@ -0,0 +1,61 @@ +/* + This file is part of ethereum.js. + + ethereum.js is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + ethereum.js 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with ethereum.js. If not, see . +*/ +/** + * @file batch.js + * @author Marek Kotewicz + * @date 2015 + */ + +var RequestManager = require('./requestmanager'); + +var Batch = function () { + this.requests = []; +}; + +/** + * Should be called to add create new request to batch request + * + * @method add + * @param {Object} jsonrpc requet object + */ +Batch.prototype.add = function (request) { + this.requests.push(request); +}; + +/** + * Should be called to execute batch request + * + * @method execute + */ +Batch.prototype.execute = function () { + var requests = this.requests; + RequestManager.getInstance().sendBatch(requests, function (err, results) { + results = results || []; + requests.map(function (request, index) { + return results[index] || {}; + }).map(function (result, index) { + return requests[index].format ? requests[index].format(result.result) : result.result; + }).forEach(function (result, index) { + if (requests[index].callback) { + requests[index].callback(err, result); + } + }); + }); +}; + +module.exports = Batch; + diff --git a/libjsqrc/ethereumjs/lib/web3/contract.js b/libjsqrc/ethereumjs/lib/web3/contract.js index 47ffae8f4..9666f9eaa 100644 --- a/libjsqrc/ethereumjs/lib/web3/contract.js +++ b/libjsqrc/ethereumjs/lib/web3/contract.js @@ -21,13 +21,39 @@ */ var web3 = require('../web3'); -var solAbi = require('../solidity/abi'); var utils = require('../utils/utils'); +var coder = require('../solidity/coder'); var SolidityEvent = require('./event'); var SolidityFunction = require('./function'); -var addFunctionsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to encode constructor params + * + * @method encodeConstructorParams + * @param {Array} abi + * @param {Array} constructor params + */ +var encodeConstructorParams = function (abi, params) { + return abi.filter(function (json) { + return json.type === 'constructor' && json.inputs.length === params.length; + }).map(function (json) { + return json.inputs.map(function (input) { + return input.type; + }); + }).map(function (types) { + return coder.encodeParams(types, params); + })[0] || ''; +}; + +/** + * Should be called to add functions to contract object + * + * @method addFunctionsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addFunctionsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'function'; }).map(function (json) { return new SolidityFunction(json, contract.address); @@ -36,8 +62,15 @@ var addFunctionsToContract = function (contract, desc) { }); }; -var addEventsToContract = function (contract, desc) { - desc.filter(function (json) { +/** + * Should be called to add events to contract object + * + * @method addEventsToContract + * @param {Contract} contract + * @param {Array} abi + */ +var addEventsToContract = function (contract, abi) { + abi.filter(function (json) { return json.type === 'event'; }).map(function (json) { return new SolidityEvent(json, contract.address); @@ -47,59 +80,100 @@ var addEventsToContract = function (contract, desc) { }; /** - * This method should be called when we want to call / transact some solidity method from javascript - * it returns an object which has same methods available as solidity contract description - * usage example: - * - * var abi = [{ - * name: 'myMethod', - * inputs: [{ name: 'a', type: 'string' }], - * outputs: [{name: 'd', type: 'string' }] - * }]; // contract abi - * - * var MyContract = web3.eth.contract(abi); // creation of contract prototype - * - * var contractInstance = new MyContract('0x0123123121'); + * Should be called to create new ContractFactory * - * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default) - * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit) - * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction - * - * @param abi - abi json description of the contract, which is being created - * @returns contract object + * @method contract + * @param {Array} abi + * @returns {ContractFactory} new contract factory */ var contract = function (abi) { + return new ContractFactory(abi); +}; - // return prototype - return Contract.bind(null, abi); +/** + * Should be called to create new ContractFactory instance + * + * @method ContractFactory + * @param {Array} abi + */ +var ContractFactory = function (abi) { + this.abi = abi; }; -var Contract = function (abi, options) { - - this.address = ''; - if (utils.isAddress(options)) { - this.address = options; - } else { // is an object! - // TODO, parse the rest of the args - options = options || {}; - var args = Array.prototype.slice.call(arguments, 2); - var bytes = solAbi.formatConstructorParams(abi, args); - options.data += bytes; - this.address = web3.eth.sendTransaction(options); +/** + * Should be called to create new contract on a blockchain + * + * @method new + * @param {Any} contract constructor param1 (optional) + * @param {Any} contract constructor param2 (optional) + * @param {Object} contract transaction object (required) + * @param {Function} callback + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.new = function () { + // parse arguments + var options = {}; // required! + var callback; + + var args = Array.prototype.slice.call(arguments); + if (utils.isFunction(args[args.length - 1])) { + callback = args.pop(); } - addFunctionsToContract(this, abi); - addEventsToContract(this, abi); + var last = args[args.length - 1]; + if (utils.isObject(last) && !utils.isArray(last)) { + options = args.pop(); + } + + // throw an error if there are no options + + var bytes = encodeConstructorParams(this.abi, args); + options.data += bytes; + + if (!callback) { + var address = web3.eth.sendTransaction(options); + return this.at(address); + } + + var self = this; + web3.eth.sendTransaction(options, function (err, address) { + if (err) { + callback(err); + } + self.at(address, callback); + }); }; -Contract.prototype.call = function () { - console.error('contract.call is deprecated'); - return this; +/** + * Should be called to get access to existing contract on a blockchain + * + * @method at + * @param {Address} contract address (required) + * @param {Function} callback {optional) + * @returns {Contract} returns contract if no callback was passed, + * otherwise calls callback function (err, contract) + */ +ContractFactory.prototype.at = function (address, callback) { + // TODO: address is required + + if (callback) { + callback(null, new Contract(this.abi, address)); + } + return new Contract(this.abi, address); }; -Contract.prototype.sendTransaction = function () { - console.error('contract.sendTransact is deprecated'); - return this; +/** + * Should be called to create new contract instance + * + * @method Contract + * @param {Array} abi + * @param {Address} contract address + */ +var Contract = function (abi, address) { + this.address = address; + addFunctionsToContract(this, abi); + addEventsToContract(this, abi); }; module.exports = contract; diff --git a/libjsqrc/ethereumjs/lib/web3/eth.js b/libjsqrc/ethereumjs/lib/web3/eth.js index b955a45ac..87a2b290c 100644 --- a/libjsqrc/ethereumjs/lib/web3/eth.js +++ b/libjsqrc/ethereumjs/lib/web3/eth.js @@ -174,6 +174,14 @@ var call = new Method({ inputFormatter: [formatters.inputTransactionFormatter, formatters.inputDefaultBlockNumberFormatter] }); +var estimateGas = new Method({ + name: 'estimateGas', + call: 'eth_estimateGas', + params: 1, + inputFormatter: [formatters.inputTransactionFormatter], + outputFormatter: utils.toDecimal +}); + var compileSolidity = new Method({ name: 'compile.solidity', call: 'eth_compileSolidity', @@ -192,6 +200,18 @@ var compileSerpent = new Method({ params: 1 }); +var submitWork = new Method({ + name: 'submitWork', + call: 'eth_submitWork', + params: 3 +}); + +var getWork = new Method({ + name: 'getWork', + call: 'eth_getWork', + params: 0 +}); + var methods = [ getBalance, getStorageAt, @@ -205,10 +225,13 @@ var methods = [ getTransactionFromBlock, getTransactionCount, call, + estimateGas, sendTransaction, compileSolidity, compileLLL, compileSerpent, + submitWork, + getWork ]; /// @returns an array of objects describing web3.eth api properties diff --git a/libjsqrc/ethereumjs/lib/web3/function.js b/libjsqrc/ethereumjs/lib/web3/function.js index 2bbb68423..e9ad5d03a 100644 --- a/libjsqrc/ethereumjs/lib/web3/function.js +++ b/libjsqrc/ethereumjs/lib/web3/function.js @@ -14,7 +14,7 @@ You should have received a copy of the GNU Lesser General Public License along with ethereum.js. If not, see . */ -/** +/** * @file function.js * @author Marek Kotewicz * @date 2015 @@ -39,18 +39,23 @@ var SolidityFunction = function (json, address) { this._address = address; }; +SolidityFunction.prototype.extractCallback = function (args) { + if (utils.isFunction(args[args.length - 1])) { + return args.pop(); // modify the args array! + } +}; + /** * Should be used to create payload from arguments * * @method toPayload - * @param {...} solidity function params + * @param {Array} solidity function params * @param {Object} optional payload options */ -SolidityFunction.prototype.toPayload = function () { - var args = Array.prototype.slice.call(arguments); +SolidityFunction.prototype.toPayload = function (args) { var options = {}; if (args.length > this._inputTypes.length && utils.isObject(args[args.length -1])) { - options = args.pop(); + options = args[args.length - 1]; } options.to = this._address; options.data = '0x' + this.signature() + coder.encodeParams(this._inputTypes, args); @@ -67,19 +72,41 @@ SolidityFunction.prototype.signature = function () { return web3.sha3(web3.fromAscii(this._name)).slice(2, 10); }; + +SolidityFunction.prototype.unpackOutput = function (output) { + if (output === null) { + return; + } + + output = output.length >= 2 ? output.slice(2) : output; + var result = coder.decodeParams(this._outputTypes, output); + return result.length === 1 ? result[0] : result; +}; + /** - * Should be used to call function - * + * Calls a contract function. + * * @method call - * @param {Object} options + * @param {...Object} Contract function arguments + * @param {function} If the last argument is a function, the contract function + * call will be asynchronous, and the callback will be passed the + * error and result. * @return {String} output bytes */ SolidityFunction.prototype.call = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - var output = web3.eth.call(payload); - output = output.length >= 2 ? output.slice(2) : output; - var result = coder.decodeParams(this._outputTypes, output); - return result.length === 1 ? result[0] : result; + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + var output = web3.eth.call(payload); + return this.unpackOutput(output); + } + + var self = this; + web3.eth.call(payload, function (error, output) { + callback(error, self.unpackOutput(output)); + }); }; /** @@ -89,8 +116,16 @@ SolidityFunction.prototype.call = function () { * @param {Object} options */ SolidityFunction.prototype.sendTransaction = function () { - var payload = this.toPayload.apply(this, Array.prototype.slice.call(arguments)); - web3.eth.sendTransaction(payload); + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + + if (!callback) { + web3.eth.sendTransaction(payload); + return; + } + + web3.eth.sendTransaction(payload, callback); }; /** @@ -105,7 +140,7 @@ SolidityFunction.prototype.displayName = function () { /** * Should be used to get function type name - * + * * @method typeName * @return {String} type name of the function */ @@ -113,6 +148,25 @@ SolidityFunction.prototype.typeName = function () { return utils.extractTypeName(this._name); }; +/** + * Should be called to get rpc requests from solidity function + * + * @method request + * @returns {Object} + */ +SolidityFunction.prototype.request = function () { + var args = Array.prototype.slice.call(arguments); + var callback = this.extractCallback(args); + var payload = this.toPayload(args); + var format = this.unpackOutput.bind(this); + + return { + callback: callback, + payload: payload, + format: format + }; +}; + /** * Should be called to execute function * @@ -120,7 +174,7 @@ SolidityFunction.prototype.typeName = function () { */ SolidityFunction.prototype.execute = function () { var transaction = !this._constant; - + // send transaction if (transaction) { return this.sendTransaction.apply(this, Array.prototype.slice.call(arguments)); @@ -138,6 +192,7 @@ SolidityFunction.prototype.execute = function () { */ SolidityFunction.prototype.attachToContract = function (contract) { var execute = this.execute.bind(this); + execute.request = this.request.bind(this); execute.call = this.call.bind(this); execute.sendTransaction = this.sendTransaction.bind(this); var displayName = this.displayName(); diff --git a/libjsqrc/ethereumjs/lib/web3/method.js b/libjsqrc/ethereumjs/lib/web3/method.js index 449388dd3..8f10b2dfe 100644 --- a/libjsqrc/ethereumjs/lib/web3/method.js +++ b/libjsqrc/ethereumjs/lib/web3/method.js @@ -54,7 +54,6 @@ Method.prototype.extractCallback = function (args) { if (utils.isFunction(args[args.length - 1])) { return args.pop(); // modify the args array! } - return null; }; /** @@ -107,6 +106,7 @@ Method.prototype.formatOutput = function (result) { */ Method.prototype.attachToObject = function (obj) { var func = this.send.bind(this); + func.request = this.request.bind(this); func.call = this.call; // that's ugly. filter.js uses it var name = this.name.split('.'); if (name.length > 1) { @@ -137,6 +137,19 @@ Method.prototype.toPayload = function (args) { }; }; +/** + * Should be called to create pure JSONRPC request which can be used in batch request + * + * @method request + * @param {...} params + * @return {Object} jsonrpc request + */ +Method.prototype.request = function () { + var payload = this.toPayload(Array.prototype.slice.call(arguments)); + payload.format = this.formatOutput.bind(this); + return payload; +}; + /** * Should send request to the API * @@ -149,7 +162,7 @@ Method.prototype.send = function () { if (payload.callback) { var self = this; return RequestManager.getInstance().sendAsync(payload, function (err, result) { - payload.callback(null, self.formatOutput(result)); + payload.callback(err, self.formatOutput(result)); }); } return this.formatOutput(RequestManager.getInstance().send(payload)); diff --git a/libjsqrc/ethereumjs/lib/web3/property.js b/libjsqrc/ethereumjs/lib/web3/property.js index bfcbb2d25..a2e7282e9 100644 --- a/libjsqrc/ethereumjs/lib/web3/property.js +++ b/libjsqrc/ethereumjs/lib/web3/property.js @@ -63,16 +63,23 @@ Property.prototype.formatOutput = function (result) { Property.prototype.attachToObject = function (obj) { var proto = { get: this.get.bind(this), - set: this.set.bind(this) }; - var name = this.name.split('.'); - if (name.length > 1) { - obj[name[0]] = obj[name[0]] || {}; - Object.defineProperty(obj[name[0]], name[1], proto); - } else { - Object.defineProperty(obj, name[0], proto); + var names = this.name.split('.'); + var name = names[0]; + if (names.length > 1) { + obj[names[0]] = obj[names[0]] || {}; + obj = obj[names[0]]; + name = names[1]; } + + Object.defineProperty(obj, name, proto); + + var toAsyncName = function (prefix, name) { + return prefix + name.charAt(0).toUpperCase() + name.slice(1); + }; + + obj[toAsyncName('get', name)] = this.getAsync.bind(this); }; /** @@ -88,15 +95,20 @@ Property.prototype.get = function () { }; /** - * Should be used to set value of the property + * Should be used to asynchrounously get value of property * - * @method set - * @param {Object} new value of the property + * @method getAsync + * @param {Function} */ -Property.prototype.set = function (value) { - return RequestManager.getInstance().send({ - method: this.setter, - params: [this.formatInput(value)] +Property.prototype.getAsync = function (callback) { + var self = this; + RequestManager.getInstance().sendAsync({ + method: this.getter + }, function (err, result) { + if (err) { + return callback(err); + } + callback(err, self.formatOutput(result)); }); }; diff --git a/libjsqrc/ethereumjs/lib/web3/requestmanager.js b/libjsqrc/ethereumjs/lib/web3/requestmanager.js index 87eeb8a29..73a18881a 100644 --- a/libjsqrc/ethereumjs/lib/web3/requestmanager.js +++ b/libjsqrc/ethereumjs/lib/web3/requestmanager.js @@ -105,6 +105,33 @@ RequestManager.prototype.sendAsync = function (data, callback) { }); }; +/** + * Should be called to asynchronously send batch request + * + * @method sendBatch + * @param {Array} batch data + * @param {Function} callback + */ +RequestManager.prototype.sendBatch = function (data, callback) { + if (!this.provider) { + return callback(errors.InvalidProvider()); + } + + var payload = Jsonrpc.getInstance().toBatchPayload(data); + + this.provider.sendAsync(payload, function (err, results) { + if (err) { + return callback(err); + } + + if (!utils.isArray(results)) { + return callback(errors.InvalidResponse(results)); + } + + callback(err, results); + }); +}; + /** * Should be used to set provider of request manager * diff --git a/libjsqrc/ethereumjs/lib/web3/watches.js b/libjsqrc/ethereumjs/lib/web3/watches.js index 0b2c1bd3b..8bcfe207b 100644 --- a/libjsqrc/ethereumjs/lib/web3/watches.js +++ b/libjsqrc/ethereumjs/lib/web3/watches.js @@ -25,7 +25,20 @@ var Method = require('./method'); /// @returns an array of objects describing web3.eth.filter api methods var eth = function () { var newFilterCall = function (args) { - return typeof args[0] === 'string' ? 'eth_newBlockFilter' : 'eth_newFilter'; + var type = args[0]; + + switch(type) { + case 'latest': + args.pop(); + this.params = 0; + return 'eth_newBlockFilter'; + case 'pending': + args.pop(); + this.params = 0; + return 'eth_newPendingTransactionFilter'; + default: + return 'eth_newFilter'; + } }; var newFilter = new Method({ diff --git a/libjsqrc/ethereumjs/package.js b/libjsqrc/ethereumjs/package.js index bfb8d0556..953edb4fb 100644 --- a/libjsqrc/ethereumjs/package.js +++ b/libjsqrc/ethereumjs/package.js @@ -1,7 +1,7 @@ /* jshint ignore:start */ Package.describe({ name: 'ethereum:web3', - version: '0.3.6', + version: '0.4.2', 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/libjsqrc/ethereumjs/package.json b/libjsqrc/ethereumjs/package.json index 4c7c81445..59d4f6211 100644 --- a/libjsqrc/ethereumjs/package.json +++ b/libjsqrc/ethereumjs/package.json @@ -1,7 +1,7 @@ { "name": "web3", "namespace": "ethereum", - "version": "0.3.6", + "version": "0.4.2", "description": "Ethereum JavaScript API, middleware to talk to a ethereum node over RPC", "main": "./index.js", "directories": { diff --git a/libjsqrc/ethereumjs/test/abi.formatConstructorParams.js b/libjsqrc/ethereumjs/test/abi.formatConstructorParams.js deleted file mode 100644 index 9113f02c6..000000000 --- a/libjsqrc/ethereumjs/test/abi.formatConstructorParams.js +++ /dev/null @@ -1,106 +0,0 @@ -var chai = require('chai'); -var assert = require('assert'); -var abi = require('../lib/solidity/abi'); - -describe('lib/solidity/abi', function () { - describe('formatConstructorParams', function () { - it('should format uint256 properly', function () { - // given - var description = [{ - "name": "test", - "type": "constructor", - "inputs": [{ - "name": "a", - "type": "uint256" - } - ] - }]; - - // when - var bytes = abi.formatConstructorParams(description, [2]); - - // then - assert.equal(bytes, '0000000000000000000000000000000000000000000000000000000000000002'); - }); - - it('should not find matching constructor', function () { - // given - var description = [{ - "name": "test", - "type": "constructor", - "inputs": [{ - "name": "a", - "type": "uint256" - } - ] - }]; - - // when - var bytes = abi.formatConstructorParams(description, []); - - // then - assert.equal(bytes, ''); - }); - - it('should not find matching constructor2', function () { - // given - var description = [{ - "name": "test", - "type": "constructor", - "inputs": [{ - "name": "a", - "type": "uint256" - } - ] - }]; - - // when - var bytes = abi.formatConstructorParams(description, [1,2]); - - // then - assert.equal(bytes, ''); - }); - - it('should not find matching constructor3', function () { - // given - var description = [{ - "name": "test", - "type": "function", - "inputs": [{ - "name": "a", - "type": "uint256" - } - ] - }]; - - // when - var bytes = abi.formatConstructorParams(description, [2]); - - // then - assert.equal(bytes, ''); - }); - - it('should find matching constructor with multiple args', function () { - // given - var description = [{ - "name": "test", - "type": "constructor", - "inputs": [{ - "name": "a", - "type": "uint256" - }, { - "name": "b", - "type": "uint256" - }] - }]; - - // when - var bytes = abi.formatConstructorParams(description, ['1', '5']); - - // then - assert.equal(bytes, '00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000005'); - }); - }); -}); - - diff --git a/libjsqrc/ethereumjs/test/async.js b/libjsqrc/ethereumjs/test/async.js new file mode 100644 index 000000000..77497603c --- /dev/null +++ b/libjsqrc/ethereumjs/test/async.js @@ -0,0 +1,69 @@ +var chai = require('chai'); +var assert = chai.assert; +var web3 = require('../index'); +var FakeHttpProvider = require('./helpers/FakeHttpProvider'); + +// use sendTransaction as dummy +var method = 'sendTransaction'; + +var tests = [{ + result: '0xb', + formattedResult: '0xb', + call: 'eth_'+ method +}]; + +describe('async', function () { + tests.forEach(function (test, index) { + it('test: ' + index, function (done) { + + // given + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + provider.injectResult(test.result); + provider.injectValidation(function (payload) { + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, test.call); + assert.deepEqual(payload.params, [{}]); + }); + + // when + web3.eth[method]({}, function(error, result){ + + // then + assert.isNull(error); + assert.strictEqual(test.formattedResult, result); + + done(); + }); + + }); + + it('error test: ' + index, function (done) { + + // given + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + provider.injectError({ + message: test.result, + code: -32603 + }); + provider.injectValidation(function (payload) { + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, test.call); + assert.deepEqual(payload.params, [{}]); + }); + + // when + web3.eth[method]({}, function(error, result){ + + // then + assert.isUndefined(result); + assert.strictEqual(test.formattedResult, error.message); + + done(); + }); + + }); + }); +}); + diff --git a/libjsqrc/ethereumjs/test/batch.js b/libjsqrc/ethereumjs/test/batch.js new file mode 100644 index 000000000..69ae8fd58 --- /dev/null +++ b/libjsqrc/ethereumjs/test/batch.js @@ -0,0 +1,86 @@ +var chai = require('chai'); +var assert = chai.assert; +var web3 = require('../index'); +var FakeHttpProvider = require('./helpers/FakeHttpProvider'); +var bn = require('bignumber.js'); + +describe('lib/web3/batch', function () { + describe('execute', function () { + it('should execute batch request', function (done) { + + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + web3.reset(); + + var result = '0x126'; + var result2 = '0x127'; + provider.injectBatchResults([result, result2]); + + var counter = 0; + var callback = function (err, r) { + counter++; + assert.deepEqual(new bn(result), r); + }; + + var callback2 = function (err, r) { + assert.equal(counter, 1); + assert.deepEqual(new bn(result2), r); + done(); + }; + + var batch = web3.createBatch(); + batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); + batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000005', 'latest', callback2)); + batch.execute(); + }); + + it('should execute batch request', function (done) { + + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + web3.reset(); + + var abi = [{ + "name": "balance(address)", + "type": "function", + "inputs": [{ + "name": "who", + "type": "address" + }], + "constant": true, + "outputs": [{ + "name": "value", + "type": "uint256" + }] + }]; + + + var address = '0x0000000000000000000000000000000000000000'; + var result = '0x126'; + var result2 = '0x0000000000000000000000000000000000000000000000000000000000000123'; + var signature = '0x001122334455'; + + // TODO: fix this, maybe in browser sha3? + provider.injectResult(signature); + + var counter = 0; + var callback = function (err, r) { + counter++; + assert.deepEqual(new bn(result), r); + }; + + var callback2 = function (err, r) { + assert.equal(counter, 1); + assert.deepEqual(new bn(result2), r); + done(); + }; + + var batch = web3.createBatch(); + batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); + batch.add(web3.eth.contract(abi).at(address).balance.request(address, callback2)); + provider.injectBatchResults([result, result2]); + batch.execute(); + }); + }); +}); + diff --git a/libjsqrc/ethereumjs/test/contract.js b/libjsqrc/ethereumjs/test/contract.js index 0dcaa1003..a46a8cab3 100644 --- a/libjsqrc/ethereumjs/test/contract.js +++ b/libjsqrc/ethereumjs/test/contract.js @@ -116,8 +116,7 @@ describe('web3.eth.contract', function () { } }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); + var contract = web3.eth.contract(desc).at(address); var res = 0; contract.Changed({from: address}).watch(function(err, result) { @@ -155,8 +154,7 @@ describe('web3.eth.contract', function () { } }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); + var contract = web3.eth.contract(desc).at(address); contract.balance(address); }); @@ -186,8 +184,7 @@ describe('web3.eth.contract', function () { } }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); + var contract = web3.eth.contract(desc).at(address); contract.send(address, 17); }); @@ -218,8 +215,7 @@ describe('web3.eth.contract', function () { } }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); + var contract = web3.eth.contract(desc).at(address); contract.balance(address, {from: address, gas: 50000}); @@ -251,8 +247,7 @@ describe('web3.eth.contract', function () { } }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); + var contract = web3.eth.contract(desc).at(address); contract.balance.call(address, {from: address, gas: 50000}); @@ -287,8 +282,7 @@ describe('web3.eth.contract', function () { } }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); + var contract = web3.eth.contract(desc).at(address); contract.send(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000}); }); @@ -322,12 +316,48 @@ describe('web3.eth.contract', function () { } }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); + var contract = web3.eth.contract(desc).at(address); contract.send.sendTransaction(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000}); }); + it('should explicitly sendTransaction with optional params and call callback without error', function (done) { + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + web3.reset(); + var sha3 = '0x5131231231231231231231'; + var address = '0x1234567890123456789012345678901234567890'; + provider.injectResult(sha3); + var step = 0; + provider.injectValidation(function (payload) { + if (step === 0) { + step = 1; + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, 'web3_sha3'); + assert.equal(payload.params[0], web3.fromAscii('send(address,uint256)')); + } else if (step === 1) { + assert.equal(payload.method, 'eth_sendTransaction'); + assert.deepEqual(payload.params, [{ + data: sha3.slice(0, 10) + + '0000000000000000000000001234567890123456789012345678901234567890' + + '0000000000000000000000000000000000000000000000000000000000000011' , + to: address, + from: address, + gas: '0xc350', + gasPrice: '0xbb8', + value: '0x2710' + }]); + } + }); + + var contract = web3.eth.contract(desc).at(address); + + contract.send.sendTransaction(address, 17, {from: address, gas: 50000, gasPrice: 3000, value: 10000}, function (err) { + assert.equal(err, null); + done(); + }); + }); + it('should call testArr method and properly parse result', function () { var provider = new FakeHttpProvider2(); web3.setProvider(provider); @@ -356,12 +386,48 @@ describe('web3.eth.contract', function () { step++; }); - var Contract = web3.eth.contract(desc); - var contract = new Contract(address); - + var contract = web3.eth.contract(desc).at(address); var result = contract.testArr([3]); assert.deepEqual(new BigNumber(5), result); }); + + it('should call testArr method, properly parse result and return the result async', function (done) { + var provider = new FakeHttpProvider2(); + web3.setProvider(provider); + web3.reset(); + var sha3 = '0x5131231231231231231231'; + var address = '0x1234567890123456789012345678901234567890'; + provider.injectResultList([{ + result: sha3 + }, { + result: '0x0000000000000000000000000000000000000000000000000000000000000005' + }]); + var step = 0; + provider.injectValidation(function (payload) { + if (step === 1) { // getting sha3 is first + assert.equal(payload.method, 'eth_call'); + assert.deepEqual(payload.params, [{ + data: sha3.slice(0, 10) + + '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000003', + to: address + }, + 'latest' + ]); + } + step++; + }); + + var contract = web3.eth.contract(desc).at(address); + + contract.testArr([3], function (err, result) { + assert.deepEqual(new BigNumber(5), result); + done(); + }); + + }); }); }); + diff --git a/libjsqrc/ethereumjs/test/method.request.js b/libjsqrc/ethereumjs/test/method.request.js new file mode 100644 index 000000000..00bf52cb7 --- /dev/null +++ b/libjsqrc/ethereumjs/test/method.request.js @@ -0,0 +1,23 @@ +var chai = require('chai'); +var assert = chai.assert; +var web3 = require('../index'); + +describe('lib/web3/method', function () { + describe('request', function () { + it('should create proper request', function () { + + var callback = function (err, result) {}; + var expected = { + method: 'eth_getBalance', + callback: callback, + params: ['0x0000000000000000000000000000000000000000', 'latest'], + }; + + var request = web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback); + + expected.format = request.format; + assert.deepEqual(request, expected); + }); + }); +}); + diff --git a/libjsqrc/ethereumjs/test/node/app.js b/libjsqrc/ethereumjs/test/node/app.js index c3fd489a0..9ec310f44 100644 --- a/libjsqrc/ethereumjs/test/node/app.js +++ b/libjsqrc/ethereumjs/test/node/app.js @@ -1,4 +1,4 @@ -var web3 = require('ethereum.js'); +var web3 = require('web3'); console.log(web3.version.api); diff --git a/libjsqrc/ethereumjs/test/node/package.json b/libjsqrc/ethereumjs/test/node/package.json index 4c56b2c10..310ad2e04 100644 --- a/libjsqrc/ethereumjs/test/node/package.json +++ b/libjsqrc/ethereumjs/test/node/package.json @@ -9,6 +9,6 @@ "author": "", "license": "ISC", "dependencies": { - "ethereum.js": "ethereum/ethereum.js#master" + "web3": "ethereum/web3.js#master" } } diff --git a/libjsqrc/ethereumjs/test/polling.js b/libjsqrc/ethereumjs/test/polling.js index ea7dd9829..8bd2b041c 100644 --- a/libjsqrc/ethereumjs/test/polling.js +++ b/libjsqrc/ethereumjs/test/polling.js @@ -6,15 +6,26 @@ var utils = require('../lib/utils/utils'); var tests = [{ protocol: 'eth', - args: ['pending'], + args: ['latest'], firstResult: 1, firstPayload: { method: "eth_newBlockFilter", - params: [ - "pending" - ] + params: [] + }, + secondResult: ['0x1234'], + secondPayload: { + method: "eth_getFilterChanges" + } +}, +{ + protocol: 'eth', + args: ['pending'], + firstResult: 1, + firstPayload: { + method: "eth_newPendingTransactionFilter", + params: [] }, - secondResult: [null], + secondResult: ['0x1234'], secondPayload: { method: "eth_getFilterChanges" } diff --git a/libjsqrc/ethereumjs/test/web3.eth.blockNumber.js b/libjsqrc/ethereumjs/test/web3.eth.blockNumber.js index dfd73f57e..dbe7f1c44 100644 --- a/libjsqrc/ethereumjs/test/web3.eth.blockNumber.js +++ b/libjsqrc/ethereumjs/test/web3.eth.blockNumber.js @@ -32,6 +32,26 @@ describe('web3.eth', function () { // then assert.strictEqual(test.formattedResult, result); }); + + it('async get property test: ' + index, function (done) { + + // given + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + provider.injectResult(test.result); + provider.injectValidation(function (payload) { + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, test.call); + assert.deepEqual(payload.params, []); + }); + + // when + web3.eth.getBlockNumber(function (err, result) { + assert.strictEqual(test.formattedResult, result); + done(); + }); + + }); }); }); }); diff --git a/libjsqrc/ethereumjs/test/web3.eth.call.js b/libjsqrc/ethereumjs/test/web3.eth.call.js new file mode 100644 index 000000000..d79bd64d4 --- /dev/null +++ b/libjsqrc/ethereumjs/test/web3.eth.call.js @@ -0,0 +1,41 @@ +var web3 = require('../index'); +var testMethod = require('./helpers/test.method.js'); + +var method = 'call'; + +var tests = [{ + args: [{ + to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', + data: '0x23455654', + gas: 11, + gasPrice: 11 + }], + formattedArgs: [{ + to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', + data: '0x23455654', + gas: '0xb', + gasPrice: '0xb' + }, 'latest'], + result: '0x31981', + formattedResult: '0x31981', + call: 'eth_'+ method +},{ + args: [{ + to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', + data: '0x23455654', + gas: 11, + gasPrice: 11 + }, 11], + formattedArgs: [{ + to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', + data: '0x23455654', + gas: '0xb', + gasPrice: '0xb' + }, '0xb'], + result: '0x31981', + formattedResult: '0x31981', + call: 'eth_'+ method +}]; + +testMethod.runTests('eth', method, tests); + diff --git a/libjsqrc/ethereumjs/test/web3.eth.contract.js b/libjsqrc/ethereumjs/test/web3.eth.contract.js index 651810b69..b089f0243 100644 --- a/libjsqrc/ethereumjs/test/web3.eth.contract.js +++ b/libjsqrc/ethereumjs/test/web3.eth.contract.js @@ -25,8 +25,7 @@ describe('web3.eth.contract', function() { var address = '0x1234567890123456789012345678901234567890'; // when - var Con = contract(description); - var myCon = new Con(address); + var myCon = contract(description).at(address); // then assert.equal('function', typeof myCon.test); @@ -54,8 +53,7 @@ describe('web3.eth.contract', function() { var address = '0x1234567890123456789012345678901234567890'; // when - var Con = contract(description); - var myCon = new Con(address); + var myCon = contract(description).at(address); // then assert.equal('function', typeof myCon.test); @@ -97,8 +95,7 @@ describe('web3.eth.contract', function() { var address = '0x1234567890123456789012345678901234567890'; // when - var Con = contract(description); - var myCon = new Con(address); + var myCon = contract(description).at(address); // then assert.equal('function', typeof myCon.test); @@ -142,8 +139,7 @@ describe('web3.eth.contract', function() { var address = '0x1234567890123456789012345678901234567890'; // when - var Con = contract(description); - var myCon = new Con(address); + var myCon = contract(description).at(address); // then assert.equal('function', typeof myCon.test); @@ -171,8 +167,7 @@ describe('web3.eth.contract', function() { var address = '0x1234567890123456789012345678901234567890'; // when - var Con = contract(description); - var myCon = new Con(address); + var myCon = contract(description).at(address); // then assert.equal('undefined', typeof myCon.test); @@ -200,8 +195,7 @@ describe('web3.eth.contract', function() { var address = '0x1234567890123456789012345678901234567890'; // when - var Con = contract(description); - var myCon = new Con(address); + var myCon = contract(description).at(address); // then assert.equal('function', typeof myCon.test); @@ -233,8 +227,7 @@ describe('web3.eth.contract', function() { done(); }); - var Con = contract(description); - var myCon = new Con({data: code}, 2); + var myCon = contract(description).new(2, {data: code}); }); }); diff --git a/libjsqrc/ethereumjs/test/web3.eth.estimateGas.js b/libjsqrc/ethereumjs/test/web3.eth.estimateGas.js new file mode 100644 index 000000000..efa6bf310 --- /dev/null +++ b/libjsqrc/ethereumjs/test/web3.eth.estimateGas.js @@ -0,0 +1,25 @@ +var web3 = require('../index'); +var testMethod = require('./helpers/test.method.js'); + +var method = 'estimateGas'; + +var tests = [{ + args: [{ + to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', + data: '0x23455654', + gas: 11, + gasPrice: 11 + }], + formattedArgs: [{ + to: '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b', + data: '0x23455654', + gas: '0xb', + gasPrice: '0xb' + }], + result: '0x31981', + formattedResult: 203137, + call: 'eth_'+ method +}]; + +testMethod.runTests('eth', method, tests); + diff --git a/libjsqrc/ethereumjs/test/web3.eth.filter.js b/libjsqrc/ethereumjs/test/web3.eth.filter.js index 7a355b50c..9f196b349 100644 --- a/libjsqrc/ethereumjs/test/web3.eth.filter.js +++ b/libjsqrc/ethereumjs/test/web3.eth.filter.js @@ -37,11 +37,17 @@ var tests = [{ formattedResult: '0xf', call: 'eth_newFilter' },{ - args: ['pending'], - formattedArgs: ['pending'], + args: ['latest'], + formattedArgs: [], result: '0xf', formattedResult: '0xf', call: 'eth_newBlockFilter' +},{ + args: ['pending'], + formattedArgs: [], + result: '0xf', + formattedResult: '0xf', + call: 'eth_newPendingTransactionFilter' }]; describe('web3.eth', function () { diff --git a/libjsqrc/ethereumjs/test/web3.eth.getWork.js b/libjsqrc/ethereumjs/test/web3.eth.getWork.js new file mode 100644 index 000000000..181c1894b --- /dev/null +++ b/libjsqrc/ethereumjs/test/web3.eth.getWork.js @@ -0,0 +1,16 @@ +var chai = require('chai'); +var web3 = require('../index'); +var testMethod = require('./helpers/test.method.js'); + +var method = 'getWork'; + +var tests = [{ + args: [], + formattedArgs: [], + result: true, + formattedResult: true, + call: 'eth_'+ method +}]; + +testMethod.runTests('eth', method, tests); + diff --git a/libjsqrc/ethereumjs/test/web3.eth.submitWork.js b/libjsqrc/ethereumjs/test/web3.eth.submitWork.js new file mode 100644 index 000000000..3751c8073 --- /dev/null +++ b/libjsqrc/ethereumjs/test/web3.eth.submitWork.js @@ -0,0 +1,17 @@ +var chai = require('chai'); +var web3 = require('../index'); +var testMethod = require('./helpers/test.method.js'); + +var method = 'submitWork'; + +var tests = [ +{ + args: ['0x567890abcdef5555', '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', '0xcdef1234567890abcdef1234567890abcdef0x1234567890abcf1234567890ab'], + formattedArgs: ['0x567890abcdef5555', '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', '0xcdef1234567890abcdef1234567890abcdef0x1234567890abcf1234567890ab'], + result: true, + formattedResult: true, + call: 'eth_'+ method +}]; + +testMethod.runTests('eth', method, tests); + diff --git a/libp2p/Common.cpp b/libp2p/Common.cpp index ed84f014c..ad04ca4ba 100644 --- a/libp2p/Common.cpp +++ b/libp2p/Common.cpp @@ -47,6 +47,9 @@ const char* NetTriviaDetail::name() { return EthYellow "N" EthCoal " 0"; } const char* NetAllDetail::name() { return EthYellow "N" EthCoal " A"; } const char* NetRight::name() { return EthYellow "N" EthGreen "->"; } const char* NetLeft::name() { return EthYellow "N" EthNavy "<-"; } +const char* NetP2PWarn::name() { return EthYellow "N" EthRed " X"; } +const char* NetP2PNote::name() { return EthYellow "N" EthBlue " i"; } +const char* NetP2PConnect::name() { return EthYellow "N" EthYellow " C"; } #else const char* NetWarn::name() { return EthYellow "⧎" EthRed " ✘"; } const char* NetImpolite::name() { return EthYellow "⧎" EthRed " !"; } @@ -59,6 +62,9 @@ const char* NetTriviaDetail::name() { return EthYellow "⧎" EthCoal " ◍"; } const char* NetAllDetail::name() { return EthYellow "⧎" EthCoal " ●"; } const char* NetRight::name() { return EthYellow "⧎" EthGreen "▬▶"; } const char* NetLeft::name() { return EthYellow "⧎" EthNavy "◀▬"; } +const char* NetP2PWarn::name() { return EthYellow "⧎" EthRed " ✘"; } +const char* NetP2PNote::name() { return EthYellow "⧎" EthBlue " ℹ"; } +const char* NetP2PConnect::name() { return EthYellow "⧎" EthYellow " ▢"; } #endif bool p2p::isPublicAddress(std::string const& _addressToCheck) diff --git a/libp2p/Common.h b/libp2p/Common.h index da7558ecb..8fd330580 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -78,8 +78,8 @@ struct InvalidHostIPAddress: virtual dev::Exception {}; struct NetWarn: public LogChannel { static const char* name(); static const int verbosity = 0; }; struct NetNote: public LogChannel { static const char* name(); static const int verbosity = 1; }; -struct NetImpolite: public LogChannel { static const char* name(); static const int verbosity = 1; }; -struct NetMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct NetImpolite: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct NetMessageSummary: public LogChannel { static const char* name(); static const int verbosity = 3; }; struct NetConnect: public LogChannel { static const char* name(); static const int verbosity = 10; }; struct NetMessageDetail: public LogChannel { static const char* name(); static const int verbosity = 5; }; struct NetTriviaSummary: public LogChannel { static const char* name(); static const int verbosity = 10; }; @@ -87,6 +87,9 @@ struct NetTriviaDetail: public LogChannel { static const char* name(); static co struct NetAllDetail: public LogChannel { static const char* name(); static const int verbosity = 13; }; struct NetRight: public LogChannel { static const char* name(); static const int verbosity = 14; }; struct NetLeft: public LogChannel { static const char* name(); static const int verbosity = 15; }; +struct NetP2PWarn: public LogChannel { static const char* name(); static const int verbosity = 2; }; +struct NetP2PNote: public LogChannel { static const char* name(); static const int verbosity = 6; }; +struct NetP2PConnect: public LogChannel { static const char* name(); static const int verbosity = 10; }; enum PacketType { @@ -172,12 +175,13 @@ struct NodeIPEndpoint /// Setting true causes isAllowed to return true for all addresses. (Used by test fixtures) static bool test_allowLocal; + NodeIPEndpoint() = default; NodeIPEndpoint(bi::address _addr, uint16_t _udp, uint16_t _tcp): address(_addr), udpPort(_udp), tcpPort(_tcp) {} NodeIPEndpoint(RLP const& _r) { interpretRLP(_r); } - bi::address address; - uint16_t udpPort; - uint16_t tcpPort; + bi::address address = bi::address(); + uint16_t udpPort = 0; + uint16_t tcpPort = 0; operator bi::udp::endpoint() const { return std::move(bi::udp::endpoint(address, udpPort)); } operator bi::tcp::endpoint() const { return std::move(bi::tcp::endpoint(address, tcpPort)); } diff --git a/libp2p/Host.cpp b/libp2p/Host.cpp index 9b5a6dca7..998579a90 100644 --- a/libp2p/Host.cpp +++ b/libp2p/Host.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include "Session.h" #include "Common.h" #include "Capability.h" @@ -244,7 +244,7 @@ void Host::startPeerSession(Public const& _id, RLP const& _rlp, RLPXFrameIO* _io m_sessions[_id] = ps; } - clog(NetNote) << "p2p.host.peer.register" << _id; + clog(NetP2PNote) << "p2p.host.peer.register" << _id; StructuredLogger::p2pConnected(_id.abridged(), ps->m_peer->endpoint, ps->m_peer->m_lastConnected, clientVersion, peerCount()); } @@ -252,7 +252,7 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) { if (_e == NodeEntryAdded) { - clog(NetNote) << "p2p.host.nodeTable.events.nodeEntryAdded " << _n; + clog(NetP2PNote) << "p2p.host.nodeTable.events.nodeEntryAdded " << _n; // only add iff node is in node table if (Node n = m_nodeTable->node(_n)) { @@ -268,7 +268,7 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) { p.reset(new Peer(n)); m_peers[_n] = p; - clog(NetNote) << "p2p.host.peers.events.peerAdded " << _n << p->endpoint; + clog(NetP2PNote) << "p2p.host.peers.events.peerAdded " << _n << p->endpoint; } } if (peerSlotsAvailable(Egress)) @@ -277,7 +277,7 @@ void Host::onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e) } else if (_e == NodeEntryDropped) { - clog(NetNote) << "p2p.host.nodeTable.events.NodeEntryDropped " << _n; + clog(NetP2PNote) << "p2p.host.nodeTable.events.NodeEntryDropped " << _n; RecursiveGuard l(x_sessions); m_peers.erase(_n); } @@ -392,7 +392,7 @@ string Host::pocHost() std::unordered_map const& Host::pocHosts() { static const std::unordered_map c_ret = { -// { Public(""), "poc-9.ethdev.com:30303" }, + { Public("487611428e6c99a11a9795a6abe7b529e81315ca6aad66e2a2fc76e3adf263faba0d35466c2f8f68d561dbefa8878d4df5f1f2ddb1fbeab7f42ffb8cd328bd4a"), "poc-9.ethdev.com:30303" }, { Public("a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c"), "52.16.188.185:30303" }, { Public("7f25d3eab333a6b98a8b5ed68d962bb22c876ffcd5561fca54e3c2ef27f754df6f7fd7c9b74cc919067abac154fb8e1f8385505954f161ae440abc355855e034"), "54.207.93.166:30303" } }; @@ -475,9 +475,11 @@ void Host::connect(std::shared_ptr const& _p) if (!!m_nodeTable && !m_nodeTable->haveNode(_p->id)) { - clog(NetWarn) << "Aborted connect. Node not in node table."; + // connect was attempted, so try again by adding to node table m_nodeTable->addNode(*_p.get()); - return; + // abort unless peer is required + if (!_p->required) + return; } // prevent concurrently connecting to a node @@ -647,14 +649,14 @@ void Host::startedWorking() runAcceptor(); } else - clog(NetNote) << "p2p.start.notice id:" << id() << "TCP Listen port is invalid or unavailable."; + clog(NetP2PNote) << "p2p.start.notice id:" << id() << "TCP Listen port is invalid or unavailable."; shared_ptr nodeTable(new NodeTable(m_ioService, m_alias, NodeIPEndpoint(bi::address::from_string(listenAddress()), listenPort(), listenPort()))); nodeTable->setEventHandler(new HostNodeTableHandler(*this)); m_nodeTable = nodeTable; restoreNetwork(&m_restoreNetwork); - clog(NetNote) << "p2p.started id:" << id(); + clog(NetP2PNote) << "p2p.started id:" << id(); run(boost::system::error_code()); } diff --git a/libp2p/Host.h b/libp2p/Host.h index 4cfca7718..78dc50727 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -243,7 +243,7 @@ private: std::list> m_connecting; ///< Pending connections. Mutex x_connecting; ///< Mutex for m_connecting. - unsigned m_idealPeerCount = 5; ///< Ideal number of peers to be connected to. + unsigned m_idealPeerCount = 11; ///< Ideal number of peers to be connected to. std::map> m_capabilities; ///< Each of the capabilities we support. diff --git a/libp2p/NodeTable.cpp b/libp2p/NodeTable.cpp index 35cfda64b..bf056c52f 100644 --- a/libp2p/NodeTable.cpp +++ b/libp2p/NodeTable.cpp @@ -38,7 +38,7 @@ const char* NodeTableAllDetail::name() { return "=P="; } const char* NodeTableEgress::name() { return ">>P"; } const char* NodeTableIngress::name() { return "< NodeTable::addNode(Node const& _node, NodeRelation _relati { if (_relation == Known) { - shared_ptr ret(new NodeEntry(m_node, _node.id, _node.endpoint)); + shared_ptr ret(new NodeEntry(m_node.id, _node.id, _node.endpoint)); ret->pending = false; DEV_GUARDED(x_nodes) m_nodes[_node.id] = ret; @@ -93,11 +93,10 @@ shared_ptr NodeTable::addNode(Node const& _node, NodeRelation _relati // ping address to recover nodeid if nodeid is empty if (!_node.id) { - clog(NodeTableConnect) << "Sending public key discovery Ping to" << (bi::udp::endpoint)_node.endpoint << "(Advertising:" << (bi::udp::endpoint)m_node.endpoint << ")"; - { - Guard l(x_pubkDiscoverPings); + DEV_GUARDED(x_nodes) + clog(NodeTableConnect) << "Sending public key discovery Ping to" << (bi::udp::endpoint)_node.endpoint << "(Advertising:" << (bi::udp::endpoint)m_node.endpoint << ")"; + DEV_GUARDED(x_pubkDiscoverPings) m_pubkDiscoverPings[_node.endpoint.address] = std::chrono::steady_clock::now(); - } ping(_node.endpoint); return move(shared_ptr()); } @@ -106,7 +105,7 @@ shared_ptr NodeTable::addNode(Node const& _node, NodeRelation _relati if (m_nodes.count(_node.id)) return m_nodes[_node.id]; - shared_ptr ret(new NodeEntry(m_node, _node.id, _node.endpoint)); + shared_ptr ret(new NodeEntry(m_node.id, _node.id, _node.endpoint)); DEV_GUARDED(x_nodes) m_nodes[_node.id] = ret; clog(NodeTableConnect) << "addNode pending for" << _node.endpoint; @@ -288,7 +287,10 @@ vector> NodeTable::nearestNodeEntries(NodeId _target) void NodeTable::ping(NodeIPEndpoint _to) const { - PingNode p(m_node.endpoint, _to); + NodeIPEndpoint src; + DEV_GUARDED(x_nodes) + src = m_node.endpoint; + PingNode p(src, _to); p.sign(m_secret); m_socketPointer->send(p); } @@ -466,9 +468,12 @@ void NodeTable::onReceived(UDPSocketFace*, bi::udp::endpoint const& _from, bytes } // update our endpoint address and UDP port - if ((!m_node.endpoint || !m_node.endpoint.isAllowed()) && isPublicAddress(in.destination.address)) - m_node.endpoint.address = in.destination.address; - m_node.endpoint.udpPort = in.destination.udpPort; + DEV_GUARDED(x_nodes) + { + if ((!m_node.endpoint || !m_node.endpoint.isAllowed()) && isPublicAddress(in.destination.address)) + m_node.endpoint.address = in.destination.address; + m_node.endpoint.udpPort = in.destination.udpPort; + } clog(NodeTableConnect) << "PONG from " << nodeid << _from; break; diff --git a/libp2p/NodeTable.h b/libp2p/NodeTable.h index 2e10dd891..0ec13c828 100644 --- a/libp2p/NodeTable.h +++ b/libp2p/NodeTable.h @@ -40,7 +40,7 @@ namespace p2p */ struct NodeEntry: public Node { - NodeEntry(Node _src, Public _pubk, NodeIPEndpoint _gw); + NodeEntry(NodeId const& _src, Public const& _pubk, NodeIPEndpoint const& _gw); unsigned const distance; ///< Node's distance (xor of _src as integer). bool pending = true; ///< Node will be ignored until Pong is received }; @@ -186,7 +186,7 @@ private: /* todo: replace boost::posix_time; change constants to upper camelcase */ boost::posix_time::milliseconds const c_evictionCheckInterval = boost::posix_time::milliseconds(75); ///< Interval at which eviction timeouts are checked. std::chrono::milliseconds const c_reqTimeout = std::chrono::milliseconds(300); ///< How long to wait for requests (evict, find iterations). - std::chrono::milliseconds const c_bucketRefresh = std::chrono::milliseconds(57600); ///< Refresh interval prevents bucket from becoming stale. [Kademlia] + std::chrono::milliseconds const c_bucketRefresh = std::chrono::milliseconds(7200); ///< Refresh interval prevents bucket from becoming stale. [Kademlia] struct NodeBucket { @@ -203,7 +203,7 @@ private: void ping(NodeEntry* _n) const; /// Returns center node entry which describes this node and used with dist() to calculate xor metric for node table nodes. - NodeEntry center() const { return NodeEntry(m_node, m_node.publicKey(), m_node.endpoint); } + NodeEntry center() const { return NodeEntry(m_node.id, m_node.publicKey(), m_node.endpoint); } /// Used by asynchronous operations to return NodeEntry which is active and managed by node table. std::shared_ptr nodeEntry(NodeId _id); @@ -247,7 +247,7 @@ private: std::unique_ptr m_nodeEventHandler; ///< Event handler for node events. - Node m_node; ///< This node. + Node m_node; ///< This node. LOCK x_state if endpoint access or mutation is required. Do not modify id. Secret m_secret; ///< This nodes secret key. mutable Mutex x_nodes; ///< LOCK x_state first if both locks are required. Mutable for thread-safe copy in nodes() const. diff --git a/libp2p/RLPxHandshake.cpp b/libp2p/RLPxHandshake.cpp index 8566b4f50..65116cd58 100644 --- a/libp2p/RLPxHandshake.cpp +++ b/libp2p/RLPxHandshake.cpp @@ -30,7 +30,7 @@ using namespace CryptoPP; void RLPXHandshake::writeAuth() { - clog(NetConnect) << "p2p.connect.egress sending auth to " << m_socket->remoteEndpoint(); + clog(NetP2PConnect) << "p2p.connect.egress sending auth to " << m_socket->remoteEndpoint(); m_auth.resize(Signature::size + h256::size + Public::size + h256::size + 1); bytesRef sig(&m_auth[0], Signature::size); bytesRef hepubk(&m_auth[Signature::size], h256::size); @@ -56,7 +56,7 @@ void RLPXHandshake::writeAuth() void RLPXHandshake::writeAck() { - clog(NetConnect) << "p2p.connect.ingress sending ack to " << m_socket->remoteEndpoint(); + clog(NetP2PConnect) << "p2p.connect.ingress sending ack to " << m_socket->remoteEndpoint(); m_ack.resize(Public::size + h256::size + 1); bytesRef epubk(&m_ack[0], Public::size); bytesRef nonce(&m_ack[Public::size], h256::size); @@ -74,7 +74,7 @@ void RLPXHandshake::writeAck() void RLPXHandshake::readAuth() { - clog(NetConnect) << "p2p.connect.ingress recving auth from " << m_socket->remoteEndpoint(); + clog(NetP2PConnect) << "p2p.connect.ingress recving auth from " << m_socket->remoteEndpoint(); m_authCipher.resize(307); auto self(shared_from_this()); ba::async_read(m_socket->ref(), ba::buffer(m_authCipher, 307), [this, self](boost::system::error_code ec, std::size_t) @@ -95,13 +95,13 @@ void RLPXHandshake::readAuth() m_remoteEphemeral = recover(*(Signature*)sig.data(), sharedSecret ^ m_remoteNonce); if (sha3(m_remoteEphemeral) != *(h256*)hepubk.data()) - clog(NetConnect) << "p2p.connect.ingress auth failed (invalid: hash mismatch) for" << m_socket->remoteEndpoint(); + clog(NetP2PConnect) << "p2p.connect.ingress auth failed (invalid: hash mismatch) for" << m_socket->remoteEndpoint(); transition(); } else { - clog(NetConnect) << "p2p.connect.ingress recving auth decrypt failed for" << m_socket->remoteEndpoint(); + clog(NetP2PConnect) << "p2p.connect.ingress recving auth decrypt failed for" << m_socket->remoteEndpoint(); m_nextState = Error; transition(); } @@ -110,7 +110,7 @@ void RLPXHandshake::readAuth() void RLPXHandshake::readAck() { - clog(NetConnect) << "p2p.connect.egress recving ack from " << m_socket->remoteEndpoint(); + clog(NetP2PConnect) << "p2p.connect.egress recving ack from " << m_socket->remoteEndpoint(); m_ackCipher.resize(210); auto self(shared_from_this()); ba::async_read(m_socket->ref(), ba::buffer(m_ackCipher, 210), [this, self](boost::system::error_code ec, std::size_t) @@ -125,7 +125,7 @@ void RLPXHandshake::readAck() } else { - clog(NetConnect) << "p2p.connect.egress recving ack decrypt failed for " << m_socket->remoteEndpoint(); + clog(NetP2PConnect) << "p2p.connect.egress recving ack decrypt failed for " << m_socket->remoteEndpoint(); m_nextState = Error; transition(); } @@ -138,9 +138,9 @@ void RLPXHandshake::error() auto connected = m_socket->isConnected(); if (connected && !m_socket->remoteEndpoint().address().is_unspecified()) - clog(NetConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Failed)"; + clog(NetP2PConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Failed)"; else - clog(NetConnect) << "Handshake Failed (Connection reset by peer)"; + clog(NetP2PConnect) << "Handshake Failed (Connection reset by peer)"; m_socket->close(); if (m_io != nullptr) @@ -151,7 +151,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) { if (_ech || m_nextState == Error || m_cancel) { - clog(NetConnect) << "Handshake Failed (I/O Error:" << _ech.message() << ")"; + clog(NetP2PConnect) << "Handshake Failed (I/O Error:" << _ech.message() << ")"; return error(); } @@ -175,7 +175,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) else if (m_nextState == WriteHello) { m_nextState = ReadHello; - clog(NetConnect) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "sending capabilities handshake"; + clog(NetP2PConnect) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "sending capabilities handshake"; /// This pointer will be freed if there is an error otherwise /// it will be passed to Host which will take ownership. @@ -220,7 +220,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) return; } - clog(NetNote) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "recvd hello header"; + clog(NetP2PNote) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "recvd hello header"; /// check frame size bytes& header = m_handshakeInBuffer; @@ -228,7 +228,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) if (frameSize > 1024) { // all future frames: 16777216 - clog(NetWarn) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame is too large" << frameSize; + clog(NetP2PWarn) << (m_originated ? "p2p.connect.egress" : "p2p.connect.ingress") << "hello frame is too large" << frameSize; m_nextState = Error; transition(); return; @@ -279,7 +279,7 @@ void RLPXHandshake::transition(boost::system::error_code _ech) if (!_ec) { if (!m_socket->remoteEndpoint().address().is_unspecified()) - clog(NetConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; + clog(NetP2PConnect) << "Disconnecting " << m_socket->remoteEndpoint() << " (Handshake Timeout)"; cancel(); } }); diff --git a/libp2p/UDP.h b/libp2p/UDP.h index b09d556e7..a455b5057 100644 --- a/libp2p/UDP.h +++ b/libp2p/UDP.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include "Common.h" diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 2f98ce4f6..14884254e 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include using namespace std; @@ -746,7 +746,7 @@ void FunctionCall::checkTypeRequirements(TypePointers const*) //@todo for structs, we have to check the number of arguments to be equal to the // number of non-mapping members if (m_arguments.size() != 1) - BOOST_THROW_EXCEPTION(createTypeError("More than one argument for explicit type conversion.")); + BOOST_THROW_EXCEPTION(createTypeError("Exactly one argument expected for explicit type conversion.")); if (!isPositionalCall) BOOST_THROW_EXCEPTION(createTypeError("Type conversion cannot allow named arguments.")); if (!m_arguments.front()->getType()->isExplicitlyConvertibleTo(*type.getActualType())) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index bcd4f9d68..66c503172 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -377,12 +377,16 @@ bool Compiler::visit(IfStatement const& _ifStatement) StackHeightChecker checker(m_context); CompilerContext::LocationSetter locationSetter(m_context, _ifStatement); compileExpression(_ifStatement.getCondition()); - eth::AssemblyItem trueTag = m_context.appendConditionalJump(); + m_context << eth::Instruction::ISZERO; + eth::AssemblyItem falseTag = m_context.appendConditionalJump(); + eth::AssemblyItem endTag = falseTag; + _ifStatement.getTrueStatement().accept(*this); if (_ifStatement.getFalseStatement()) + { + endTag = m_context.appendJumpToNew(); + m_context << falseTag; _ifStatement.getFalseStatement()->accept(*this); - eth::AssemblyItem endTag = m_context.appendJumpToNew(); - m_context << trueTag; - _ifStatement.getTrueStatement().accept(*this); + } m_context << endTag; checker.check(); diff --git a/libsolidity/CompilerStack.cpp b/libsolidity/CompilerStack.cpp index b3fedc45d..bffa4158f 100644 --- a/libsolidity/CompilerStack.cpp +++ b/libsolidity/CompilerStack.cpp @@ -31,7 +31,7 @@ #include #include -#include +#include using namespace std; diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 76d05bd0a..2e513b7fc 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -458,9 +458,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) break; } case Location::External: + case Location::CallCode: case Location::Bare: + case Location::BareCallCode: _functionCall.getExpression().accept(*this); - appendExternalFunctionCall(function, arguments, function.getLocation() == Location::Bare); + appendExternalFunctionCall(function, arguments); break; case Location::Creation: { @@ -527,13 +529,12 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) TypePointers{}, strings(), strings(), - Location::External, + Location::Bare, false, true, true ), - {}, - true + {} ); break; case Location::Suicide: @@ -622,7 +623,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) m_context << contractAddresses.find(function.getLocation())->second; for (unsigned i = function.getSizeOnStack(); i > 0; --i) m_context << eth::swapInstruction(i); - appendExternalFunctionCall(function, arguments, true); + appendExternalFunctionCall(function, arguments); break; } default: @@ -685,7 +686,7 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) IntegerType(0, IntegerType::Modifier::Address), true); m_context << eth::Instruction::BALANCE; } - else if (member == "send" || member.substr(0, min(member.size(), 4)) == "call") + else if ((set{"send", "call", "callcode"}).count(member)) appendTypeConversion(*_memberAccess.getExpression().getType(), IntegerType(0, IntegerType::Modifier::Address), true); else @@ -1031,9 +1032,10 @@ void ExpressionCompiler::appendHighBitsCleanup(IntegerType const& _typeOnStack) m_context << ((u256(1) << _typeOnStack.getNumBits()) - 1) << eth::Instruction::AND; } -void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functionType, - vector> const& _arguments, - bool bare) +void ExpressionCompiler::appendExternalFunctionCall( + FunctionType const& _functionType, + vector> const& _arguments +) { solAssert(_functionType.takesArbitraryParameters() || _arguments.size() == _functionType.getParameterTypes().size(), ""); @@ -1047,7 +1049,7 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio unsigned gasValueSize = (_functionType.gasSet() ? 1 : 0) + (_functionType.valueSet() ? 1 : 0); - unsigned contractStackPos = m_context.currentToBaseStackOffset(1 + gasValueSize + (bare ? 0 : 1)); + unsigned contractStackPos = m_context.currentToBaseStackOffset(1 + gasValueSize + (_functionType.isBareCall() ? 0 : 1)); unsigned gasStackPos = m_context.currentToBaseStackOffset(gasValueSize); unsigned valueStackPos = m_context.currentToBaseStackOffset(1); @@ -1057,7 +1059,7 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio unsigned retSize = firstType ? firstType->getCalldataEncodedSize() : 0; m_context << u256(retSize) << u256(0); - if (bare) + if (_functionType.isBareCall()) m_context << u256(0); else { @@ -1074,7 +1076,8 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio _arguments, _functionType.getParameterTypes(), _functionType.padArguments(), - bare, + _functionType.getLocation() == FunctionType::Location::Bare || + _functionType.getLocation() == FunctionType::Location::BareCallCode, _functionType.takesArbitraryParameters() ); @@ -1093,14 +1096,20 @@ void ExpressionCompiler::appendExternalFunctionCall(FunctionType const& _functio // send all gas except the amount needed to execute "SUB" and "CALL" // @todo this retains too much gas for now, needs to be fine-tuned. m_context << u256(50 + (_functionType.valueSet() ? 9000 : 0) + 25000) << eth::Instruction::GAS << eth::Instruction::SUB; - m_context << eth::Instruction::CALL; + if ( + _functionType.getLocation() == FunctionType::Location::CallCode || + _functionType.getLocation() == FunctionType::Location::BareCallCode + ) + m_context << eth::Instruction::CALLCODE; + else + m_context << eth::Instruction::CALL; auto tag = m_context.appendConditionalJump(); m_context << eth::Instruction::STOP << tag; // STOP if CALL leaves 0. if (_functionType.valueSet()) m_context << eth::Instruction::POP; if (_functionType.gasSet()) m_context << eth::Instruction::POP; - if (!bare) + if (!_functionType.isBareCall()) m_context << eth::Instruction::POP; m_context << eth::Instruction::POP; // pop contract address diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index 45a2311ef..954e32c84 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -98,8 +98,10 @@ private: void appendHighBitsCleanup(IntegerType const& _typeOnStack); /// Appends code to call a function of the given type with the given arguments. - void appendExternalFunctionCall(FunctionType const& _functionType, std::vector> const& _arguments, - bool bare = false); + void appendExternalFunctionCall( + FunctionType const& _functionType, + std::vector> const& _arguments + ); /// Appends code that evaluates the given arguments and moves the result to memory encoded as /// specified by the ABI. The memory offset is expected to be on the stack and is updated by /// this call. If @a _padToWordBoundaries is set to false, all values are concatenated without diff --git a/libsolidity/InterfaceHandler.cpp b/libsolidity/InterfaceHandler.cpp index a49c4dc3f..85026ac12 100644 --- a/libsolidity/InterfaceHandler.cpp +++ b/libsolidity/InterfaceHandler.cpp @@ -101,7 +101,7 @@ std::unique_ptr InterfaceHandler::getABIInterface(ContractDefinitio event["inputs"] = params; abi.append(event); } - return std::unique_ptr(new std::string(m_writer.write(abi))); + return std::unique_ptr(new std::string(Json::FastWriter().write(abi))); } unique_ptr InterfaceHandler::getABISolidityInterface(ContractDefinition const& _contractDef) @@ -153,7 +153,7 @@ std::unique_ptr InterfaceHandler::getUserDocumentation(ContractDefi } doc["methods"] = methods; - return std::unique_ptr(new std::string(m_writer.write(doc))); + return std::unique_ptr(new std::string(Json::FastWriter().write(doc))); } std::unique_ptr InterfaceHandler::getDevDocumentation(ContractDefinition const& _contractDef) @@ -217,7 +217,7 @@ std::unique_ptr InterfaceHandler::getDevDocumentation(ContractDefin } doc["methods"] = methods; - return std::unique_ptr(new std::string(m_writer.write(doc))); + return std::unique_ptr(new std::string(Json::FastWriter().write(doc))); } /* -- private -- */ diff --git a/libsolidity/InterfaceHandler.h b/libsolidity/InterfaceHandler.h index 6aa3f72d6..405181890 100644 --- a/libsolidity/InterfaceHandler.h +++ b/libsolidity/InterfaceHandler.h @@ -108,8 +108,6 @@ private: std::string const& _tag, CommentOwner _owner); - Json::StyledWriter m_writer; - // internal state DocTagType m_lastTag; std::string m_notice; diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index 7a5b309d9..7577b83a1 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -316,6 +316,7 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe const MemberList IntegerType::AddressMemberList({ {"balance", make_shared(256)}, {"call", make_shared(strings(), strings(), FunctionType::Location::Bare, true)}, + {"callcode", make_shared(strings(), strings(), FunctionType::Location::BareCallCode, true)}, {"send", make_shared(strings{"uint"}, strings{}, FunctionType::Location::Send)} }); @@ -1115,9 +1116,11 @@ unsigned FunctionType::getSizeOnStack() const } unsigned size = 0; - if (location == Location::External) + if (location == Location::External || location == Location::CallCode) size = 2; - else if (location == Location::Internal || location == Location::Bare) + else if (location == Location::Bare || location == Location::BareCallCode) + size = 1; + else if (location == Location::Internal) size = 1; if (m_gasSet) size++; @@ -1156,6 +1159,7 @@ MemberList const& FunctionType::getMembers() const case Location::SHA256: case Location::RIPEMD160: case Location::Bare: + case Location::BareCallCode: if (!m_members) { MemberList::MemberMap members{ @@ -1228,6 +1232,21 @@ bool FunctionType::hasEqualArgumentTypes(FunctionType const& _other) const ); } +bool FunctionType::isBareCall() const +{ + switch (m_location) + { + case Location::Bare: + case Location::BareCallCode: + case Location::ECRecover: + case Location::SHA256: + case Location::RIPEMD160: + return true; + default: + return false; + } +} + string FunctionType::externalSignature(std::string const& _name) const { std::string funcName = _name; diff --git a/libsolidity/Types.h b/libsolidity/Types.h index da2fcdb89..a69df964c 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -540,17 +540,32 @@ private: class FunctionType: public Type { public: - /// The meaning of the value(s) on the stack referencing the function: - /// INTERNAL: jump tag, EXTERNAL: contract address + function identifier, - /// BARE: contract address (non-abi contract call) - /// OTHERS: special virtual function, nothing on the stack + /// How this function is invoked on the EVM. /// @todo This documentation is outdated, and Location should rather be named "Type" - enum class Location { Internal, External, Creation, Send, - SHA3, Suicide, - ECRecover, SHA256, RIPEMD160, - Log0, Log1, Log2, Log3, Log4, Event, - SetGas, SetValue, BlockHash, - Bare }; + enum class Location + { + Internal, ///< stack-call using plain JUMP + External, ///< external call using CALL + CallCode, ///< extercnal call using CALLCODE, i.e. not exchanging the storage + Bare, ///< CALL without function hash + BareCallCode, ///< CALLCODE without function hash + Creation, ///< external call using CREATE + Send, ///< CALL, but without data and gas + SHA3, ///< SHA3 + Suicide, ///< SUICIDE + ECRecover, ///< CALL to special contract for ecrecover + SHA256, ///< CALL to special contract for sha256 + RIPEMD160, ///< CALL to special contract for ripemd160 + Log0, + Log1, + Log2, + Log3, + Log4, + Event, ///< syntactic sugar for LOG* + SetGas, ///< modify the default gas value for the function call + SetValue, ///< modify the default value transfer for the function call + BlockHash ///< BLOCKHASH + }; virtual Category getCategory() const override { return Category::Function; } @@ -620,6 +635,8 @@ public: /// @returns true if the types of parameters are equal (does't check return parameter types) bool hasEqualArgumentTypes(FunctionType const& _other) const; + /// @returns true if the ABI is used for this call (only meaningful for external calls) + bool isBareCall() const; Location const& getLocation() const { return m_location; } /// @returns the external signature of this function type given the function name /// If @a _name is not provided (empty string) then the @c m_declaration member of the diff --git a/libtestutils/Common.cpp b/libtestutils/Common.cpp index 5767be32c..cff21d464 100644 --- a/libtestutils/Common.cpp +++ b/libtestutils/Common.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "Common.h" using namespace std; diff --git a/libweb3jsonrpc/WebThreeStubServer.cpp b/libweb3jsonrpc/WebThreeStubServer.cpp index 5235b0c4f..44f7f521c 100644 --- a/libweb3jsonrpc/WebThreeStubServer.cpp +++ b/libweb3jsonrpc/WebThreeStubServer.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include "WebThreeStubServer.h" using namespace std; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index cac634a61..6b714f2ac 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -99,11 +99,12 @@ static Json::Value toJson(dev::eth::Transaction const& _t, std::pair(_blockHash); if (_includeTransactions) - return toJson(client()->blockInfo(h), client()->uncleHashes(h), client()->transactions(h)); + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h)); else - return toJson(client()->blockInfo(h), client()->uncleHashes(h), client()->transactionHashes(h)); + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactionHashes(h)); } catch (...) { @@ -618,9 +620,9 @@ Json::Value WebThreeStubServerBase::eth_getBlockByNumber(string const& _blockNum { auto h = jsToBlockNumber(_blockNumber); if (_includeTransactions) - return toJson(client()->blockInfo(h), client()->uncleHashes(h), client()->transactions(h)); + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactions(h)); else - return toJson(client()->blockInfo(h), client()->uncleHashes(h), client()->transactionHashes(h)); + return toJson(client()->blockInfo(h), client()->blockDetails(h), client()->uncleHashes(h), client()->transactionHashes(h)); } catch (...) { diff --git a/libwhisper/Common.cpp b/libwhisper/Common.cpp index c29ac6bf6..dd9172c70 100644 --- a/libwhisper/Common.cpp +++ b/libwhisper/Common.cpp @@ -21,7 +21,7 @@ #include "Common.h" -#include +#include #include "Message.h" using namespace std; using namespace dev; diff --git a/libwhisper/Interface.h b/libwhisper/Interface.h index db595e21e..8b84193aa 100644 --- a/libwhisper/Interface.h +++ b/libwhisper/Interface.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include "Common.h" #include "Message.h" diff --git a/libwhisper/Message.h b/libwhisper/Message.h index bd73df268..893602190 100644 --- a/libwhisper/Message.h +++ b/libwhisper/Message.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "Common.h" namespace dev diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h index ebbbcf8ed..cd427da35 100644 --- a/libwhisper/WhisperHost.h +++ b/libwhisper/WhisperHost.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include #include "Common.h" #include "WhisperPeer.h" #include "Interface.h" diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp index 9bef25140..7bcdfe8aa 100644 --- a/libwhisper/WhisperPeer.cpp +++ b/libwhisper/WhisperPeer.cpp @@ -66,10 +66,8 @@ bool WhisperPeer::interpret(unsigned _id, RLP const& _r) } case MessagesPacket: { - unsigned n = 0; for (auto i: _r) - if (n++) - host()->inject(Envelope(i), this); + host()->inject(Envelope(i), this); break; } default: diff --git a/libwhisper/WhisperPeer.h b/libwhisper/WhisperPeer.h index 8542e987d..ab9c8222a 100644 --- a/libwhisper/WhisperPeer.h +++ b/libwhisper/WhisperPeer.h @@ -29,7 +29,7 @@ #include #include -#include +#include #include "Common.h" #include "Message.h" diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index b355c336f..54d5db2b5 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -194,7 +194,7 @@ QVariantMap ClientModel::contractAddresses() const { QVariantMap res; for (auto const& c: m_contractAddresses) - res.insert(c.first, QString::fromStdString(toJS(c.second))); + res.insert(c.first.first, QString::fromStdString(toJS(c.second))); return res; } @@ -256,30 +256,17 @@ void ClientModel::setupState(QVariantMap _state) u256 value = (qvariant_cast(transaction.value("value")))->toU256Wei(); u256 gasPrice = (qvariant_cast(transaction.value("gasPrice")))->toU256Wei(); QString sender = transaction.value("sender").toString(); - bool isStdContract = (transaction.value("stdContract").toBool()); - if (isStdContract) - { - if (contractId.isEmpty()) //TODO: This is to support old project files, remove later - contractId = functionId; - TransactionSettings transactionSettings(contractId, transaction.value("url").toString()); - transactionSettings.gasPrice = 10000000000000; - transactionSettings.gasAuto = true; - transactionSettings.value = 0; - transactionSettings.sender = Secret(sender.toStdString()); - transactionSequence.push_back(transactionSettings); - } - else - { - if (contractId.isEmpty() && m_codeModel->hasContract()) //TODO: This is to support old project files, remove later - contractId = m_codeModel->contracts().keys()[0]; - TransactionSettings transactionSettings(contractId, functionId, value, gas, gasAuto, gasPrice, Secret(sender.toStdString())); - transactionSettings.parameterValues = transaction.value("parameters").toMap(); + bool isContractCreation = transaction.value("isContractCreation").toBool(); + bool isFunctionCall = transaction.value("isFunctionCall").toBool(); + if (contractId.isEmpty() && m_codeModel->hasContract()) //TODO: This is to support old project files, remove later + contractId = m_codeModel->contracts().keys()[0]; + TransactionSettings transactionSettings(contractId, functionId, value, gas, gasAuto, gasPrice, Secret(sender.toStdString()), isContractCreation, isFunctionCall); + transactionSettings.parameterValues = transaction.value("parameters").toMap(); - if (contractId == functionId || functionId == "Constructor") - transactionSettings.functionId.clear(); + if (contractId == functionId || functionId == "Constructor") + transactionSettings.functionId.clear(); - transactionSequence.push_back(transactionSettings); - } + transactionSequence.push_back(transactionSettings); } m_ethAccounts->setAccounts(userAccounts); executeSequence(transactionSequence, accounts, Secret(_state.value("miner").toMap().value("secret").toString().toStdString())); @@ -308,84 +295,75 @@ void ClientModel::executeSequence(vector const& _sequence, m_gasCosts.clear(); for (TransactionSettings const& transaction: _sequence) { + std::pair ctrInstance = resolvePair(transaction.contractId); + QString address = resolveToken(ctrInstance, deployedContracts); + if (!transaction.isFunctionCall) + { + callAddress(Address(address.toStdString()), bytes(), transaction); + onNewTransaction(); + continue; + } ContractCallDataEncoder encoder; - if (!transaction.stdContractUrl.isEmpty()) + //encode data + CompiledContract const& compilerRes = m_codeModel->contract(ctrInstance.first); + QFunctionDefinition const* f = nullptr; + bytes contractCode = compilerRes.bytes(); + shared_ptr contractDef = compilerRes.sharedContract(); + if (transaction.functionId.isEmpty()) + f = contractDef->constructor(); + else + for (QFunctionDefinition const* tf: contractDef->functionsList()) + if (tf->name() == transaction.functionId) + { + f = tf; + break; + } + if (!f) { - //std contract - bytes const& stdContractCode = m_codeModel->getStdContractCode(transaction.contractId, transaction.stdContractUrl); - TransactionSettings stdTransaction = transaction; - stdTransaction.gasAuto = true; - Address address = deployContract(stdContractCode, stdTransaction); - deployedContracts.push_back(address); - m_stdContractAddresses[stdTransaction.contractId] = address; - m_stdContractNames[address] = stdTransaction.contractId; + emit runFailed("Function '" + transaction.functionId + tr("' not found. Please check transactions or the contract code.")); + m_running = false; + emit runStateChanged(); + return; + } + if (!transaction.functionId.isEmpty()) + encoder.encode(f); + for (QVariableDeclaration const* p: f->parametersList()) + { + QSolidityType const* type = p->type(); + QVariant value = transaction.parameterValues.value(p->name()); + if (type->type().type == SolidityType::Type::Address) + { + std::pair ctrParamInstance = resolvePair(value.toString()); + value = QVariant(resolveToken(ctrParamInstance, deployedContracts)); + } + encoder.encode(value, type->type()); + } + + if (transaction.functionId.isEmpty() || transaction.functionId == ctrInstance.first) + { + bytes param = encoder.encodedData(); + contractCode.insert(contractCode.end(), param.begin(), param.end()); + Address newAddress = deployContract(contractCode, transaction); + deployedContracts.push_back(newAddress); + std::pair contractToken = retrieveToken(transaction.contractId, deployedContracts); + m_contractAddresses[contractToken] = newAddress; + m_contractNames[newAddress] = contractToken.first; + contractAddressesChanged(); + gasCostsChanged(); } else { - //encode data - CompiledContract const& compilerRes = m_codeModel->contract(transaction.contractId); - QFunctionDefinition const* f = nullptr; - bytes contractCode = compilerRes.bytes(); - shared_ptr contractDef = compilerRes.sharedContract(); - if (transaction.functionId.isEmpty()) - f = contractDef->constructor(); - else - for (QFunctionDefinition const* tf: contractDef->functionsList()) - if (tf->name() == transaction.functionId) - { - f = tf; - break; - } - if (!f) + auto contractAddressIter = m_contractAddresses.find(ctrInstance); + if (contractAddressIter == m_contractAddresses.end()) { - emit runFailed("Function '" + transaction.functionId + tr("' not found. Please check transactions or the contract code.")); + emit runFailed("Contract '" + transaction.contractId + tr(" not deployed.") + "' " + tr(" Cannot call ") + transaction.functionId); m_running = false; emit runStateChanged(); return; } - if (!transaction.functionId.isEmpty()) - encoder.encode(f); - for (QVariableDeclaration const* p: f->parametersList()) - { - QSolidityType const* type = p->type(); - QVariant value = transaction.parameterValues.value(p->name()); - if (type->type().type == SolidityType::Type::Address && value.toString().startsWith("<") && value.toString().endsWith(">")) - { - QStringList nb = value.toString().remove("<").remove(">").split(" - "); - value = QVariant(QString::fromStdString("0x" + dev::toHex(deployedContracts.at(nb.back().toInt()).ref()))); - } - encoder.encode(value, type->type()); - } - - if (transaction.functionId.isEmpty() || transaction.functionId == transaction.contractId) - { - bytes param = encoder.encodedData(); - contractCode.insert(contractCode.end(), param.begin(), param.end()); - Address newAddress = deployContract(contractCode, transaction); - deployedContracts.push_back(newAddress); - auto contractAddressIter = m_contractAddresses.find(transaction.contractId); - if (contractAddressIter == m_contractAddresses.end() || newAddress != contractAddressIter->second) - { - m_contractAddresses[transaction.contractId] = newAddress; - m_contractNames[newAddress] = transaction.contractId; - contractAddressesChanged(); - } - gasCostsChanged(); - } - else - { - auto contractAddressIter = m_contractAddresses.find(transaction.contractId); - if (contractAddressIter == m_contractAddresses.end()) - { - emit runFailed("Contract '" + transaction.contractId + tr(" not deployed.") + "' " + tr(" Cannot call ") + transaction.functionId); - m_running = false; - emit runStateChanged(); - return; - } - callContract(contractAddressIter->second, encoder.encodedData(), transaction); - } - m_gasCosts.append(m_client->lastExecution().gasUsed); + callAddress(contractAddressIter->second, encoder.encodedData(), transaction); } + m_gasCosts.append(m_client->lastExecution().gasUsed); onNewTransaction(); } m_running = false; @@ -406,6 +384,37 @@ void ClientModel::executeSequence(vector const& _sequence, }); } + +std::pair ClientModel::resolvePair(QString const& _contractId) +{ + std::pair ret; + ret.first = _contractId; + ret.second = -1; + if (_contractId.startsWith("<") && _contractId.endsWith(">")) + { + QStringList values = ret.first.remove("<").remove(">").split(" - "); + ret.first = values[0]; + ret.second = values[1].toUInt(); + } + return ret; +} + +QString ClientModel::resolveToken(std::pair const& _value, vector
const& _contracts) +{ + if (_value.second != -1) + return QString::fromStdString("0x" + dev::toHex(_contracts.at(_value.second).ref())); + else + return _value.first; +} + +std::pair ClientModel::retrieveToken(QString const& _value, vector
const& _contracts) +{ + std::pair ret; + ret.first = _value; + ret.second = _contracts.size() - 1; + return ret; +} + void ClientModel::showDebugger() { ExecutionResult last = m_client->lastExecution(); @@ -610,7 +619,7 @@ Address ClientModel::deployContract(bytes const& _code, TransactionSettings cons return newAddress; } -void ClientModel::callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr) +void ClientModel::callAddress(Address const& _contract, bytes const& _data, TransactionSettings const& _tr) { m_client->submitTransaction(_tr.sender, _tr.value, _contract, _data, _tr.gas, _tr.gasPrice, _tr.gasAuto); } @@ -660,14 +669,7 @@ void ClientModel::onNewTransaction() if (creation) { //contract creation - auto const stdContractName = m_stdContractNames.find(tr.contractAddress); - if (stdContractName != m_stdContractNames.end()) - { - function = stdContractName->second; - contract = function; - } - else - function = QObject::tr("Constructor"); + function = QObject::tr("Constructor"); address = QObject::tr("(Create contract)"); } else diff --git a/mix/ClientModel.h b/mix/ClientModel.h index 910c0ed01..e1648b78d 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -53,10 +53,10 @@ struct SolidityType; struct TransactionSettings { TransactionSettings() {} - TransactionSettings(QString const& _contractId, QString const& _functionId, u256 _value, u256 _gas, bool _gasAuto, u256 _gasPrice, Secret _sender): - contractId(_contractId), functionId(_functionId), value(_value), gas(_gas), gasAuto(_gasAuto), gasPrice(_gasPrice), sender(_sender) {} + TransactionSettings(QString const& _contractId, QString const& _functionId, u256 _value, u256 _gas, bool _gasAuto, u256 _gasPrice, Secret _sender, bool _isContractCreation, bool _isFunctionCall): + contractId(_contractId), functionId(_functionId), value(_value), gas(_gas), gasAuto(_gasAuto), gasPrice(_gasPrice), sender(_sender), isContractCreation(_isContractCreation), isFunctionCall(_isFunctionCall) {} TransactionSettings(QString const& _stdContractName, QString const& _stdContractUrl): - contractId(_stdContractName), gasAuto(true), stdContractUrl(_stdContractUrl) {} + contractId(_stdContractName), gasAuto(true), stdContractUrl(_stdContractUrl), isContractCreation(true), isFunctionCall(true) {} /// Contract name QString contractId; @@ -76,6 +76,10 @@ struct TransactionSettings QString stdContractUrl; /// Sender Secret sender; + /// Tr deploys a contract + bool isContractCreation; + /// Tr call a ctr function + bool isFunctionCall; }; @@ -222,11 +226,14 @@ private: QVariantList gasCosts() const; void executeSequence(std::vector const& _sequence, std::unordered_map const& _accounts, Secret const& _miner); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); - void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); + void callAddress(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); void onNewTransaction(); void onStateReset(); void showDebuggerForTransaction(ExecutionResult const& _t); QVariant formatValue(SolidityType const& _type, dev::u256 const& _value); + QString resolveToken(std::pair const& _value, std::vector
const& _contracts); + std::pair retrieveToken(QString const& _value, std::vector
const& _contracts); + std::pair resolvePair(QString const& _contractId); QVariant formatStorageValue(SolidityType const& _type, std::unordered_map const& _storage, unsigned _offset, dev::u256 const& _slot); std::atomic m_running; @@ -237,7 +244,7 @@ private: std::unique_ptr m_web3Server; std::shared_ptr m_ethAccounts; QList m_gasCosts; - std::map m_contractAddresses; + std::map, Address> m_contractAddresses; std::map m_contractNames; std::map m_stdContractAddresses; std::map m_stdContractNames; diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 636a665e6..b0edb20f9 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include #include "QContractDefinition.h" @@ -50,6 +52,7 @@ const std::set c_predefinedContracts = namespace { +using namespace dev::eth; using namespace dev::solidity; class CollectLocalsVisitor: public ASTConstVisitor @@ -219,6 +222,19 @@ void CodeModel::reset(QVariantMap const& _documents) emit scheduleCompilationJob(++m_backgroundJobId); } +void CodeModel::unregisterContractSrc(QString const& _documentId) +{ + { + Guard pl(x_pendingContracts); + m_pendingContracts.erase(_documentId); + } + + // launch the background thread + m_compiling = true; + emit stateChanged(); + emit scheduleCompilationJob(++m_backgroundJobId); +} + void CodeModel::registerCodeChange(QString const& _documentId, QString const& _code) { { @@ -292,6 +308,7 @@ void CodeModel::runCompilationJob(int _jobId) } } cs.compile(false); + gasEstimation(cs); collectContracts(cs, sourceNames); } catch (dev::Exception const& _exception) @@ -314,6 +331,44 @@ void CodeModel::runCompilationJob(int _jobId) emit stateChanged(); } +void CodeModel::gasEstimation(solidity::CompilerStack const& _cs) +{ + if (m_gasCostsMaps) + m_gasCostsMaps->deleteLater(); + m_gasCostsMaps = new GasMapWrapper(this); + for (std::string n: _cs.getContractNames()) + { + ContractDefinition const& contractDefinition = _cs.getContractDefinition(n); + QString sourceName = QString::fromStdString(*contractDefinition.getLocation().sourceName); + + if (!m_gasCostsMaps->contains(sourceName)) + m_gasCostsMaps->insert(sourceName, QVariantList()); + + if (!contractDefinition.isFullyImplemented()) + continue; + dev::solidity::SourceUnit const& sourceUnit = _cs.getAST(*contractDefinition.getLocation().sourceName); + AssemblyItems const* items = _cs.getRuntimeAssemblyItems(n); + StructuralGasEstimator estimator; + std::map gasCosts = estimator.breakToStatementLevel(estimator.performEstimation(*items, std::vector({&sourceUnit})), {&sourceUnit}); + for (auto gasItem = gasCosts.begin(); gasItem != gasCosts.end(); ++gasItem) + { + SourceLocation const& location = gasItem->first->getLocation(); + GasMeter::GasConsumption cost = gasItem->second; + std::stringstream v; + v << cost.value; + m_gasCostsMaps->push(sourceName, location.start, location.end, QString::fromStdString(v.str()), cost.isInfinite); + } + } +} + +QVariantList CodeModel::gasCostByDocumentId(QString const& _documentId) const +{ + if (m_gasCostsMaps) + return m_gasCostsMaps->gasCostsByDocId(_documentId); + else + return QVariantList(); +} + void CodeModel::collectContracts(dev::solidity::CompilerStack const& _cs, std::vector const& _sourceNames) { Guard pl(x_pendingContracts); @@ -503,3 +558,29 @@ QString CodeModel::resolveFunctionName(dev::SourceLocation const& _location) } return QString(); } + +void GasMapWrapper::push(QString _source, int _start, int _end, QString _value, bool _isInfinite) +{ + GasMap* gas = new GasMap(_start, _end, _value, _isInfinite, this); + m_gasMaps.find(_source).value().push_back(QVariant::fromValue(gas)); +} + +bool GasMapWrapper::contains(QString _key) +{ + return m_gasMaps.contains(_key); +} + +void GasMapWrapper::insert(QString _source, QVariantList _variantList) +{ + m_gasMaps.insert(_source, _variantList); +} + +QVariantList GasMapWrapper::gasCostsByDocId(QString _source) +{ + auto gasIter = m_gasMaps.find(_source); + if (gasIter != m_gasMaps.end()) + return gasIter.value(); + else + return QVariantList(); +} + diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 3f713a17b..994e9936a 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -32,6 +32,7 @@ #include #include #include "SolidityType.h" +#include "QBigInt.h" class QTextDocument; @@ -127,6 +128,42 @@ struct SourceMap }; using SourceMaps = QMap; //by source id +using GasCostsMaps = QMap; //gas cost by contract name + +class GasMapWrapper: public QObject +{ + Q_OBJECT + + Q_PROPERTY(GasCostsMaps gasMaps MEMBER m_gasMaps CONSTANT) + +public: + GasMapWrapper(QObject* _parent): QObject(_parent){} + void push(QString _source, int _start, int _end, QString _value, bool _isInfinite); + bool contains(QString _key); + void insert(QString _source, QVariantList _variantList); + QVariantList gasCostsByDocId(QString _source); + +private: + GasCostsMaps m_gasMaps; +}; + +class GasMap: public QObject +{ + Q_OBJECT + + Q_PROPERTY(int start MEMBER m_start CONSTANT) + Q_PROPERTY(int end MEMBER m_end CONSTANT) + Q_PROPERTY(QString gas MEMBER m_gas CONSTANT) + Q_PROPERTY(bool isInfinite MEMBER m_isInfinite CONSTANT) + +public: + GasMap(int _start, int _end, QString _gas, bool _isInfinite, QObject* _parent): QObject(_parent), m_start(_start), m_end(_end), m_gas(_gas), m_isInfinite(_isInfinite) {} + + int m_start; + int m_end; + QString m_gas; + bool m_isInfinite; +}; /// Code compilation model. Compiles contracts in background an provides compiled contract data class CodeModel: public QObject @@ -160,12 +197,18 @@ public: Q_INVOKABLE CompiledContract* contractByDocumentId(QString const& _documentId) const; /// Reset code model Q_INVOKABLE void reset() { reset(QVariantMap()); } + /// Delete a contract source + Q_INVOKABLE void unregisterContractSrc(QString const& _documentId); /// Convert solidity type info to mix type static SolidityType nodeType(dev::solidity::Type const* _type); /// Check if given location belongs to contract or function bool isContractOrFunctionLocation(dev::SourceLocation const& _location); /// Get funciton name by location QString resolveFunctionName(dev::SourceLocation const& _location); + /// Gas estimation for compiled sources + void gasEstimation(solidity::CompilerStack const& _cs); + /// Gas cost by doc id + Q_INVOKABLE QVariantList gasCostByDocumentId(QString const& _documentId) const; signals: /// Emited on compilation state change @@ -201,6 +244,7 @@ private: mutable dev::Mutex x_contractMap; ContractMap m_contractMap; SourceMaps m_sourceMaps; + GasMapWrapper* m_gasCostsMaps = 0; std::unique_ptr m_codeHighlighterSettings; QThread m_backgroundThread; BackgroundWorker m_backgroundWorker; @@ -214,3 +258,5 @@ private: } } + +//Q_DECLARE_METATYPE(dev::mix::GasMap) diff --git a/mix/FileIo.cpp b/mix/FileIo.cpp index 0991aa63d..cf8300677 100644 --- a/mix/FileIo.cpp +++ b/mix/FileIo.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include "FileIo.h" using namespace dev; @@ -210,3 +210,9 @@ void FileIo::stopWatching(QString const& _path) { m_watcher->removePath(pathFromUrl(_path)); } + +void FileIo::deleteFile(QString const& _path) +{ + QFile file(pathFromUrl(_path)); + file.remove(); +} diff --git a/mix/FileIo.h b/mix/FileIo.h index 33c2bd5fd..90a143120 100644 --- a/mix/FileIo.h +++ b/mix/FileIo.h @@ -66,6 +66,8 @@ public: Q_INVOKABLE void watchFileChanged(QString const& _path); /// Stop Listenning for files change in @arg _path. Q_INVOKABLE void stopWatching(QString const& _path); + /// Delete a file + Q_INVOKABLE void deleteFile(QString const& _path); private: QString getHomePath() const; diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 888c9b59f..b011e0cec 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -220,7 +220,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c d.address = _t.receiveAddress(); d.sender = _t.sender(); d.value = _t.value(); - d.gasUsed = er.gasUsed + er.gasRefunded; + d.gasUsed = er.gasUsed + er.gasRefunded + c_callStipend; if (_t.isCreation()) d.contractAddress = right160(sha3(rlpList(_t.sender(), _t.nonce()))); if (!_call) @@ -234,7 +234,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c er =_state.execute(lastHashes, t); if (t.isCreation() && _state.code(d.contractAddress).empty()) BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment")); - d.gasUsed = er.gasUsed + er.gasRefunded + er.gasForDeposit; + d.gasUsed = er.gasUsed + er.gasRefunded + er.gasForDeposit + c_callStipend; // collect watches h256Set changed; Guard l(x_filtersWatches); diff --git a/mix/QFunctionDefinition.cpp b/mix/QFunctionDefinition.cpp index 13dbd4821..e6764d712 100644 --- a/mix/QFunctionDefinition.cpp +++ b/mix/QFunctionDefinition.cpp @@ -20,7 +20,7 @@ */ #include -#include +#include #include #include "QVariableDeclaration.h" #include "QFunctionDefinition.h" diff --git a/mix/qml.qrc b/mix/qml.qrc index 6cbc97a78..c47a7254f 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -8,7 +8,6 @@ qml/CodeEditorStyle.qml qml/CodeEditorView.qml qml/CommonSeparator.qml - qml/ContractLibrary.qml qml/DebugBasicInfo.qml qml/DebugInfoList.qml qml/Debugger.qml diff --git a/mix/qml/Application.qml b/mix/qml/Application.qml index fe62efe12..161f7141a 100644 --- a/mix/qml/Application.qml +++ b/mix/qml/Application.qml @@ -116,6 +116,10 @@ ApplicationWindow { MenuSeparator {} MenuItem { action: toggleAssemblyDebuggingAction } } + Menu { + title: qsTr("Tools") + MenuItem { action: gasEstimationAction } + } Menu { title: qsTr("Windows") MenuItem { action: openNextDocumentAction } @@ -409,4 +413,15 @@ ApplicationWindow { mainContent.codeEditor.goToCompilationError(); } } + + Action { + id: gasEstimationAction + text: qsTr("Display gas estimation") + shortcut: "Ctrl+G" + checkable: true + onTriggered: + { + mainContent.codeEditor.displayGasEstimation(checked); + } + } } diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml index e4d62ed81..80449c89a 100644 --- a/mix/qml/CodeEditorView.qml +++ b/mix/qml/CodeEditorView.qml @@ -168,6 +168,13 @@ Item { editors.itemAt(i).item.setFontSize(size); } + function displayGasEstimation(checked) + { + var editor = getEditor(currentDocumentId); + if (editor) + editor.displayGasEstimation(checked); + } + Component.onCompleted: projectModel.codeEditor = codeEditorView; Connections { @@ -177,6 +184,10 @@ Item { } onCompilationComplete: { sourceInError = ""; + var gasCosts = codeModel.gasCostByDocumentId(currentDocumentId); + var editor = getEditor(currentDocumentId); + if (editor) + editor.setGasCosts(gasCosts); } } @@ -190,9 +201,12 @@ Item { for (var i = 0; i < openDocCount; i++) { var doc = editorListModel.get(i); - var editor = editors.itemAt(i).item; - if (editor) - fileIo.writeFile(doc.path, editor.getText()); + if (editors.itemAt(i)) + { + var editor = editors.itemAt(i).item; + if (editor) + fileIo.writeFile(doc.path, editor.getText()); + } } } @@ -277,6 +291,7 @@ Item { messageDialog.doc = editorListModel.get(index); messageDialog.open(); } + loader.item.displayGasEstimation(gasEstimationAction.checked); } } Component.onCompleted: { @@ -315,6 +330,16 @@ Item { break; } } + + onDocumentRemoved: { + for (var i = 0; i < editorListModel.count; i++) + if (editorListModel.get(i).documentId === documentId) + { + editorListModel.remove(i); + openDocCount--; + break; + } + } } function loadIfNotLoaded () { diff --git a/mix/qml/ContractLibrary.qml b/mix/qml/ContractLibrary.qml deleted file mode 100644 index 4f3afafc6..000000000 --- a/mix/qml/ContractLibrary.qml +++ /dev/null @@ -1,27 +0,0 @@ -import QtQuick 2.2 - -Item { - id: contractLibrary - property alias model: contractListModel; - - Connections { - target: mainApplication - onLoaded: { - - //TODO: load a list, dependencies, ets, from external files - contractListModel.append({ - name: "Config", - url: "qrc:///stdc/std.sol", - }); - contractListModel.append({ - name: "NameReg", - url: "qrc:///stdc/std.sol", - }); - } - } - - ListModel { - id: contractListModel - } -} - diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index c6283b60e..9decc91ae 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -4,7 +4,6 @@ import QtQuick.Controls.Styles 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import Qt.labs.settings 1.0 -import QtGraphicalEffects 1.0 import "js/Debugger.js" as Debugger import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "." diff --git a/mix/qml/DeploymentDialog.qml b/mix/qml/DeploymentDialog.qml index 1fbde3ac9..81092ec76 100644 --- a/mix/qml/DeploymentDialog.qml +++ b/mix/qml/DeploymentDialog.qml @@ -15,7 +15,7 @@ Dialog { id: modalDeploymentDialog modality: Qt.ApplicationModal width: 735 - height: 400 + height: 450 visible: false property int ownedRegistrarDeployGas: 1179075 // TODO: Use sol library to calculate gas requirement for each tr. property int ownedRegistrarSetSubRegistrarGas: 50000 @@ -293,15 +293,15 @@ Dialog { DefaultLabel { text: qsTr("Root Registrar address:") - visible: false //still use it for now in dev env. + visible: true //still use it for now in dev env. } DefaultTextField { Layout.preferredWidth: 350 id: registrarAddr - text: "ab69f864e49fc4294d18355c4bafb0b91b5e629b" - visible: false + text: "c6d9d2cd449a754c494264e1809c50e34d64562b" + visible: true } DefaultLabel diff --git a/mix/qml/FilesSection.qml b/mix/qml/FilesSection.qml index d89875583..5e49143a7 100644 --- a/mix/qml/FilesSection.qml +++ b/mix/qml/FilesSection.qml @@ -3,6 +3,7 @@ import QtQuick.Window 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 import QtQuick.Controls.Styles 1.3 +import QtQuick.Dialogs 1.2 import "." @@ -241,8 +242,13 @@ Rectangle anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked:{ - if (mouse.button === Qt.RightButton && !isContract) - contextMenu.popup(); + if (mouse.button === Qt.RightButton) + { + if (isContract) + contextMenuContract.popup(); + else + contextMenu.popup(); + } else if (mouse.button === Qt.LeftButton) { rootItem.isSelected = true; @@ -263,11 +269,32 @@ Rectangle MenuItem { text: qsTr("Delete") onTriggered: { - projectModel.removeDocument(documentId); - wrapperItem.removeDocument(documentId); + deleteConfirmation.open(); } } } + + Menu { + id: contextMenuContract + MenuItem { + text: qsTr("Delete") + onTriggered: { + deleteConfirmation.open(); + } + } + } + + MessageDialog + { + id: deleteConfirmation + text: qsTr("Are you sure to delete this file ?") + standardButtons: StandardIcon.Ok | StandardIcon.Cancel + onAccepted: + { + projectModel.removeDocument(documentId); + wrapperItem.removeDocument(documentId); + } + } } } } diff --git a/mix/qml/QAddressView.qml b/mix/qml/QAddressView.qml index 204e92508..c880f0904 100644 --- a/mix/qml/QAddressView.qml +++ b/mix/qml/QAddressView.qml @@ -8,6 +8,10 @@ Item property alias accountRef: ctrModel property string subType property bool readOnly + property alias currentIndex: trCombobox.currentIndex + property alias currentText: textinput.text + property variant accounts + signal indexChanged() id: editRoot height: 20 width: 320 @@ -17,6 +21,51 @@ Item id: boldFont } + function currentValue() { + return currentText; + } + + function currentType() + { + return accountRef.get(trCombobox.currentIndex).type; + } + + function current() + { + return accountRef.get(trCombobox.currentIndex); + } + + function load() + { + accountRef.clear(); + accountRef.append({"itemid": " - "}); + + if (subType === "contract" || subType === "address") + { + var trCr = 0; + for (var k = 0; k < transactionsModel.count; k++) + { + if (k >= transactionIndex) + break; + var tr = transactionsModel.get(k); + if (tr.functionId === tr.contractId /*&& (dec[1] === tr.contractId || item.subType === "address")*/) + { + accountRef.append({ "itemid": tr.contractId + " - " + trCr, "value": "<" + tr.contractId + " - " + trCr + ">", "type": "contract" }); + trCr++; + } + } + } + if (subType === "address") + { + for (k = 0; k < accounts.length; k++) + { + if (accounts[k].address === undefined) + accounts[k].address = clientModel.address(accounts[k].secret); + accountRef.append({ "itemid": accounts[k].name, "value": "0x" + accounts[k].address, "type": "address" }); + } + } + } + function init() { trCombobox.visible = !readOnly @@ -35,6 +84,18 @@ Item } } + function select(address) + { + for (var k = 0; k < accountRef.count; k++) + { + if (accountRef.get(k).value === address) + { + trCombobox.currentIndex = k; + break; + } + } + } + Rectangle { anchors.fill: parent radius: 4 @@ -96,6 +157,7 @@ Item { textinput.text = ""; } + indexChanged(); } } } diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index 13d01d474..f8da6dabd 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -436,7 +436,7 @@ Dialog { model: transactionsModel headerVisible: false TableViewColumn { - role: "name" + role: "label" title: qsTr("Name") width: 150 delegate: Item { @@ -476,7 +476,7 @@ Dialog { text: { if (styleData.row >= 0) return transactionsModel.get( - styleData.row).functionId + styleData.row).label else return "" } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index 889a2d940..f21c93199 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -22,7 +22,7 @@ Item { s.contracts = []; return { title: s.title, - transactions: s.transactions.map(fromPlainTransactionItem), + transactions: s.transactions.filter(function(t) { return !t.stdContract; }).map(fromPlainTransactionItem), //support old projects by filtering std contracts accounts: s.accounts.map(fromPlainAccountItem), contracts: s.contracts.map(fromPlainAccountItem), miner: s.miner @@ -46,6 +46,7 @@ Item { t.sender = defaultAccount; //support for old project var r = { + type: t.type, contractId: t.contractId, functionId: t.functionId, url: t.url, @@ -53,10 +54,22 @@ Item { gas: QEtherHelper.createBigInt(t.gas.value), gasPrice: QEtherHelper.createEther(t.gasPrice.value, t.gasPrice.unit), gasAuto: t.gasAuto, - stdContract: t.stdContract ? true : false, parameters: {}, - sender: t.sender + sender: t.sender, + isContractCreation: t.isContractCreation, + label: t.label, + isFunctionCall: t.isFunctionCall }; + + if (r.isFunctionCall === undefined) + r.isFunctionCall = true; + + if (!r.label) + r.label = r.contractId + " - " + r.functionId; + + if (r.isContractCreation === undefined) + r.isContractCreation = r.functionId === r.contractId; + for (var key in t.parameters) r.parameters[key] = t.parameters[key]; @@ -100,6 +113,7 @@ Item { function toPlainTransactionItem(t) { var r = { + type: t.type, contractId: t.contractId, functionId: t.functionId, url: t.url, @@ -107,9 +121,11 @@ Item { gas: { value: t.gas.value() }, gasAuto: t.gasAuto, gasPrice: { value: t.gasPrice.value, unit: t.gasPrice.unit }, - stdContract: t.stdContract, sender: t.sender, - parameters: {} + parameters: {}, + isContractCreation: t.isContractCreation, + label: t.label, + isFunctionCall: t.isFunctionCall }; for (var key in t.parameters) r.parameters[key] = t.parameters[key]; @@ -171,10 +187,6 @@ Item { } } - ContractLibrary { - id: contractLibrary; - } - ListModel { id: stateListModel property int defaultStateIndex: 0 @@ -208,18 +220,6 @@ Item { item.accounts.push(account); item.miner = account; - //add all stdc contracts - for (var i = 0; i < contractLibrary.model.count; i++) { - var contractTransaction = defaultTransactionItem(); - var contractItem = contractLibrary.model.get(i); - contractTransaction.url = contractItem.url; - contractTransaction.contractId = contractItem.name; - contractTransaction.functionId = contractItem.name; - contractTransaction.stdContract = true; - contractTransaction.sender = item.accounts[0].secret; // default account is used to deploy std contract. - item.transactions.push(contractTransaction); - }; - //add constructors, //TODO: order by dependencies for(var c in codeModel.contracts) { var ctorTr = defaultTransactionItem(); @@ -255,17 +255,12 @@ Item { } function addNewContracts() { - //add new contracts for all states + //add new contracts to empty states var changed = false; for (var c in codeModel.contracts) { for (var s = 0; s < stateListModel.count; s++) { var state = stateList[s]; - for (var t = 0; t < state.transactions.length; t++) { - var transaction = state.transactions[t]; - if (transaction.functionId === c && transaction.contractId === c) - break; - } - if (t === state.transactions.length) { + if (state.transactions.length === 0) { //append this contract var ctorTr = defaultTransactionItem(); ctorTr.functionId = c; diff --git a/mix/qml/StatesComboBox.qml b/mix/qml/StatesComboBox.qml index 907580ee7..3d2b08eef 100644 --- a/mix/qml/StatesComboBox.qml +++ b/mix/qml/StatesComboBox.qml @@ -23,7 +23,6 @@ import QtQuick 2.0 import QtQuick.Controls 1.0 import QtQuick.Layouts 1.1 -import QtGraphicalEffects 1.0 import org.ethereum.qml.InverseMouseArea 1.0 Rectangle { diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index 0c01caeb1..1c1453002 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -3,7 +3,6 @@ import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Controls.Styles 1.3 import org.ethereum.qml.InverseMouseArea 1.0 -import QtGraphicalEffects 1.0 import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "." diff --git a/mix/qml/StructView.qml b/mix/qml/StructView.qml index 4df9ace67..4feab2166 100644 --- a/mix/qml/StructView.qml +++ b/mix/qml/StructView.qml @@ -75,38 +75,13 @@ Column item.readOnly = context === "variable"; if (ptype.category === QSolidityType.Address) { + item.accounts = accounts item.value = getValue(); if (context === "parameter") { var dec = modelData.type.name.split(" "); item.subType = dec[0]; - item.accountRef.append({"itemid": " - "}); - - if (item.subType === "contract" || item.subType === "address") - { - var trCr = 0; - for (var k = 0; k < transactionsModel.count; k++) - { - if (k >= transactionIndex) - break; - var tr = transactionsModel.get(k); - if (tr.functionId === tr.contractId && (dec[1] === tr.contractId || item.subType === "address")) - { - item.accountRef.append({ "itemid": tr.contractId + " - " + trCr, "value": "<" + tr.contractId + " - " + trCr + ">", "type": "contract" }); - trCr++; - } - } - } - if (item.subType === "address") - { - for (k = 0; k < accounts.length; k++) - { - if (accounts[k].address === undefined) - accounts[k].address = clientModel.address(accounts[k].secret); - item.accountRef.append({ "itemid": accounts[k].name, "value": "0x" + accounts[k].address, "type": "address" }); - } - - } + item.load(); } item.init(); } diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 66a98d19e..1437c2562 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -66,29 +66,48 @@ Dialog { contractIndex = 0; //@todo suggest unused contract contractComboBox.currentIndex = contractIndex; - loadFunctions(contractComboBox.currentValue()); + recipients.accounts = senderComboBox.model; + recipients.subType = "address"; + recipients.load(); + recipients.init(); + recipients.select(contractId); + + if (item.isContractCreation) + loadFunctions(contractComboBox.currentValue()); + else + loadFunctions(contractFromToken(recipients.currentValue())) selectFunction(functionId); + trType.checked = item.isContractCreation + trType.init(); + paramsModel = []; - if (functionId !== contractComboBox.currentValue()) + if (item.isContractCreation) + loadCtorParameters(); + else loadParameters(); - else { - var contract = codeModel.contracts[contractId]; - if (contract) { - var params = contract.contract.constructor.parameters; - for (var p = 0; p < params.length; p++) - loadParameter(params[p]); - } - } - initTypeLoader(); visible = true; valueField.focus = true; } + function loadCtorParameters(contractId) + { + paramsModel = []; + console.log(contractId); + var contract = codeModel.contracts[contractId]; + if (contract) { + var params = contract.contract.constructor.parameters; + for (var p = 0; p < params.length; p++) + loadParameter(params[p]); + } + initTypeLoader(); + } + function loadFunctions(contractId) { functionsModel.clear(); + functionsModel.append({ text: " - " }); var contract = codeModel.contracts[contractId]; if (contract) { var functions = codeModel.contracts[contractId].contract.functions; @@ -96,9 +115,6 @@ Dialog { functionsModel.append({ text: functions[f].name }); } } - //append constructor - functionsModel.append({ text: contractId }); - } function selectContract(contractName) @@ -136,7 +152,7 @@ Dialog { function loadParameters() { paramsModel = [] if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) { - var contract = codeModel.contracts[contractComboBox.currentValue()]; + var contract = codeModel.contracts[contractFromToken(recipients.currentValue())]; if (contract) { var func = contract.contract.functions[functionComboBox.currentIndex]; if (func) { @@ -193,10 +209,39 @@ Dialog { item.functionId = transactionDialog.functionId; } + item.isContractCreation = trType.checked; + if (item.isContractCreation) + item.functionId = item.contractId; + item.isFunctionCall = item.functionId !== " - "; + + if (!item.isContractCreation) + { + item.contractId = recipients.currentText; + item.label = item.contractId + " " + item.functionId; + if (recipients.current().type === "address") + { + item.functionId = ""; + item.isFunctionCall = false; + } + } + else + { + item.functionId = item.contractId; + item.label = qsTr("Deploy") + " " + item.contractId; + } + item.sender = senderComboBox.model[senderComboBox.currentIndex].secret; item.parameters = paramValues; return item; } + + function contractFromToken(token) + { + if (token.indexOf('<') === 0) + return token.replace("<", "").replace(">", "").split(" - ")[0]; + return token; + } + contentItem: Rectangle { color: transactionDialogStyle.generic.backgroundColor ColumnLayout { @@ -238,6 +283,59 @@ Dialog { } } + RowLayout + { + id: rowIsContract + Layout.fillWidth: true + height: 150 + CheckBox { + id: trType + onCheckedChanged: + { + init(); + } + + function init() + { + rowFunction.visible = !checked; + rowContract.visible = checked; + rowRecipient.visible = !checked; + paramLabel.visible = checked; + paramScroll.visible = checked; + functionComboBox.enabled = !checked; + if (checked) + loadCtorParameters(contractComboBox.currentValue()); + } + + text: qsTr("is contract creation") + checked: true + } + } + + RowLayout + { + id: rowRecipient + Layout.fillWidth: true + height: 150 + DefaultLabel { + Layout.preferredWidth: 75 + text: qsTr("Recipient") + } + + QAddressView + { + id: recipients + onIndexChanged: + { + rowFunction.visible = current().type === "contract"; + paramLabel.visible = current().type === "contract"; + paramScroll.visible = current().type === "contract"; + if (!rowIsContract.checked) + loadFunctions(contractFromToken(recipients.currentValue())) + } + } + } + RowLayout { id: rowContract @@ -260,7 +358,7 @@ Dialog { id: contractsModel } onCurrentIndexChanged: { - loadFunctions(currentValue()); + loadCtorParameters(currentValue()); } } } diff --git a/mix/qml/WebCodeEditor.qml b/mix/qml/WebCodeEditor.qml index 38f2327b1..562c9716b 100644 --- a/mix/qml/WebCodeEditor.qml +++ b/mix/qml/WebCodeEditor.qml @@ -83,6 +83,16 @@ Item { editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {}); } + function setGasCosts(gasCosts) { + if (initialized && editorBrowser) + editorBrowser.runJavaScript("setGasCosts('" + JSON.stringify(gasCosts) + "')", function(result) {}); + } + + function displayGasEstimation(show) { + if (initialized && editorBrowser) + editorBrowser.runJavaScript("displayGasEstimation('" + show + "')", function(result) {}); + } + Clipboard { id: clipboard @@ -134,7 +144,12 @@ Item { function compilationComplete() { if (editorBrowser) + { editorBrowser.runJavaScript("compilationComplete()", function(result) { }); + parent.displayGasEstimation(gasEstimationAction.checked); + } + + } function compilationError(error, sourceName) diff --git a/mix/qml/html/WebContainer.html b/mix/qml/html/WebContainer.html index 9c458a4c7..cd92852a7 100644 --- a/mix/qml/html/WebContainer.html +++ b/mix/qml/html/WebContainer.html @@ -23,8 +23,7 @@ updateContracts = function(contracts) { window.contracts = {}; window.BigNumber = require('bignumber.js'); for (var c in contracts) { - var contractProto = window.web3.eth.contract(contracts[c].interface); - var contract = new contractProto(contracts[c].address); + var contract = window.web3.eth.contract(contracts[c].interface).at(contracts[c].address); window.contracts[c] = { address: contracts[c].address, interface: contracts[c].interface, diff --git a/mix/qml/html/cm/codemirror.css b/mix/qml/html/cm/codemirror.css index 625baa942..c25a3ddad 100644 --- a/mix/qml/html/cm/codemirror.css +++ b/mix/qml/html/cm/codemirror.css @@ -8,6 +8,10 @@ font-size:12px } +.CodeMirror-search-field { + height:200%; +} + /* BREAKPOINTS */ .breakpoints {width: .8em;} .breakpoint { color: #822; } diff --git a/mix/qml/html/cm/solarized.css b/mix/qml/html/cm/solarized.css index b8cede806..1d298b990 100644 --- a/mix/qml/html/cm/solarized.css +++ b/mix/qml/html/cm/solarized.css @@ -189,3 +189,9 @@ view-port } span.CodeMirror-selectedtext { color: #586e75 !important; } + +/* Gas Costs */ +.CodeMirror-gasCosts { + border-bottom: double 1px #2aa198; +} + diff --git a/mix/qml/html/cm/solidityToken.js b/mix/qml/html/cm/solidityToken.js index d8e588a10..1c12278e1 100644 --- a/mix/qml/html/cm/solidityToken.js +++ b/mix/qml/html/cm/solidityToken.js @@ -5,7 +5,7 @@ function solCurrency() function solKeywords() { - return { "break": true, "case": true, "constant": true, "continue": true, "contract": true, "default": true, "do": true, "else": true, "event": true, "external": true, "is": true, "indexed": true, "for": true, "function": true, "if": true, "import": true, "mapping": true, "modifier": true, "new": true, "public": true, "private": true, "internal": true, "return": true, "returns": true, "struct": true, "switch": true, "var": true, "while": true, "enum": true }; + return { "break": true, "case": true, "constant": true, "continue": true, "contract": true, "default": true, "delete": true, "do": true, "else": true, "event": true, "external": true, "is": true, "indexed": true, "for": true, "function": true, "if": true, "import": true, "mapping": true, "modifier": true, "new": true, "public": true, "private": true, "internal": true, "return": true, "returns": true, "struct": true, "switch": true, "var": true, "while": true, "enum": true }; } function solStdContract() diff --git a/mix/qml/html/codeeditor.js b/mix/qml/html/codeeditor.js index d25fbd091..6499922ae 100644 --- a/mix/qml/html/codeeditor.js +++ b/mix/qml/html/codeeditor.js @@ -203,5 +203,112 @@ setFontSize = function(size) editor.refresh(); } +makeGasCostMarker = function(value) { + var marker = document.createElement("div"); + marker.style.color = "#822"; + marker.innerHTML = value; + marker.className = "CodeMirror-errorannotation-context"; + return marker; +}; + +var gasCosts = null; +setGasCosts = function(_gasCosts) +{ + gasCosts = JSON.parse(_gasCosts); + if (showingGasEstimation) + { + displayGasEstimation(false); + displayGasEstimation(true); + } +} + +var showingGasEstimation = false; +var gasMarkText = []; +var gasMarkRef = {}; +displayGasEstimation = function(show) +{ + show = JSON.parse(show); + showingGasEstimation = show; + if (show) + { + var maxGas = 20000; + var step = colorGradient.length / maxGas; // 20000 max gas + clearGasMark(); + gasMarkText = []; + gasMarkRef = {}; + for (var i in gasCosts) + { + if (gasCosts[i].gas !== "0") + { + var color; + var colorIndex = Math.round(step * gasCosts[i].gas); + if (gasCosts[i].isInfinite || colorIndex > colorGradient.length) + color = colorGradient[colorGradient.length - 1]; + else + color = colorGradient[colorIndex]; + var className = "CodeMirror-gasCosts" + i; + var line = editor.posFromIndex(gasCosts[i].start) + gasMarkText.push(editor.markText(line, editor.posFromIndex(gasCosts[i].end), { inclusiveLeft: true, inclusiveRight: true, handleMouseEvents: true, className: className, css: "background-color:" + color })); + gasMarkRef[className] = { line: line.line, value: gasCosts[i] }; + } + } + CodeMirror.on(editor.getWrapperElement(), "mouseover", listenMouseOver); + } + else + { + CodeMirror.off(editor.getWrapperElement(), "mouseover", listenMouseOver); + clearGasMark(); + if (gasAnnotation) + { + gasAnnotation.clear(); + gasAnnotation = null; + } + } +} + +function clearGasMark() +{ + if (gasMarkText) + for (var k in gasMarkText) + gasMarkText[k].clear(); +} + +var gasAnnotation; +function listenMouseOver(e) +{ + var node = e.target || e.srcElement; + if (node) + { + if (node.className && node.className.indexOf("CodeMirror-gasCosts") !== -1) + { + if (gasAnnotation) + gasAnnotation.clear(); + var cl = getGasCostClass(node); + var gasTitle = gasMarkRef[cl].value.isInfinite ? "infinite" : gasMarkRef[cl].value.gas; + gasTitle = gasTitle + " gas"; + gasAnnotation = editor.addLineWidget(gasMarkRef[cl].line + 1, makeGasCostMarker(gasTitle), { coverGutter: false, above: true }); + } + else if (gasAnnotation) + { + gasAnnotation.clear(); + gasAnnotation = null; + } + } +} + +function getGasCostClass(node) +{ + var classes = node.className.split(" "); + for (var k in classes) + { + if (classes[k].indexOf("CodeMirror-gasCosts") !== -1) + return classes[k]; + } + return ""; +} + +// blue => red ["#1515ED", "#1714EA", "#1914E8", "#1B14E6", "#1D14E4", "#1F14E2", "#2214E0", "#2414DE", "#2614DC", "#2813DA", "#2A13D8", "#2D13D6", "#2F13D4", "#3113D2", "#3313D0", "#3513CE", "#3713CC", "#3A12CA", "#3C12C8", "#3E12C6", "#4012C4", "#4212C2", "#4512C0", "#4712BE", "#4912BC", "#4B11BA", "#4D11B8", "#4F11B6", "#5211B4", "#5411B2", "#5611B0", "#5811AE", "#5A11AC", "#5D11AA", "#5F10A7", "#6110A5", "#6310A3", "#6510A1", "#67109F", "#6A109D", "#6C109B", "#6E1099", "#700F97", "#720F95", "#750F93", "#770F91", "#790F8F", "#7B0F8D", "#7D0F8B", "#7F0F89", "#820E87", "#840E85", "#860E83", "#880E81", "#8A0E7F", "#8D0E7D", "#8F0E7B", "#910E79", "#930D77", "#950D75", "#970D73", "#9A0D71", "#9C0D6F", "#9E0D6D", "#A00D6B", "#A20D69", "#A50D67", "#A70C64", "#A90C62", "#AB0C60", "#AD0C5E", "#AF0C5C", "#B20C5A", "#B40C58", "#B60C56", "#B80B54", "#BA0B52", "#BD0B50", "#BF0B4E", "#C10B4C", "#C30B4A", "#C50B48", "#C70B46", "#CA0A44", "#CC0A42", "#CE0A40", "#D00A3E", "#D20A3C", "#D50A3A", "#D70A38", "#D90A36", "#DB0934", "#DD0932", "#DF0930", "#E2092E", "#E4092C", "#E6092A", "#E80928", "#EA0926", "#ED0924"] +/* green => red */ var colorGradient = ["#429C27", "#439A26", "#449926", "#469726", "#479626", "#489525", "#4A9325", "#4B9225", "#4D9025", "#4E8F25", "#4F8E24", "#518C24", "#528B24", "#548924", "#558824", "#568723", "#588523", "#598423", "#5B8223", "#5C8122", "#5D8022", "#5F7E22", "#607D22", "#627B22", "#637A21", "#647921", "#667721", "#677621", "#697421", "#6A7320", "#6B7220", "#6D7020", "#6E6F20", "#706E20", "#716C1F", "#726B1F", "#74691F", "#75681F", "#76671E", "#78651E", "#79641E", "#7B621E", "#7C611E", "#7D601D", "#7F5E1D", "#805D1D", "#825B1D", "#835A1D", "#84591C", "#86571C", "#87561C", "#89541C", "#8A531B", "#8B521B", "#8D501B", "#8E4F1B", "#904D1B", "#914C1A", "#924B1A", "#94491A", "#95481A", "#97461A", "#984519", "#994419", "#9B4219", "#9C4119", "#9E4019", "#9F3E18", "#A03D18", "#A23B18", "#A33A18", "#A43917", "#A63717", "#A73617", "#A93417", "#AA3317", "#AB3216", "#AD3016", "#AE2F16", "#B02D16", "#B12C16", "#B22B15", "#B42915", "#B52815", "#B72615", "#B82514", "#B92414", "#BB2214", "#BC2114", "#BE1F14", "#BF1E13", "#C01D13", "#C21B13", "#C31A13", "#C51813", "#C61712", "#C71612", "#C91412", "#CA1312", "#CC1212"] + editor.setOption("extraKeys", extraKeys); diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index 6ec906996..6fce7686d 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -294,7 +294,10 @@ function renameDocument(documentId, newName) { function getDocument(documentId) { var i = getDocumentIndex(documentId); - return projectListModel.get(i); + if (i === -1) + return undefined; + else + return projectListModel.get(i); } function getDocumentIdByName(fileName) @@ -308,10 +311,13 @@ function getDocumentIdByName(fileName) function removeDocument(documentId) { var i = getDocumentIndex(documentId); var document = projectListModel.get(i); - if (!document.isContract) { - projectListModel.remove(i); - documentRemoved(documentId); - } + fileIo.stopWatching(document.path); + fileIo.deleteFile(document.path); + if (document.isContract) + codeModel.unregisterContractSrc(documentId); + projectListModel.remove(i); + saveProjectFile(); + documentRemoved(documentId); } function newHtmlFile() { diff --git a/mix/qml/js/TransactionHelper.js b/mix/qml/js/TransactionHelper.js index b0a5caa9e..b9a011b66 100644 --- a/mix/qml/js/TransactionHelper.js +++ b/mix/qml/js/TransactionHelper.js @@ -9,7 +9,10 @@ function defaultTransaction() gasAuto: true, gasPrice: createEther("100000", QEther.Wei), parameters: {}, - stdContract: false + stdContract: false, + isContractCreation: true, + label: "", + isFunctionCall: true }; } diff --git a/mix/test/qml/TestMain.qml b/mix/test/qml/TestMain.qml index 829364a99..727d90b25 100644 --- a/mix/test/qml/TestMain.qml +++ b/mix/test/qml/TestMain.qml @@ -113,5 +113,6 @@ TestCase function test_project_contractRename() { TestProject.test_contractRename(); } function test_project_multipleWebPages() { TestProject.test_multipleWebPages(); } function test_project_multipleContractsSameFile() { TestProject.test_multipleContractsSameFile(); } + function test_project_deleteFile() { TestProject.test_deleteFile(); } } diff --git a/mix/test/qml/js/TestDebugger.js b/mix/test/qml/js/TestDebugger.js index 4933136ff..4e295c46f 100644 --- a/mix/test/qml/js/TestDebugger.js +++ b/mix/test/qml/js/TestDebugger.js @@ -223,13 +223,16 @@ function test_ctrTypeAsParam() "}"); mainApplication.projectModel.stateListModel.editState(0); //C1 ctor already added var transactionDialog = mainApplication.projectModel.stateDialog.transactionDialog; + mainApplication.projectModel.stateDialog.model.editTransaction(3); + ts.waitForRendering(transactionDialog, 3000); + clickElement(transactionDialog, 200, 300); + ts.typeString("", transactionDialog); + transactionDialog.acceptAndClose(); mainApplication.projectModel.stateDialog.model.addTransaction(); transactionDialog = mainApplication.projectModel.stateDialog.transactionDialog; ts.waitForRendering(transactionDialog, 3000); transactionDialog.selectContract("C2"); transactionDialog.selectFunction("getFromC1"); - clickElement(transactionDialog, 406, 340); - clickElement(transactionDialog, 406, 366); transactionDialog.acceptAndClose(); mainApplication.projectModel.stateDialog.acceptAndClose(); mainApplication.mainContent.startQuickDebugging(); diff --git a/mix/test/qml/js/TestProject.js b/mix/test/qml/js/TestProject.js index 49b5ea51f..fe1023f05 100644 --- a/mix/test/qml/js/TestProject.js +++ b/mix/test/qml/js/TestProject.js @@ -44,3 +44,17 @@ function test_multipleContractsSameFile() tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel.get(3), "contract", "C2"); tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel.get(4), "contract", "C3"); } + +function test_deleteFile() +{ + newProject(); + var path = mainApplication.projectModel.projectPath; + createHtml("page1.html", "
Fail
"); + createHtml("page2.html", "
Fail
"); + createHtml("page3.html", "
Fail
"); + mainApplication.projectModel.removeDocument("page2.html"); + mainApplication.projectModel.closeProject(function(){}); + mainApplication.projectModel.loadProject(path); + var doc = mainApplication.projectModel.getDocument("page2.html"); + verify(!doc, "page2.html has not been removed"); +} diff --git a/neth/main.cpp b/neth/main.cpp index 7ce64cba5..a6e661d2e 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include #include #include diff --git a/rlp/main.cpp b/rlp/main.cpp index 5f2f7f358..3924f9c44 100644 --- a/rlp/main.cpp +++ b/rlp/main.cpp @@ -25,7 +25,7 @@ #include "../test/JsonSpiritHeaders.h" #include #include -#include +#include using namespace std; using namespace dev; namespace js = json_spirit; diff --git a/solc/jsonCompiler.cpp b/solc/jsonCompiler.cpp index 6f3834af4..d47903fca 100644 --- a/solc/jsonCompiler.cpp +++ b/solc/jsonCompiler.cpp @@ -50,6 +50,14 @@ string formatError(Exception const& _exception, string const& _name, CompilerSta return Json::FastWriter().write(output); } +Json::Value functionHashes(ContractDefinition const& _contract) +{ + Json::Value functionHashes(Json::objectValue); + for (auto const& it: _contract.getInterfaceFunctions()) + functionHashes[it.second->externalSignature()] = toHex(it.first.ref()); + return functionHashes; +} + string compile(string _input, bool _optimize) { StringMap sources; @@ -100,6 +108,7 @@ string compile(string _input, bool _optimize) contractData["interface"] = compiler.getInterface(contractName); contractData["bytecode"] = toHex(compiler.getBytecode(contractName)); contractData["opcodes"] = eth::disassemble(compiler.getBytecode(contractName)); + contractData["functionHashes"] = functionHashes(compiler.getContractDefinition(contractName)); ostringstream unused; contractData["assembly"] = compiler.streamAssembly(unused, contractName, sources, true); output["contracts"][contractName] = contractData; diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index dede47038..aada83041 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -549,58 +549,53 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e } } -void userDefinedTest(string testTypeFlag, std::function doTests) +void userDefinedTest(std::function doTests) { - Options::get(); // parse command line options, e.g. to enable JIT + if (!Options::get().singleTest) + return; - for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i) + if (Options::get().singleTestFile.empty() || Options::get().singleTestName.empty()) { - string arg = boost::unit_test::framework::master_test_suite().argv[i]; - if (arg == testTypeFlag) - { - if (boost::unit_test::framework::master_test_suite().argc <= i + 2) - { - cnote << "Missing filename\nUsage: testeth " << testTypeFlag << " \n"; - return; - } - string filename = boost::unit_test::framework::master_test_suite().argv[i + 1]; - string testname = boost::unit_test::framework::master_test_suite().argv[i + 2]; - int currentVerbosity = g_logVerbosity; - g_logVerbosity = 12; - try - { - cnote << "Testing user defined test: " << filename; - json_spirit::mValue v; - string s = asString(contents(filename)); - BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. "); - json_spirit::read_string(s, v); - json_spirit::mObject oSingleTest; - - json_spirit::mObject::const_iterator pos = v.get_obj().find(testname); - if (pos == v.get_obj().end()) - { - cnote << "Could not find test: " << testname << " in " << filename << "\n"; - return; - } - else - oSingleTest[pos->first] = pos->second; + cnote << "Missing user test specification\nUsage: testeth --singletest \n"; + return; + } - json_spirit::mValue v_singleTest(oSingleTest); - doTests(v_singleTest, false); - } - catch (Exception const& _e) - { - BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e)); - g_logVerbosity = currentVerbosity; - } - catch (std::exception const& _e) - { - BOOST_ERROR("Failed Test with Exception: " << _e.what()); - g_logVerbosity = currentVerbosity; - } - g_logVerbosity = currentVerbosity; + auto& filename = Options::get().singleTestFile; + auto& testname = Options::get().singleTestName; + int currentVerbosity = g_logVerbosity; + g_logVerbosity = 12; + try + { + cnote << "Testing user defined test: " << filename; + json_spirit::mValue v; + string s = asString(contents(filename)); + BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. "); + json_spirit::read_string(s, v); + json_spirit::mObject oSingleTest; + + json_spirit::mObject::const_iterator pos = v.get_obj().find(testname); + if (pos == v.get_obj().end()) + { + cnote << "Could not find test: " << testname << " in " << filename << "\n"; + return; } + else + oSingleTest[pos->first] = pos->second; + + json_spirit::mValue v_singleTest(oSingleTest); + doTests(v_singleTest, false); + } + catch (Exception const& _e) + { + BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e)); + g_logVerbosity = currentVerbosity; } + catch (std::exception const& _e) + { + BOOST_ERROR("Failed Test with Exception: " << _e.what()); + g_logVerbosity = currentVerbosity; + } + g_logVerbosity = currentVerbosity; } void executeTests(const string& _name, const string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests) @@ -731,6 +726,8 @@ Options::Options() bigData = true; else if (arg == "--checkstate") checkState = true; + else if (arg == "--wallet") + wallet = true; else if (arg == "--all") { performance = true; @@ -738,11 +735,25 @@ Options::Options() memory = true; inputLimits = true; bigData = true; + wallet= true; } else if (arg == "--singletest" && i + 1 < argc) { singleTest = true; - singleTestName = argv[i + 1]; + auto name1 = std::string{argv[i + 1]}; + if (i + 1 < argc) // two params + { + auto name2 = std::string{argv[i + 2]}; + if (name2[0] == '-') // not param, another option + singleTestName = std::move(name1); + else + { + singleTestFile = std::move(name1); + singleTestName = std::move(name2); + } + } + else + singleTestName = std::move(name1); } } } diff --git a/test/TestHelper.h b/test/TestHelper.h index 00b520d06..fc6c77fad 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -157,7 +157,7 @@ void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs); void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates); void executeTests(const std::string& _name, const std::string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests); -void userDefinedTest(std::string testTypeFlag, std::function doTests); +void userDefinedTest(std::function doTests); RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj); eth::LastHashes lastHashes(u256 _currentBlockNumber); json_spirit::mObject fillJsonWithState(eth::State _state); @@ -188,12 +188,14 @@ public: /// Test selection /// @{ bool singleTest = false; + std::string singleTestFile; std::string singleTestName; bool performance = false; bool quadratic = false; bool memory = false; bool inputLimits = false; bool bigData = false; + bool wallet = false; /// @} /// Get reference to options diff --git a/test/deprecated/main.cpp b/test/deprecated/main.cpp index 6ec8885b3..47e96f337 100644 --- a/test/deprecated/main.cpp +++ b/test/deprecated/main.cpp @@ -20,10 +20,6 @@ * Main test functions. */ -#include -#include "TrieHash.h" -#include "MemTrie.h" - #include int trieTest(); diff --git a/test/libdevcrypto/MemTrie.cpp b/test/libdevcrypto/MemTrie.cpp index ab5a13b60..4507d1d80 100644 --- a/test/libdevcrypto/MemTrie.cpp +++ b/test/libdevcrypto/MemTrie.cpp @@ -21,8 +21,8 @@ #include "MemTrie.h" -#include -#include +#include +#include #include using namespace std; using namespace dev; diff --git a/test/libdevcrypto/crypto.cpp b/test/libdevcrypto/crypto.cpp index 88ff98965..497887145 100644 --- a/test/libdevcrypto/crypto.cpp +++ b/test/libdevcrypto/crypto.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include @@ -45,13 +45,19 @@ static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1()); static CryptoPP::DL_GroupParameters_EC s_params(s_curveOID); static CryptoPP::DL_GroupParameters_EC::EllipticCurve s_curve(s_params.GetCurve()); -BOOST_AUTO_TEST_CASE(emptySHA3Types) +BOOST_AUTO_TEST_CASE(sha3general) { - h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")); - BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3); + BOOST_REQUIRE_EQUAL(sha3(""), h256("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); + BOOST_REQUIRE_EQUAL(sha3("hello"), h256("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8")); +} +BOOST_AUTO_TEST_CASE(emptySHA3Types) +{ h256 emptySHA3(fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")); BOOST_REQUIRE_EQUAL(emptySHA3, EmptySHA3); + + h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")); + BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3); } BOOST_AUTO_TEST_CASE(cryptopp_patch) @@ -805,7 +811,7 @@ int cryptoTest() std::string hmsg = sha3(t.rlp(false), false); cout << "SHA256(RLP(TX w/o SIG)): 0x" << toHex(hmsg) << endl; - bytes privkey = sha3Bytes("123"); + bytes privkey = sha3("123").asBytes(); { bytes pubkey(65); diff --git a/test/libdevcrypto/hexPrefix.cpp b/test/libdevcrypto/hexPrefix.cpp index c72f24535..223f1ac7b 100644 --- a/test/libdevcrypto/hexPrefix.cpp +++ b/test/libdevcrypto/hexPrefix.cpp @@ -27,7 +27,7 @@ #include "../JsonSpiritHeaders.h" #include #include -#include +#include #include "../TestHelper.h" using namespace std; diff --git a/test/libdevcrypto/trie.cpp b/test/libdevcrypto/trie.cpp index 3b3fa1dd2..b5d8662dc 100644 --- a/test/libdevcrypto/trie.cpp +++ b/test/libdevcrypto/trie.cpp @@ -27,8 +27,8 @@ #include "../JsonSpiritHeaders.h" #include -#include -#include "TrieHash.h" +#include +#include #include "MemTrie.h" #include "../TestHelper.h" @@ -102,10 +102,13 @@ BOOST_AUTO_TEST_CASE(hex_encoded_securetrie_test) { next_permutation(ss.begin(), ss.end()); MemoryDB m; + EnforceRefs r(m, true); GenericTrieDB t(&m); MemoryDB hm; + EnforceRefs hr(hm, true); HashedGenericTrieDB ht(&hm); MemoryDB fm; + EnforceRefs fr(fm, true); FatGenericTrieDB ft(&fm); t.init(); ht.init(); @@ -121,7 +124,9 @@ BOOST_AUTO_TEST_CASE(hex_encoded_securetrie_test) BOOST_REQUIRE(t.check(true)); BOOST_REQUIRE(ht.check(true)); BOOST_REQUIRE(ft.check(true)); - for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) + auto i = ft.begin(); + auto j = t.begin(); + for (; i != ft.end() && j != t.end(); ++i, ++j) { BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); @@ -164,10 +169,13 @@ BOOST_AUTO_TEST_CASE(trie_test_anyorder) { next_permutation(ss.begin(), ss.end()); MemoryDB m; + EnforceRefs r(m, true); GenericTrieDB t(&m); MemoryDB hm; + EnforceRefs hr(hm, true); HashedGenericTrieDB ht(&hm); MemoryDB fm; + EnforceRefs fr(fm, true); FatGenericTrieDB ft(&fm); t.init(); ht.init(); @@ -183,7 +191,9 @@ BOOST_AUTO_TEST_CASE(trie_test_anyorder) BOOST_REQUIRE(t.check(true)); BOOST_REQUIRE(ht.check(true)); BOOST_REQUIRE(ft.check(true)); - for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) + auto i = ft.begin(); + auto j = t.begin(); + for (; i != ft.end() && j != t.end(); ++i, ++j) { BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); @@ -244,10 +254,13 @@ BOOST_AUTO_TEST_CASE(trie_tests_ordered) } MemoryDB m; + EnforceRefs r(m, true); GenericTrieDB t(&m); MemoryDB hm; + EnforceRefs hr(hm, true); HashedGenericTrieDB ht(&hm); MemoryDB fm; + EnforceRefs fr(fm, true); FatGenericTrieDB ft(&fm); t.init(); ht.init(); @@ -265,7 +278,9 @@ BOOST_AUTO_TEST_CASE(trie_tests_ordered) BOOST_REQUIRE(t.check(true)); BOOST_REQUIRE(ht.check(true)); BOOST_REQUIRE(ft.check(true)); - for (auto i = ft.begin(), j = t.begin(); i != ft.end() && j != t.end(); ++i, ++j) + auto i = ft.begin(); + auto j = t.begin(); + for (; i != ft.end() && j != t.end(); ++i, ++j) { BOOST_CHECK_EQUAL(i == ft.end(), j == t.end()); BOOST_REQUIRE((*i).first.toBytes() == (*j).first.toBytes()); @@ -279,15 +294,25 @@ BOOST_AUTO_TEST_CASE(trie_tests_ordered) } } -inline h256 stringMapHash256(StringMap const& _s) +h256 stringMapHash256(StringMap const& _s) { - return hash256(_s); + BytesMap bytesMap; + for (auto const& _v: _s) + bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end()))); + return hash256(bytesMap); +} + +bytes stringMapRlp256(StringMap const& _s) +{ + BytesMap bytesMap; + for (auto const& _v: _s) + bytesMap.insert(std::make_pair(bytes(_v.first.begin(), _v.first.end()), bytes(_v.second.begin(), _v.second.end()))); + return rlp256(bytesMap); } BOOST_AUTO_TEST_CASE(moreTrieTests) { cnote << "Testing Trie more..."; -#if 0 // More tests... { MemoryDB m; @@ -296,7 +321,7 @@ BOOST_AUTO_TEST_CASE(moreTrieTests) cout << t; cout << m; cout << t.root() << endl; - cout << hash256(StringMap()) << endl; + cout << stringMapHash256(StringMap()) << endl; t.insert(string("tesz"), string("test")); cout << t; @@ -321,7 +346,7 @@ BOOST_AUTO_TEST_CASE(moreTrieTests) t.remove(string("test")); cout << m; cout << t.root() << endl; - cout << hash256(StringMap()) << endl; + cout << stringMapHash256(StringMap()) << endl; } { MemoryDB m; @@ -333,20 +358,23 @@ BOOST_AUTO_TEST_CASE(moreTrieTests) cout << m; cout << t.root() << endl; cout << stringMapHash256({{"b", "B"}, {"a", "A"}}) << endl; - cout << RLP(rlp256({{"b", "B"}, {"a", "A"}})) << endl; + bytes r(stringMapRlp256({{"b", "B"}, {"a", "A"}})); + cout << RLP(r) << endl; } { MemTrie t; t.insert("dog", "puppy"); cout << hex << t.hash256() << endl; - cout << RLP(t.rlp()) << endl; + bytes r(t.rlp()); + cout << RLP(r) << endl; } { MemTrie t; t.insert("bed", "d"); t.insert("be", "e"); cout << hex << t.hash256() << endl; - cout << RLP(t.rlp()) << endl; + bytes r(t.rlp()); + cout << RLP(r) << endl; } { cout << hex << stringMapHash256({{"dog", "puppy"}, {"doe", "reindeer"}}) << endl; @@ -354,12 +382,13 @@ BOOST_AUTO_TEST_CASE(moreTrieTests) t.insert("dog", "puppy"); t.insert("doe", "reindeer"); cout << hex << t.hash256() << endl; - cout << RLP(t.rlp()) << endl; + bytes r(t.rlp()); + cout << RLP(r) << endl; cout << toHex(t.rlp()) << endl; } -#endif { MemoryDB m; + EnforceRefs r(m, true); GenericTrieDB d(&m); d.init(); // initialise as empty tree. MemTrie t; @@ -371,16 +400,16 @@ BOOST_AUTO_TEST_CASE(moreTrieTests) t.insert(a, b); s[a] = b; - /*cout << endl << "-------------------------------" << endl; + cout << endl << "-------------------------------" << endl; cout << a << " -> " << b << endl; cout << d; cout << m; cout << d.root() << endl; - cout << hash256(s) << endl;*/ + cout << stringMapHash256(s) << endl; BOOST_REQUIRE(d.check(true)); - BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); - BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); + BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s)); + BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s)); for (auto const& i: s) { (void)i; @@ -405,8 +434,8 @@ BOOST_AUTO_TEST_CASE(moreTrieTests) BOOST_REQUIRE(d.check(true)); BOOST_REQUIRE(t.at(a).empty()); BOOST_REQUIRE(d.at(string(a)).empty()); - BOOST_REQUIRE_EQUAL(t.hash256(), hash256(s)); - BOOST_REQUIRE_EQUAL(d.root(), hash256(s)); + BOOST_REQUIRE_EQUAL(t.hash256(), stringMapHash256(s)); + BOOST_REQUIRE_EQUAL(d.root(), stringMapHash256(s)); for (auto const& i: s) { (void)i; @@ -477,7 +506,6 @@ BOOST_AUTO_TEST_CASE(trieLowerBound) BOOST_AUTO_TEST_CASE(trieStess) { cnote << "Stress-testing Trie..."; - if (0) { MemoryDB m; MemoryDB dm; @@ -496,8 +524,8 @@ BOOST_AUTO_TEST_CASE(trieStess) m[k] = v; t.insert(k, v); d.insert(k, v); - BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); - BOOST_REQUIRE_EQUAL(hash256(m), d.root()); + BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256()); + BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root()); BOOST_REQUIRE(d.check(true)); } while (!m.empty()) @@ -541,13 +569,60 @@ BOOST_AUTO_TEST_CASE(trieStess) cwarn << "Good?" << d2.root(); } BOOST_REQUIRE(d.check(true)); - BOOST_REQUIRE_EQUAL(hash256(m), t.hash256()); - BOOST_REQUIRE_EQUAL(hash256(m), d.root()); + BOOST_REQUIRE_EQUAL(stringMapHash256(m), t.hash256()); + BOOST_REQUIRE_EQUAL(stringMapHash256(m), d.root()); } } } } +template void perfTestTrie(char const* _name) +{ + for (size_t p = 1000; p != 1000000; p*=10) + { + MemoryDB dm; + Trie d(&dm); + d.init(); + cnote << "TriePerf " << _name << p; + std::vector keys(1000); + boost::timer t; + size_t ki = 0; + for (size_t i = 0; i < p; ++i) + { + auto k = h256::random(); + auto v = toString(i); + d.insert(k, v); + + if (i % (p / 1000) == 0) + keys[ki++] = k; + } + cnote << "Insert " << p << "values: " << t.elapsed(); + t.restart(); + for (auto k: keys) + d.at(k); + cnote << "Query 1000 values: " << t.elapsed(); + t.restart(); + size_t i = 0; + for (auto it = d.begin(); i < 1000 && it != d.end(); ++it, ++i) + *it; + cnote << "Iterate 1000 values: " << t.elapsed(); + t.restart(); + for (auto k: keys) + d.remove(k); + cnote << "Remove 1000 values:" << t.elapsed() << "\n"; + } +} + +BOOST_AUTO_TEST_CASE(triePerf) +{ + if (test::Options::get().performance) + { + perfTestTrie, h256>>("GenericTrieDB"); + perfTestTrie, h256>>("HashedGenericTrieDB"); + perfTestTrie, h256>>("FatGenericTrieDB"); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libethcore/dagger.cpp b/test/libethcore/dagger.cpp index 4faf0a283..59770373d 100644 --- a/test/libethcore/dagger.cpp +++ b/test/libethcore/dagger.cpp @@ -63,14 +63,14 @@ BOOST_AUTO_TEST_CASE(basic_test) unsigned cacheSize(o["cache_size"].get_int()); h256 cacheHash(o["cache_hash"].get_str()); - BOOST_REQUIRE_EQUAL(EthashAux::get()->light(header)->size, cacheSize); - BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->light(header)->data()), cacheHash); + BOOST_REQUIRE_EQUAL(EthashAux::get()->light(header.seedHash())->size, cacheSize); + BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->light(header.seedHash())->data()), cacheHash); #if TEST_FULL unsigned fullSize(o["full_size"].get_int()); h256 fullHash(o["full_hash"].get_str()); - BOOST_REQUIRE_EQUAL(EthashAux::get()->full(header)->size(), fullSize); - BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->full(header)->data()), fullHash); + BOOST_REQUIRE_EQUAL(EthashAux::get()->full(header.seedHash())->size(), fullSize); + BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->full(header.seedHash())->data()), fullHash); #endif h256 result(o["result"].get_str()); diff --git a/test/libethereum/BlockTestsFiller/bcUncleTestFiller.json b/test/libethereum/BlockTestsFiller/bcUncleTestFiller.json index e67cfeecd..aeb372f67 100644 --- a/test/libethereum/BlockTestsFiller/bcUncleTestFiller.json +++ b/test/libethereum/BlockTestsFiller/bcUncleTestFiller.json @@ -103,7 +103,588 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "30" + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "nonce" : "3" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "0", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + } + ] + }, + + "oneUncle" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "30" + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "nonce" : "3" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "2", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + } + ] + }, + + "uncleWithSameBlockNumber" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20" + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "nonce" : "2" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "3", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + } + ] + } + ] + }, + + "InChainUncle" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20" + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "nonce" : "2" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", + "difficulty" : "131072", + "extraData" : "0x", + "gasLimit" : "3141592", + "gasUsed" : "0", + "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", + "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", + "nonce" : "18a524c1790fa83b", + "number" : "2", + "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", + "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", + "timestamp" : "0x54c98c82", + "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + { + "sameAsBlock" : "1" + } + ] + } + ] + }, + + + "InChainUncleFather" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20" + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "nonce" : "2" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "sameAsBlock" : "2" + } + ] + } + ] + }, + + "InChainUncleGrandPa" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20" + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "nonce" : "2" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "sameAsBlock" : "1" + } + ] + } + ] + }, + + + "InChainUncleGreatGrandPa" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "30" }, @@ -163,30 +744,30 @@ } ], "uncleHeaders" : [ + ] + }, + { + "transactions" : [ { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "3141592", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "0", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "sameAsBlock" : "1" } ] } ] }, - "oneUncle" : { + "InChainUncleGreatGreatGrandPa" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", @@ -204,12 +785,12 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "30" + "balance" : "40" }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "nonce" : "3" + "nonce" : "4" } }, "pre" : { @@ -264,30 +845,45 @@ } ], "uncleHeaders" : [ + ] + }, + { + "transactions" : [ { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "3141592", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "2", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "4", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "sameAsBlock" : "1" } ] } ] }, - "uncleWithSameBlockNumber" : { + "InChainUncleGreatGreatGreatGrandPa" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", @@ -305,12 +901,12 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20" + "balance" : "50" }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "nonce" : "2" + "nonce" : "5" } }, "pre" : { @@ -365,30 +961,60 @@ } ], "uncleHeaders" : [ + ] + }, + { + "transactions" : [ { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "3141592", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "3", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "4", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "5", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + { + "sameAsBlock" : "1" } ] } ] }, - "InChainUncle" : { + "InChainUncleGreatGreatGreatGreatGrandPa" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", @@ -406,12 +1032,12 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20" + "balance" : "60" }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "nonce" : "2" + "nonce" : "6" } }, "pre" : { @@ -466,24 +1092,66 @@ } ], "uncleHeaders" : [ + ] + }, + { + "transactions" : [ { - "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase" : "bcde5374fce5edbc8e2a8697c15331677e6ebf0b", - "difficulty" : "131072", - "extraData" : "0x", - "gasLimit" : "3141592", - "gasUsed" : "0", - "hash" : "9de9879b6a81d1b6c4993c63c90a3c9d1e775f14572694778e828bc64972ae04", - "mixHash" : "b557f905d29ed0fca99d65d0adcce698dee97cf72a13c7cd8d7a7826b8eee770", - "nonce" : "18a524c1790fa83b", - "number" : "2", - "parentHash" : "6134fc6b5d99ee03c4aab1592640f6f9dcbc850668d75d631aee34989b938fae", - "receiptTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot" : "ff640b30d613c35dad43e3693329e1b1ee6350f989cf46a288025a1cbfdab9cd", - "timestamp" : "0x54c98c82", - "transactionsTrie" : "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash" : "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "4", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "5", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + }, + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "314159", + "gasPrice" : "1", + "nonce" : "6", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ { "sameAsBlock" : "1" } @@ -510,7 +1178,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20" }, @@ -614,7 +1282,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "30" }, @@ -739,7 +1407,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "20" }, @@ -876,7 +1544,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "40" }, @@ -995,7 +1663,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "50" }, @@ -1129,7 +1797,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "60" }, @@ -1278,7 +1946,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "70" }, @@ -1442,7 +2110,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "80" }, @@ -1621,7 +2289,7 @@ "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, - "expect" : { + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "balance" : "80" }, diff --git a/test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json b/test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json index dc18fb2ca..2dbbb5032 100644 --- a/test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json +++ b/test/libethereum/BlockTestsFiller/bcValidBlockTestFiller.json @@ -122,8 +122,8 @@ "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" }, "expect" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "100" + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000" } }, "pre" : { @@ -139,8 +139,8 @@ "transactions" : [ { "data" : "", - "gasLimit" : "100001", - "gasPrice" : "0", + "gasLimit" : "10000001", + "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", @@ -153,6 +153,83 @@ ] }, + "gasLimitTooHigh2" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "30" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "1", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "1", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + } + ] + }, + "SimpleTx" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -203,6 +280,96 @@ ] }, + "SimpleTx3" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "3141592", + "gasUsed" : "0", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "10" + }, + "000000000000000000000000000b9331677e6ebf" : { + "balance" : "10" + }, + "b94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "31bb58672e8bf7684108feeacf424ab62b873824" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "fa7f04899691becd07dd3081d0a2f3ee7640af52" : { + "balance" : "10000000000", + "nonce" : "3", + "code" : "", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "50000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x00", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", + "to" : "000000000000000000000000000b9331677e6ebf", + "v" : "0x1c", + "value" : "0x0a" + }, + { + "data" : "0x", + "gasLimit" : "0x5208", + "gasPrice" : "0x01", + "nonce" : "0x03", + "r" : "0x98ff921201554726367d2be8c804a7ff89ccf285ebc57dff8ae4c44b9c19ac4a", + "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3", + "to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "v" : "0x1c", + "value" : "0x0a" + } + ], + "uncleHeaders" : [ + ] + } + ] + }, + "txOrder" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", diff --git a/test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json b/test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json index d75439f78..682b0cb3e 100644 --- a/test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json +++ b/test/libethereum/StateTestsFiller/stCallCreateCallCodeTestFiller.json @@ -787,5 +787,243 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "0x60406103ca600439600451602451336000819055506000600481905550816001819055508060028190555042600581905550336003819055505050610381806100496000396000f30060003560e060020a9004806343d726d61461004257806391b7f5ed14610050578063d686f9ee14610061578063f5bade661461006f578063fcfff16f1461008057005b61004a6101de565b60006000f35b61005b6004356100bf565b60006000f35b610069610304565b60006000f35b61007a60043561008e565b60006000f35b6100886100f0565b60006000f35b600054600160a060020a031633600160a060020a031614156100af576100b4565b6100bc565b806001819055505b50565b600054600160a060020a031633600160a060020a031614156100e0576100e5565b6100ed565b806002819055505b50565b600054600160a060020a031633600160a060020a031614806101255750600354600160a060020a031633600160a060020a0316145b61012e57610161565b60016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a16101dc565b60045460011480610173575060015434105b6101b85760016004819055507f59ebeb90bc63057b6515673c3ecf9438e5058bca0f92585014eced636878c9a560006000a142600581905550336003819055506101db565b33600160a060020a03166000346000600060006000848787f16101d757005b5050505b5b565b60006004546000146101ef576101f4565b610301565b600054600160a060020a031633600160a060020a031614801561022c5750600054600160a060020a0316600354600160a060020a0316145b61023557610242565b6000600481905550610301565b600354600160a060020a031633600160a060020a03161461026257610300565b600554420360025402905060015481116102c757600354600160a060020a0316600082600154036000600060006000848787f161029b57005b505050600054600160a060020a03166000826000600060006000848787f16102bf57005b5050506102ee565b600054600160a060020a031660006001546000600060006000848787f16102ea57005b5050505b60006004819055506000546003819055505b5b50565b6000600054600160a060020a031633600160a060020a031614156103275761032c565b61037e565b600554420360025402905060015481116103455761037d565b600054600160a060020a031660006001546000600060006000848787f161036857005b50505060006004819055506000546003819055505b5b505600000000000000000000000000000000000000000000000000000000000000420000000000000000000000000000000000000000000000000000000000000023" } + }, + + "createInitFailStackUnderflow": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{(MSTORE8 0 0x01 ) (SUICIDE (CREATE 1 0 1)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createInitFailUndefinedInstruction": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{(MSTORE8 0 0xf4 ) (SUICIDE (CREATE 1 0 1)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createInitFailBadJumpDestination": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{(MSTORE8 0 0x56 ) (SUICIDE (CREATE 1 0 1)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createInitFail_OOGduringInit": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{(MSTORE8 0 0x5a ) (SUICIDE (CREATE 1 0 1)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "53021", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createInitFailStackSizeLargerThan1024": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{(MSTORE 0 0x6103ff6000525b7f0102030405060708090a0102030405060708090a01020304) (MSTORE 32 0x05060708090a0102600160005103600052600051600657000000000000000000 ) (SUICIDE (CREATE 1 0 64)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "100000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createFailBalanceTooLow": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{(MSTORE8 0 0x5a ) (SUICIDE (CREATE 1000000000000000024 0 1)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "53021", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "23", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "createInitOOGforCREATE": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{(MSTORE8 0 0x5a ) (SUICIDE (CREATE 1 0 1)) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "53020", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } } } diff --git a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json index 69e2456fb..87e6df3cf 100644 --- a/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json +++ b/test/libethereum/StateTestsFiller/stPreCompiledContractsFiller.json @@ -1,14 +1,14 @@ { "CallEcrecover0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", @@ -16,14 +16,14 @@ "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "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": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "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" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -40,18 +40,18 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover0_overlappingInputOutput": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", @@ -59,14 +59,14 @@ "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "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": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "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" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -83,33 +83,33 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover0_completeReturnValue": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "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": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "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" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -126,18 +126,18 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover0_gas3000": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", @@ -145,14 +145,14 @@ "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 3000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -169,30 +169,30 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover0_BonusGas": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 0 1 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 0 1 1 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -209,30 +209,30 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover0_Gas2999": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 2999 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 64 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 96 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 2999 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -249,31 +249,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover0_0input": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code": "{ [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ [[ 2 ]] (CALL 300000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) }", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -290,31 +290,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover1": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (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)) }", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 1) (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)) }", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -331,31 +331,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c) (MSTORE 32 28) (MSTORE 33 0x73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f) (MSTORE 65 0xeeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549) [[ 2 ]] (CALL 100000 1 0 0 97 97 32) [[ 0 ]] (MOD (MLOAD 97) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -372,32 +372,32 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallEcrecover3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xe4319f4b631c6d0fcfc84045dbcb676865fe5e13", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code": "{ (MSTORE 0 0x2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9) (MSTORE 32 27) (MSTORE 64 0x6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a) (MSTORE 96 0x37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4) [[ 2 ]] (CALL 100000 1 0 0 128 128 32) [[ 0 ]] (MOD (MLOAD 128) (EXP 2 160)) [[ 1 ]] (EQ (ORIGIN) (SLOAD 0)) }", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -414,31 +414,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "0x600160005260206000602060006000600260fff1600051600055", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "0x600160005260206000602060006000600260fff1600051600055", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -455,32 +455,32 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_1": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALL 500 2 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -497,18 +497,18 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_1_nonzeroValue": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "100000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "0000000000000000000000000000000000000002" : { "balance" : "19" }, @@ -518,14 +518,14 @@ "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "200000000", - "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "200000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALL 200000 2 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -542,32 +542,32 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -584,32 +584,32 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 2 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -626,32 +626,32 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_4": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -668,32 +668,32 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_4_gas99": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 99 2 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -710,31 +710,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallSha256_5": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 2 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -751,31 +751,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallRipemd160_0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "0x600160005260206000602060006000600360fff1600051600055", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "0x600160005260206000602060006000600360fff1600051600055", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -792,32 +792,32 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallRipemd160_1": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0x9c1185a5c5e9fc54612808977ee8f548b2258d31", "0x02" : "0x01" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ [[ 2 ]] (CALL 600 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALL 600 3 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -834,30 +834,30 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallRipemd160_2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 600 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 5 0xf34578907f) [[ 2 ]] (CALL 600 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -874,31 +874,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallRipemd160_3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xf34578907f" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 600 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 600 3 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -915,31 +915,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallRipemd160_4": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 120 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 120 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -956,31 +956,31 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallRipemd160_4_gas99": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 119 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 119 3 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -997,31 +997,410 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - }, + }, "CallRipemd160_5": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expect" : { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "10000000", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentitiy_0": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0000000000000000000000000000000000000000000000000000000000000001" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "0x600160005260206000602060006000600460fff1600051600055", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentitiy_1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALL 500 4 0 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentity_1_nonzeroValue": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "100000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "0000000000000000000000000000000000000004" : { + "balance" : "19" + }, + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x00", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "200000000", + "nonce" : "0", + "code" : "{ [[ 2 ]] (CALL 200000 4 0x13 0 0 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentity_2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x000000000000000000000000000000000000000000000000000000f34578907f", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentity_3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0x000000000000000000000000000000000000000000000000000000f34578907f", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xf34578907f) [[ 2 ]] (CALL 500 4 0 0 37 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentity_4": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 100 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentity_4_gas18": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x02" : "0x01" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 18 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentity_4_gas17": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "storage" : { + "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x02" : "0x00" + } + } + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 17 4 0 0 32 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + } + }, + "transaction" : { + "nonce" : "0", + "gasPrice" : "1", + "gasLimit" : "365224", + "to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value" : "100000", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data" : "" + } + }, + + "CallIdentity_5": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "10000000", + "currentDifficulty" : "256", + "currentTimestamp" : 1, + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { "storage" : { "0x" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" } } - }, - "pre" : { - "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { - "balance" : "20000000", - "nonce" : "0", - "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 3 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", - "storage": {} - }, + }, + "pre" : { + "095e7baea6a6c7c4c2dfeb977efac326af552d87" : { + "balance" : "20000000", + "nonce" : "0", + "code" : "{ (MSTORE 0 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) [[ 2 ]] (CALL 600 4 0 0 1000000 0 32) [[ 0 ]] (MLOAD 0)}", + "storage": {} + }, "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { "balance" : "1000000000000000000", "nonce" : "0", @@ -1038,6 +1417,6 @@ "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data" : "" } - } + } } diff --git a/test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json b/test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json index 25a909d9c..acaccbeb2 100644 --- a/test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json +++ b/test/libethereum/StateTestsFiller/stRecursiveCreateFiller.json @@ -31,5 +31,39 @@ "secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", "data": "" } - } + }, + + "recursiveCreateReturnValue": { + "env": { + "previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber": "0", + "currentGasLimit": "10000000000", + "currentDifficulty": "256", + "currentTimestamp": 1, + "currentCoinbase": "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre": { + "095e7baea6a6c7c4c2dfeb977efac326af552d87": { + "balance": "20000000", + "nonce" : "0", + "code": "{(CODECOPY 0 0 32) [[ 0 ]] (ADD (CREATE 0 0 32) 1) }", + "storage": {} + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "1000000000000000000", + "nonce" : "0", + "code": "", + "storage": {} + } + }, + "transaction": { + "nonce": "0", + "gasPrice": "1", + "gasLimit": "1000000000", + "to": "095e7baea6a6c7c4c2dfeb977efac326af552d87", + "value": "100000", + "secretKey": "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "data": "" + } + } } diff --git a/test/libethereum/StateTestsFiller/stSolidityTestFiller.json b/test/libethereum/StateTestsFiller/stSolidityTestFiller.json index a4243c8dd..7ee5db0c3 100644 --- a/test/libethereum/StateTestsFiller/stSolidityTestFiller.json +++ b/test/libethereum/StateTestsFiller/stSolidityTestFiller.json @@ -47,16 +47,16 @@ "//" : " function testInheretance() returns (bool res) ", "//" : " { ", "//" : " res = true; ", - "//" : " base contract1; ", + "//" : " base contract1 = new base(); ", "//" : " if (contract1.methodA() != 1) ", "//" : " return false; ", "//" : " ", - "//" : " frombase contract2; ", + "//" : " frombase contract2 = new frombase(); ", "//" : " if (contract2.methodA() != 2) ", "//" : " return false; ", "//" : " } ", "//" : "} ", - "code" : "0x6000357c0100000000000000000000000000000000000000000000000000000000900480633e0bca3b1461003a578063c04062261461004c57005b610042610099565b8060005260206000f35b61005461005e565b8060005260206000f35b6000610068610099565b600060006101000a81548160ff02191690830217905550600060009054906101000a900460ff169050610096565b90565b60006000600060019250825060018273ffffffffffffffffffffffffffffffffffffffff166381bda09b60206000827c010000000000000000000000000000000000000000000000000000000002600052600460006000866161da5a03f16100fd57005b505060005163ffffffff1614156101135761011c565b60009250610194565b60028173ffffffffffffffffffffffffffffffffffffffff166381bda09b60206000827c010000000000000000000000000000000000000000000000000000000002600052600460006000866161da5a03f161017457005b505060005163ffffffff16141561018a57610193565b60009250610194565b5b50509056", + "code" : "0x7c010000000000000000000000000000000000000000000000000000000060003504633e0bca3b8114610039578063c0406226146100a857005b6100b55b600160008060456101ec8339604560006000f091508173ffffffffffffffffffffffffffffffffffffffff166381bda09b60206000827c010000000000000000000000000000000000000000000000000000000002600052600460006000866161da5a03f161011957005b6100bf60006100c961003d565b8060005260206000f35b8060005260206000f35b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016919091179081905560ff16919050565b505060005163ffffffff166002141561019d575b5b505090565b505060005163ffffffff1660011415610194575b60456101a7600039604560006000f090508073ffffffffffffffffffffffffffffffffffffffff166381bda09b60206000827c010000000000000000000000000000000000000000000000000000000002600052600460006000866161da5a03f16100ff57005b60009250610114565b600092506101145600603980600c6000396000f3007c0100000000000000000000000000000000000000000000000000000000600035046381bda09b8114602d57005b60026000818152602090f3603980600c6000396000f3007c0100000000000000000000000000000000000000000000000000000000600035046381bda09b8114602d57005b60016000818152602090f3", "nonce" : "0", "storage" : { } diff --git a/test/libethereum/blockchain.cpp b/test/libethereum/blockchain.cpp index c5ac936fe..4e98b4036 100644 --- a/test/libethereum/blockchain.cpp +++ b/test/libethereum/blockchain.cpp @@ -21,7 +21,7 @@ */ #include -#include +#include #include #include #include @@ -204,6 +204,20 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) blObj["transactions"] = writeTransactionsToJson(txList); BlockInfo current_BlockHeader = state.info(); + + RLPStream uncleStream; + uncleStream.appendList(vBiUncles.size()); + for (unsigned i = 0; i < vBiUncles.size(); ++i) + { + RLPStream uncleRlp; + vBiUncles[i].streamRLP(uncleRlp, WithNonce); + uncleStream.appendRaw(uncleRlp.out()); + } + + // update unclehash in case of invalid uncles + current_BlockHeader.sha3Uncles = sha3(uncleStream.out()); + updatePoW(current_BlockHeader); + if (blObj.count("blockHeader")) overwriteBlockHeader(current_BlockHeader, blObj); @@ -223,15 +237,6 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) txStream.appendRaw(txrlp.out()); } - RLPStream uncleStream; - uncleStream.appendList(vBiUncles.size()); - for (unsigned i = 0; i < vBiUncles.size(); ++i) - { - RLPStream uncleRlp; - vBiUncles[i].streamRLP(uncleRlp, WithNonce); - uncleStream.appendRaw(uncleRlp.out()); - } - RLPStream block2 = createFullBlockFromHeader(current_BlockHeader, txStream.out(), uncleStream.out()); blObj["rlp"] = toHex(block2.out(), 2, HexPrefix::Add); @@ -497,14 +502,20 @@ mArray importUncles(mObject const& blObj, vector& vBiUncles, vector #include #include -#include +#include #include #include "../TestHelper.h" using namespace std; diff --git a/test/libethereum/transaction.cpp b/test/libethereum/transaction.cpp index 058d03322..017e51ded 100644 --- a/test/libethereum/transaction.cpp +++ b/test/libethereum/transaction.cpp @@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(ttCreateTest) BOOST_AUTO_TEST_CASE(userDefinedFile) { - dev::test::userDefinedTest("--singletest", dev::test::doTransactionTests); + dev::test::userDefinedTest(dev::test::doTransactionTests); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libevm/VMTestsFiller/vmArithmeticTestFiller.json b/test/libevm/VMTestsFiller/vmArithmeticTestFiller.json index c06a429e0..72c90e912 100644 --- a/test/libevm/VMTestsFiller/vmArithmeticTestFiller.json +++ b/test/libevm/VMTestsFiller/vmArithmeticTestFiller.json @@ -728,6 +728,41 @@ "gas" : "100000" } }, + + "divByZero_2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "storage" : { + "0x" : "0x00" + } + } + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (+ (/ 13 0) 7)}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, "div1": { "env" : { @@ -974,6 +1009,34 @@ } }, + "sdivByZero2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (+ (SDIV (- 0 115792089237316195423570985008687907853269984665640564039457584007900129639935) 0) 1) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "sdiv0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -1639,6 +1702,34 @@ } }, + "modByZero": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (- (% 3 0) 1) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "smod0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -1873,7 +1964,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "100000" } }, @@ -1912,6 +2003,104 @@ } }, + "smod8_byZero": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (- (SMOD (- 0 200) 0) 13)}", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + + "smod_i256min1": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "storage" : { + "0x" : "0x8000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (SMOD (- 0 57896044618658097711785492504343953926634992332820282019728792003956564819968) (- 0 1) ) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + + "smod_i256min2": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "expect" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "storage" : { + "0x" : "0x8000000000000000000000000000000000000000000000000000000000000000" + } + } + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (- (SMOD (- 0 57896044618658097711785492504343953926634992332820282019728792003956564819968) (- 0 1) ) 1) }", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "addmod0": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", @@ -2006,7 +2195,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "1000000" } }, @@ -2104,7 +2293,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "1000000" } }, @@ -2132,7 +2321,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "1000000" } }, @@ -2416,6 +2605,34 @@ } }, + "addmodDivByZero3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (- (ADDMOD 0 0 0) 1) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "mulmod0": { "env" : { @@ -2546,7 +2763,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "1000000" } }, @@ -2574,7 +2791,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "1000000" } }, @@ -2602,7 +2819,7 @@ "value" : "1000000000000000000", "data" : "", "gasPrice" : "100000000000000", - "gas" : "10000" + "gas" : "1000000" } }, @@ -2921,6 +3138,34 @@ } }, + "mulmoddivByZero3": { + "env" : { + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", + "currentNumber" : "0", + "currentGasLimit" : "1000000", + "currentDifficulty" : "256", + "currentTimestamp" : "1", + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" + }, + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "nonce" : "0", + "code" : "{ [[ 0 ]] (- 1 (MULMOD 0 0 0)) } ", + "storage": {} + } + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "origin" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "caller" : "cd1722f2947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000", + "data" : "", + "gasPrice" : "100000000000000", + "gas" : "100000" + } + }, + "expXY": { "env" : { "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp index a0d8f8d43..d00396472 100644 --- a/test/libevm/vm.cpp +++ b/test/libevm/vm.cpp @@ -44,13 +44,10 @@ h160 FakeExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _init, OnOpF return na; } -bool FakeExtVM::call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256& io_gas, bytesRef _out, OnOpFunc const&, Address _myAddressOverride, Address _codeAddressOverride) +bool FakeExtVM::call(CallParameters& _p) { - Transaction t(_value, gasPrice, io_gas, _receiveAddress, _data.toVector()); + Transaction t(_p.value, gasPrice, _p.gas, _p.receiveAddress, _p.data.toVector()); callcreates.push_back(t); - (void)_out; - (void)_myAddressOverride; - (void)_codeAddressOverride; return true; } @@ -300,9 +297,14 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) { for (auto& i: v.get_obj()) { - std::cout << " " << i.first << "\n"; mObject& o = i.second.get_obj(); + if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) + { + o.clear(); + continue; + } + std::cout << " " << i.first << "\n"; BOOST_REQUIRE(o.count("env") > 0); BOOST_REQUIRE(o.count("pre") > 0); BOOST_REQUIRE(o.count("exec") > 0); @@ -430,7 +432,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin) } } -} } // Namespace Close +} } // namespace close BOOST_AUTO_TEST_SUITE(VMTests) @@ -540,7 +542,7 @@ BOOST_AUTO_TEST_CASE(vmRandom) BOOST_AUTO_TEST_CASE(userDefinedFile) { - dev::test::userDefinedTest("--singletest", dev::test::doVMTests); + dev::test::userDefinedTest(dev::test::doVMTests); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libevm/vm.h b/test/libevm/vm.h index dff89d98d..18fa1ca25 100644 --- a/test/libevm/vm.h +++ b/test/libevm/vm.h @@ -59,7 +59,7 @@ public: virtual void suicide(Address _a) override { std::get<0>(addresses[_a]) += std::get<0>(addresses[myAddress]); addresses.erase(myAddress); } virtual bytes const& codeAt(Address _a) override { return std::get<3>(addresses[_a]); } virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _init, eth::OnOpFunc const&) override; - virtual bool call(Address _receiveAddress, u256 _value, bytesConstRef _data, u256& io_gas, bytesRef _out, eth::OnOpFunc const&, Address, Address) override; + virtual bool call(eth::CallParameters&) override; void setTransaction(Address _caller, u256 _value, u256 _gasPrice, bytes const& _data); void setContract(Address _myAddress, u256 _myBalance, u256 _myNonce, std::map const& _storage, bytes const& _code); void set(Address _a, u256 _myBalance, u256 _myNonce, std::map const& _storage, bytes const& _code); diff --git a/test/libp2p/capability.cpp b/test/libp2p/capability.cpp new file mode 100644 index 000000000..2c158f4d8 --- /dev/null +++ b/test/libp2p/capability.cpp @@ -0,0 +1,150 @@ +/* +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 capability.cpp +* @author Vladislav Gluhovsky +* @date May 2015 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::p2p; + +struct P2PFixture +{ + P2PFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = true; } + ~P2PFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = false; } +}; + +struct VerbosityHolder +{ + VerbosityHolder(): oldLogVerbosity(g_logVerbosity) { g_logVerbosity = 10; } + ~VerbosityHolder() { g_logVerbosity = oldLogVerbosity; } + + int oldLogVerbosity; +}; + +class TestCapability: public Capability +{ +public: + TestCapability(Session* _s, HostCapabilityFace* _h, unsigned _idOffset): Capability(_s, _h, _idOffset), m_cntReceivedMessages(0), m_testSum(0) {} + virtual ~TestCapability() {} + int countReceivedMessages() { return m_cntReceivedMessages; } + int testSum() { return m_testSum; } + static std::string name() { return "test"; } + static u256 version() { return 2; } + static unsigned messageCount() { return UserPacket + 1; } + void sendTestMessage(int _i) { RLPStream s; sealAndSend(prep(s, UserPacket, 1) << _i); } + +protected: + virtual bool interpret(unsigned _id, RLP const& _r) override; + + int m_cntReceivedMessages; + int m_testSum; +}; + +bool TestCapability::interpret(unsigned _id, RLP const& _r) +{ + cnote << "Capability::interpret(): custom message received"; + ++m_cntReceivedMessages; + m_testSum += _r[0].toInt(); + BOOST_ASSERT(_id == UserPacket); + return (_id == UserPacket); +} + +class TestHostCapability: public HostCapability, public Worker +{ +public: + TestHostCapability(): Worker("test") {} + virtual ~TestHostCapability() {} + + void sendTestMessage(NodeId const& _id, int _x) + { + for (auto i: peerSessions()) + if (_id == i.second->id) + i.first->cap().get()->sendTestMessage(_x); + } + + std::pair retrieveTestData(NodeId const& _id) + { + int cnt = 0; + int checksum = 0; + for (auto i: peerSessions()) + if (_id == i.second->id) + { + cnt += i.first->cap().get()->countReceivedMessages(); + checksum += i.first->cap().get()->testSum(); + } + + return std::pair(cnt, checksum); + } +}; + +BOOST_FIXTURE_TEST_SUITE(p2pCapability, P2PFixture) + +BOOST_AUTO_TEST_CASE(capability) +{ + VerbosityHolder verbosityHolder; + cnote << "Testing Capability..."; + + const char* const localhost = "127.0.0.1"; + NetworkPreferences prefs1(localhost, 30301, false); + NetworkPreferences prefs2(localhost, 30302, false); + + Host host1("Test", prefs1); + auto thc1 = host1.registerCapability(new TestHostCapability()); + host1.start(); + + Host host2("Test", prefs2); + auto thc2 = host2.registerCapability(new TestHostCapability()); + host2.start(); + + int const step = 10; + + for (int i = 0; i < 3000 && (!host1.isStarted() || !host2.isStarted()); i += step) + this_thread::sleep_for(chrono::milliseconds(step)); + + BOOST_REQUIRE(host1.isStarted() && host2.isStarted()); + host1.requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string(localhost), prefs2.listenPort, prefs2.listenPort)); + + for (int i = 0; i < 3000 && (!host1.peerCount() || !host2.peerCount()); i += step) + this_thread::sleep_for(chrono::milliseconds(step)); + + BOOST_REQUIRE(host1.peerCount() > 0 && host2.peerCount() > 0); + + int const target = 7; + int checksum = 0; + for (int i = 0; i < target; checksum += i++) + thc2->sendTestMessage(host1.id(), i); + + this_thread::sleep_for(chrono::seconds(1)); + std::pair testData = thc1->retrieveTestData(host2.id()); + BOOST_REQUIRE_EQUAL(target, testData.first); + BOOST_REQUIRE_EQUAL(checksum, testData.second); +} + +BOOST_AUTO_TEST_SUITE_END() + + diff --git a/test/libp2p/net.cpp b/test/libp2p/net.cpp index a95e685c7..1cd43b13f 100644 --- a/test/libp2p/net.cpp +++ b/test/libp2p/net.cpp @@ -99,7 +99,7 @@ struct TestNodeTable: public NodeTable // manually add node for test { Guard ln(x_nodes); - shared_ptr node(new NodeEntry(m_node, n.first.pub(), NodeIPEndpoint(ourIp, n.second, n.second))); + shared_ptr node(new NodeEntry(m_node.id, n.first.pub(), NodeIPEndpoint(ourIp, n.second, n.second))); node->pending = false; m_nodes[node->id] = node; } diff --git a/test/libp2p/rlpx.cpp b/test/libp2p/rlpx.cpp index 6a86652fb..620ddd952 100644 --- a/test/libp2p/rlpx.cpp +++ b/test/libp2p/rlpx.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/test/libsolidity/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp index aa83c4650..dda7847ed 100644 --- a/test/libsolidity/SolidityCompiler.cpp +++ b/test/libsolidity/SolidityCompiler.cpp @@ -116,36 +116,35 @@ BOOST_AUTO_TEST_CASE(ifStatement) bytes code = compileContract(sourceCode); unsigned shift = 60; unsigned boilerplateSize = 73; - bytes expectation({byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x0, - byte(Instruction::DUP1), - byte(Instruction::PUSH1), byte(0x1b + shift), // "true" target - byte(Instruction::JUMPI), - // new check "else if" condition - byte(Instruction::DUP1), - byte(Instruction::ISZERO), - byte(Instruction::PUSH1), byte(0x13 + shift), - byte(Instruction::JUMPI), - // "else" body - byte(Instruction::PUSH1), 0x4f, - byte(Instruction::POP), - byte(Instruction::PUSH1), byte(0x17 + shift), // exit path of second part - byte(Instruction::JUMP), - // "else if" body - byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x4e, - byte(Instruction::POP), - byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), byte(0x1f + shift), - byte(Instruction::JUMP), - // "if" body - byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x4d, - byte(Instruction::POP), - byte(Instruction::JUMPDEST), - byte(Instruction::JUMPDEST), - byte(Instruction::POP), - byte(Instruction::JUMP)}); + bytes expectation({ + byte(Instruction::JUMPDEST), + byte(Instruction::PUSH1), 0x0, + byte(Instruction::DUP1), + byte(Instruction::ISZERO), + byte(Instruction::PUSH1), byte(0x0f + shift), // "false" target + byte(Instruction::JUMPI), + // "if" body + byte(Instruction::PUSH1), 0x4d, + byte(Instruction::POP), + byte(Instruction::PUSH1), byte(0x21 + shift), + byte(Instruction::JUMP), + // new check "else if" condition + byte(Instruction::JUMPDEST), + byte(Instruction::DUP1), + byte(Instruction::ISZERO), + byte(Instruction::ISZERO), + byte(Instruction::PUSH1), byte(0x1c + shift), + byte(Instruction::JUMPI), + // "else if" body + byte(Instruction::PUSH1), 0x4e, + byte(Instruction::POP), + byte(Instruction::PUSH1), byte(0x20 + shift), + byte(Instruction::JUMP), + // "else" body + byte(Instruction::JUMPDEST), + byte(Instruction::PUSH1), 0x4f, + byte(Instruction::POP), + }); checkCodePresentAt(code, expectation, boilerplateSize); } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index ed5f1acdf..90ce20d26 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include using namespace std; @@ -1501,9 +1501,7 @@ BOOST_AUTO_TEST_CASE(sha256) compileAndRun(sourceCode); auto f = [&](u256 const& _input) -> u256 { - h256 ret; - dev::sha256(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32)); - return ret; + return dev::sha256(dev::ref(toBigEndian(_input))); }; testSolidityAgainstCpp("a(bytes32)", f, u256(4)); testSolidityAgainstCpp("a(bytes32)", f, u256(5)); @@ -1520,9 +1518,7 @@ BOOST_AUTO_TEST_CASE(ripemd) compileAndRun(sourceCode); auto f = [&](u256 const& _input) -> u256 { - h256 ret; - dev::ripemd160(dev::ref(toBigEndian(_input)), bytesRef(&ret[0], 32)); - return u256(ret); + return h256(dev::ripemd160(h256(_input).ref()), h256::AlignLeft); // This should be aligned right. i guess it's fixed elsewhere? }; testSolidityAgainstCpp("a(bytes32)", f, u256(4)); testSolidityAgainstCpp("a(bytes32)", f, u256(5)); @@ -2558,6 +2554,37 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2); } +BOOST_AUTO_TEST_CASE(generic_callcode) +{ + char const* sourceCode = R"**( + contract receiver { + uint public received; + function receive(uint256 x) { received = x; } + } + contract sender { + uint public received; + function doSend(address rec) returns (uint d) + { + bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); + rec.callcode.value(2)(signature, 23); + return receiver(rec).received(); + } + } + )**"; + compileAndRun(sourceCode, 0, "receiver"); + u160 const c_receiverAddress = m_contractAddress; + compileAndRun(sourceCode, 50, "sender"); + u160 const c_senderAddress = m_contractAddress; + BOOST_CHECK(callContractFunction("doSend(address)", c_receiverAddress) == encodeArgs(0)); + BOOST_CHECK(callContractFunction("received()") == encodeArgs(23)); + m_contractAddress = c_receiverAddress; + BOOST_CHECK(callContractFunction("received()") == encodeArgs(0)); + BOOST_CHECK(m_state.storage(c_receiverAddress).empty()); + BOOST_CHECK(!m_state.storage(c_senderAddress).empty()); + BOOST_CHECK_EQUAL(m_state.balance(c_receiverAddress), 0); + BOOST_CHECK_EQUAL(m_state.balance(c_senderAddress), 50); +} + BOOST_AUTO_TEST_CASE(store_bytes) { // this test just checks that the copy loop does not mess up the stack diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 4ec7b8bda..c52bbf9de 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 3cb6a536a..744fc48ae 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -29,6 +29,7 @@ #include #include #include +#include using namespace std; using namespace dev::eth; @@ -96,7 +97,7 @@ public: { eth::KnownState state; for (auto const& item: addDummyLocations(_input)) - state.feedItem(item); + state.feedItem(item, true); return state; } @@ -125,7 +126,7 @@ public: BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); } - void checkCFG(AssemblyItems const& _input, AssemblyItems const& _expectation) + AssemblyItems getCFG(AssemblyItems const& _input) { AssemblyItems output = _input; // Running it four times should be enough for these tests. @@ -138,6 +139,12 @@ public: back_inserter(optItems)); output = move(optItems); } + return output; + } + + void checkCFG(AssemblyItems const& _input, AssemblyItems const& _expectation) + { + AssemblyItems output = getCFG(_input); BOOST_CHECK_EQUAL_COLLECTIONS(_expectation.begin(), _expectation.end(), output.begin(), output.end()); } @@ -251,6 +258,106 @@ BOOST_AUTO_TEST_CASE(function_calls) compareVersions("f(uint256)", 36); } +BOOST_AUTO_TEST_CASE(storage_write_in_loops) +{ + char const* sourceCode = R"( + contract test { + uint d; + function f(uint a) returns (uint r) { + var x = d; + for (uint i = 1; i < a * a; i++) { + r = d; + d = i; + } + + } + } + )"; + compileBothVersions(sourceCode); + compareVersions("f(uint256)", 0); + compareVersions("f(uint256)", 10); + compareVersions("f(uint256)", 36); +} + +BOOST_AUTO_TEST_CASE(retain_information_in_branches) +{ + // This tests that the optimizer knows that we already have "z == sha3(y)" inside both branches. + char const* sourceCode = R"( + contract c { + bytes32 d; + uint a; + function f(uint x, bytes32 y) returns (uint r_a, bytes32 r_d) { + bytes32 z = sha3(y); + if (x > 8) { + z = sha3(y); + a = x; + } else { + z = sha3(y); + a = x; + } + r_a = a; + r_d = d; + } + } + )"; + compileBothVersions(sourceCode); + compareVersions("f(uint256,bytes32)", 0, "abc"); + compareVersions("f(uint256,bytes32)", 8, "def"); + compareVersions("f(uint256,bytes32)", 10, "ghi"); + + m_optimize = true; + bytes optimizedBytecode = compileAndRun(sourceCode, 0, "c"); + size_t numSHA3s = 0; + eth::eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { + if (_instr == eth::Instruction::SHA3) + numSHA3s++; + }); + BOOST_CHECK_EQUAL(1, numSHA3s); +} + +BOOST_AUTO_TEST_CASE(store_tags_as_unions) +{ + // This calls the same function from two sources and both calls have a certain sha3 on + // the stack at the same position. + // Without storing tags as unions, the return from the shared function would not know where to + // jump and thus all jumpdests are forced to clear their state and we do not know about the + // sha3 anymore. + // Note that, for now, this only works if the functions have the same number of return + // parameters since otherwise, the return jump addresses are at different stack positions + // which triggers the "unknown jump target" situation. + char const* sourceCode = R"( + contract test { + bytes32 data; + function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { + r_d = sha3(y); + shared(y); + r_d = sha3(y); + r_a = 5; + } + function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { + r_d = sha3(y); + shared(y); + r_d = bytes32(uint(sha3(y)) + 2); + r_a = 7; + } + function shared(bytes32 y) internal { + data = sha3(y); + } + } + )"; + compileBothVersions(sourceCode); + compareVersions("f()", 7, "abc"); + + m_optimize = true; + bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test"); + size_t numSHA3s = 0; + eth::eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { + if (_instr == eth::Instruction::SHA3) + numSHA3s++; + }); + BOOST_CHECK_EQUAL(2, numSHA3s); +} + BOOST_AUTO_TEST_CASE(cse_intermediate_swap) { eth::KnownState state; @@ -868,6 +975,35 @@ BOOST_AUTO_TEST_CASE(control_flow_graph_do_not_remove_returned_to) checkCFG(input, {u256(2)}); } +BOOST_AUTO_TEST_CASE(block_deduplicator) +{ + AssemblyItems input{ + AssemblyItem(PushTag, 2), + AssemblyItem(PushTag, 1), + AssemblyItem(PushTag, 3), + u256(6), + eth::Instruction::SWAP3, + eth::Instruction::JUMP, + AssemblyItem(Tag, 1), + u256(6), + eth::Instruction::SWAP3, + eth::Instruction::JUMP, + AssemblyItem(Tag, 2), + u256(6), + eth::Instruction::SWAP3, + eth::Instruction::JUMP, + AssemblyItem(Tag, 3) + }; + BlockDeduplicator dedup(input); + dedup.deduplicate(); + + set pushTags; + for (AssemblyItem const& item: input) + if (item.type() == PushTag) + pushTags.insert(item.data()); + BOOST_CHECK_EQUAL(pushTags.size(), 2); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/third/MainWin.cpp b/third/MainWin.cpp index 12625ffbc..3cfc016e3 100644 --- a/third/MainWin.cpp +++ b/third/MainWin.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include #include