diff --git a/CMakeLists.txt b/CMakeLists.txt index d7e598678..6cd9e338f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,7 +203,9 @@ eth_format_option(ROCKSDB) eth_format_option(GUI) eth_format_option(TESTS) eth_format_option(NOBOOST) +eth_format_option(ROCKSDB) eth_format_option(TOOLS) +eth_format_option(ETHKEY) eth_format_option(ETHASHCL) eth_format_option(JSCONSOLE) eth_format_option_on_decent_platform(SERPENT) @@ -234,6 +236,15 @@ elseif (BUNDLE STREQUAL "full") set(TOOLS ON) set(TESTS ON) set(FATDB ON) +elseif (BUNDLE STREQUAL "cli") + set(SERPENT ${DECENT_PLATFORM}) + set(SOLIDITY ON) + set(USENPM ON) + set(GUI OFF) +# set(NCURSES ${DECENT_PLATFORM}) + set(TOOLS ON) + set(TESTS ON) + set(FATDB ON) elseif (BUNDLE STREQUAL "core") set(SERPENT OFF) set(SOLIDITY ON) @@ -312,6 +323,7 @@ message("-- Hardware identification support ${CPUID_FO message("-- HTTP Request support ${CURL_FOUND}") message("-- VMTRACE VM execution tracing ${VMTRACE}") message("-- PROFILING Profiling support ${PROFILING}") +message("-- NOBOOST No BOOST macros in test functions ${NOBOOST}") message("-- FATDB Full database exploring ${FATDB}") message("-- JSONRPC JSON-RPC support ${JSONRPC}") message("-- USENPM Javascript source building ${USENPM}") @@ -325,7 +337,6 @@ message("-- SERPENT Build Serpent language components ${SERPENT} message("-- GUI Build GUI components ${GUI}") message("-- NCURSES Build NCurses components ${NCURSES}") message("-- TESTS Build tests ${TESTS}") -message("-- NOBOOST No BOOST macros in test functions ${NOBOOST}") message("-- ETHASHCL Build OpenCL components (experimental!) ${ETHASHCL}") message("-- JSCONSOLE Build with javascript console ${JSCONSOLE}") message("-- EVMJIT Build LLVM-based JIT EVM (experimental!) ${EVMJIT}") @@ -362,8 +373,6 @@ else () set(GENERAL 0) endif () -message("GENERAL ${GENERAL}") - add_subdirectory(libdevcore) if (GENERAL) add_subdirectory(libevmcore) @@ -398,6 +407,7 @@ if (JSCONSOLE) endif () if (NOT WIN32) + add_definitions(-DETH_HAVE_SECP256K1) add_subdirectory(secp256k1) endif () diff --git a/CodingStandards.txt b/CodingStandards.txt index 66a61f6ae..a065928d3 100644 --- a/CodingStandards.txt +++ b/CodingStandards.txt @@ -196,7 +196,7 @@ a. Prefer 'using' to 'typedef'. e.g. using ints = std::vector; rather than b. Generally avoid shortening a standard form that already includes all important information: - e.g. stick to shared_ptr rather than shortening to ptr. c. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently. -- e.g. using Guard = boost::lock_guard; ///< Guard is used throughout the codebase since it's clear in meaning and used commonly. +- e.g. using Guard = std::lock_guard; ///< Guard is used throughout the codebase since it's clear in meaning and used commonly. d. In general expressions should be roughly as important/semantically meaningful as the space they occupy. @@ -226,4 +226,3 @@ a. Includes should go in order of lower level (STL -> boost -> libdevcore -> lib #include b. The only exception to the above rule is the top of a .cpp file where its corresponding header should be located. - diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index 93609e54c..8bc349fb2 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -7,6 +7,11 @@ if (${CMAKE_MAJOR_VERSION} GREATER 2) cmake_policy(SET CMP0043 OLD) endif() +if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.6") AND NOT APPLE) + # Supress warnings for qt headers for clang+ccache + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override") +endif () + set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) diff --git a/alethzero/DownloadView.cpp b/alethzero/DownloadView.cpp index 210649edb..788a106d3 100644 --- a/alethzero/DownloadView.cpp +++ b/alethzero/DownloadView.cpp @@ -30,56 +30,176 @@ using namespace std; using namespace dev; using namespace dev::eth; -DownloadView::DownloadView(QWidget* _p): QWidget(_p) +SyncView::SyncView(QWidget* _p): QWidget(_p) { } -void DownloadView::paintEvent(QPaintEvent*) +void SyncView::paintEvent(QPaintEvent*) { - QPainter p(this); + QPainter painter(this); + painter.fillRect(rect(), Qt::white); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::HighQualityAntialiasing, true); - p.fillRect(rect(), Qt::white); - if (!m_man || m_man->chainEmpty() || !m_man->subCount()) + if (!m_client || !isVisible() || !rect().width() || !rect().height()) return; - double ratio = (double)rect().width() / rect().height(); - if (ratio < 1) - ratio = 1 / ratio; - double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chainSize() / ratio))); + DownloadMan const* man = m_client->downloadMan(); + BlockQueueStatus bqs = m_client->blockQueueStatus(); + SyncStatus sync = m_client->syncStatus(); -// QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n)); - QSizeF area(n, n); - QPointF pos(0, 0); + unsigned syncFrom = m_client->numberFromHash(PendingBlockHash); + unsigned syncImported = syncFrom; + unsigned syncImporting = syncImported + bqs.importing; + unsigned syncVerified = syncImporting + bqs.verified; + unsigned syncVerifying = syncVerified + bqs.verifying; + unsigned syncUnverified = syncVerifying + bqs.unverified; + unsigned syncCount = syncUnverified + bqs.unknown - syncFrom; - 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) + // best effort guess. assumes there's no forks. + unsigned downloadFrom = sync.state == SyncState::Idle ? m_lastSyncFrom : m_client->numberFromHash(m_client->isKnown(man->firstBlock()) ? man->firstBlock() : PendingBlockHash); + unsigned downloadCount = sync.state == SyncState::Idle ? m_lastSyncCount : sync.blocksTotal; + unsigned downloadDone = downloadFrom + (sync.state == SyncState::Idle ? m_lastSyncCount : sync.blocksReceived); + unsigned downloadPoint = downloadFrom + (sync.state == SyncState::Idle ? m_lastSyncCount : man->overview().lastComplete); + + unsigned hashFrom = sync.state == SyncState::Hashes ? m_client->numberFromHash(PendingBlockHash) : downloadFrom; + unsigned hashCount = sync.state == SyncState::Hashes ? sync.hashesTotal : downloadCount; + unsigned hashDone = hashFrom + (sync.state == SyncState::Hashes ? sync.hashesReceived : hashCount); + + QString labelText = QString("PV%1").arg(sync.protocolVersion); + QColor labelBack = QColor::fromHsv(sync.protocolVersion == 60 ? 30 : sync.protocolVersion == 61 ? 120 : 240, 25, 200); + QColor labelFore = labelBack.darker(); + switch (sync.state) { - int s = -2; - if (bg.contains(i)) - s = -1; - else + case SyncState::Hashes: + if (!syncCount || !sync.hashesEstimated) + { + m_lastSyncFrom = min(hashFrom, m_lastSyncFrom); + m_lastSyncCount = max(hashFrom + hashCount, m_lastSyncFrom + m_lastSyncCount) - m_lastSyncFrom; + m_wasEstimate = sync.hashesEstimated; + } + break; + case SyncState::Blocks: + if (m_wasEstimate) + { + m_lastSyncFrom = downloadFrom; + m_lastSyncCount = downloadCount; + m_wasEstimate = false; + } + break; + case SyncState::Idle: + if (!syncCount) { - unsigned h = 0; - m_man->foreachSub([&](DownloadSub const& sub) - { - if (sub.askedContains(i)) - s = h; - h++; - }); + m_lastSyncFrom = (unsigned)-1; + m_lastSyncCount = 0; + labelBack = QColor::fromHsv(0, 0, 200); + labelFore = Qt::white; + labelText = "Idle"; } - 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) - p.fillRect(QRectF(QPointF(pos) + QPointF(1 * area.width() / 8, 1 * area.height() / 8), area * 3 / 4), Qt::black); - else - p.fillRect(QRectF(QPointF(pos) + QPointF(1 * area.width() / 8, 1 * area.height() / 8), area * 3 / 4), QColor::fromHsv(s * dh, 64, 128)); - - pos.setX(pos.x() + n); - if (pos.x() >= rect().width() - n) - pos = QPoint(0, pos.y() + n); + default: break; + } + + unsigned from = min(min(hashFrom, downloadFrom), min(syncFrom, m_lastSyncFrom)); + unsigned count = max(max(hashFrom + hashCount, downloadFrom + downloadCount), max(syncFrom + syncCount, m_lastSyncFrom + m_lastSyncCount)) - from; + +/* cnote << "Range " << from << "-" << (from + count) << "(" << hashFrom << "+" << hashCount << "," << downloadFrom << "+" << downloadCount << "," << syncFrom << "+" << syncCount << ")"; + auto r = [&](unsigned u) { + return toString((u - from) * 100 / count) + "%"; + }; + + if (count) + { + cnote << "Hashes:" << r(hashDone) << " Blocks:" << r(downloadFlank) << r(downloadDone) << r(downloadPoint); + cnote << "Importing:" << r(syncFrom) << r(syncImported) << r(syncImporting) << r(syncVerified) << r(syncVerifying) << r(syncUnverified); + } +*/ + float const squareSize = min(rect().width(), rect().height()); + auto middleRect = [&](float w, float h) { + return QRectF(rect().width() / 2 - w / 2, rect().height() / 2 - h / 2, w, h); + }; + auto middle = [&](float x) { + return middleRect(squareSize * x, squareSize * x); + }; + auto pieProgress = [&](unsigned h, unsigned s, unsigned v, float row, float thickness, unsigned nfrom, unsigned ncount) { + auto arcLen = [&](unsigned x) { + return x * -5760.f / count; + }; + auto arcPos = [&](unsigned x) { + return int(90 * 16.f + arcLen(x - from)) % 5760; + }; + painter.setPen(QPen(QColor::fromHsv(h, s, v), squareSize * thickness, Qt::SolidLine, Qt::FlatCap)); + painter.setBrush(Qt::NoBrush); + painter.drawArc(middle(0.5 + row / 2), arcPos(nfrom), arcLen(ncount)); + }; + auto pieProgress2 = [&](unsigned h, unsigned s, unsigned v, float row, float orbit, float thickness, unsigned nfrom, unsigned ncount) { + pieProgress(h, s, v, row - orbit, thickness, nfrom, ncount); + pieProgress(h, s, v, row + orbit, thickness, nfrom, ncount); + }; + auto pieLabel = [&](QString text, float points, QColor fore, QColor back) { + painter.setBrush(QBrush(back)); + painter.setFont(QFont("Helvetica", points, QFont::Bold)); + QRectF r = painter.boundingRect(middle(1.f), Qt::AlignCenter, text); + r.adjust(-r.width() / 4, -r.height() / 8, r.width() / 4, r.height() / 8); + painter.setPen(QPen(fore, r.height() / 20)); + painter.drawRoundedRect(r, r.height() / 4, r.height() / 4); + painter.drawText(r, Qt::AlignCenter, text); + }; + + float lineHeight = painter.boundingRect(rect(), Qt::AlignTop | Qt::AlignHCenter, "Ay").height(); + auto hProgress = [&](unsigned h, unsigned s, unsigned v, float row, float thickness, unsigned nfrom, unsigned ncount) { + QRectF r = rect(); + painter.setPen(QPen(QColor::fromHsv(h, s, v), r.height() * thickness * 3, Qt::SolidLine, Qt::FlatCap)); + painter.setBrush(Qt::NoBrush); + auto y = row * (r.height() - lineHeight) + lineHeight; + painter.drawLine(QPointF((nfrom - from) * r.width() / count, y), QPointF((nfrom + ncount - from) * r.width() / count, y)); + }; + auto hProgress2 = [&](unsigned h, unsigned s, unsigned v, float row, float orbit, float thickness, unsigned nfrom, unsigned ncount) { + hProgress(h, s, v, row - orbit * 3, thickness, nfrom, ncount); + hProgress(h, s, v, row + orbit * 3, thickness, nfrom, ncount); + }; + auto hLabel = [&](QString text, float points, QColor fore, QColor back) { + painter.setBrush(QBrush(back)); + painter.setFont(QFont("Helvetica", points, QFont::Bold)); + QRectF r = painter.boundingRect(rect(), Qt::AlignTop | Qt::AlignHCenter, text); + r.adjust(-r.width() / 4, r.height() / 8, r.width() / 4, 3 * r.height() / 8); + painter.setPen(QPen(fore, r.height() / 20)); + painter.drawRoundedRect(r, r.height() / 4, r.height() / 4); + painter.drawText(r, Qt::AlignCenter, text); + }; + + function progress; + function progress2; + function label; + if (rect().width() / rect().height() > 5) + { + progress = hProgress; + progress2 = hProgress2; + label = hLabel; } + else if (rect().height() / rect().width() > 5) + { + } + else + { + progress = pieProgress; + progress2 = pieProgress2; + label = pieLabel; + } + + if (sync.state != SyncState::Idle) + { + progress(0, 0, 220, 0.4f, 0.02f, from, hashDone - from); // Download rail + progress(240, 25, 170, 0.4f, 0.02f, downloadDone, downloadPoint - downloadDone); // Latest download point + progress(240, 50, 120, 0.4f, 0.04f, from, downloadDone - from); // Downloaded + } + + progress(0, 0, 220, 0.8f, 0.01f, from, count); // Sync rail + progress(0, 0, 170, 0.8f, 0.02f, from, syncUnverified - from); // Verification rail + progress2(60, 25, 170, 0.8f, 0.06f, 0.005f, from, syncVerifying - from); // Verifying. + progress2(120, 25, 170, 0.8f, 0.06f, 0.005f, from, syncVerified - from); // Verified. + progress(120, 50, 120, 0.8f, 0.05f, from, syncFrom - from); // Imported. + progress(0, 0, 120, 0.8f, 0.02f, syncFrom, syncImporting - syncFrom); // Importing. + + if (sync.state != SyncState::Idle || (sync.state == SyncState::Idle && !syncCount)) + label(labelText, 11, labelFore, labelBack); } diff --git a/alethzero/DownloadView.h b/alethzero/DownloadView.h index d0fc445f8..f3c8b1001 100644 --- a/alethzero/DownloadView.h +++ b/alethzero/DownloadView.h @@ -32,21 +32,25 @@ #endif namespace dev { namespace eth { -class DownloadMan; +class Client; }} -class DownloadView: public QWidget +class SyncView: public QWidget { Q_OBJECT public: - DownloadView(QWidget* _p = nullptr); + SyncView(QWidget* _p = nullptr); - void setDownloadMan(dev::eth::DownloadMan const* _man) { m_man = _man; } + void setEthereum(dev::eth::Client const* _c) { m_client = _c; } protected: virtual void paintEvent(QPaintEvent*); private: - dev::eth::DownloadMan const* m_man = nullptr; + dev::eth::Client const* m_client = nullptr; + + unsigned m_lastSyncFrom = (unsigned)-1; + unsigned m_lastSyncCount = 0; + bool m_wasEstimate = false; }; diff --git a/alethzero/ExportState.cpp b/alethzero/ExportState.cpp index c11132768..d975dea14 100644 --- a/alethzero/ExportState.cpp +++ b/alethzero/ExportState.cpp @@ -127,11 +127,21 @@ void ExportStateDialog::fillContracts() ui->contracts->clear(); ui->accounts->setEnabled(true); ui->contracts->setEnabled(true); - for (auto i: ethereum()->addresses(m_block)) + try { - string r = m_main->render(i); - (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts)) - ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); + for (auto i: ethereum()->addresses(m_block)) + { + string r = m_main->render(i); + (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts)) + ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); + } + } + catch (InterfaceNotSupported const&) + { + ui->accounts->setEnabled(false); + ui->contracts->setEnabled(false); + ui->json->setEnabled(false); + ui->json->setText(QString("This feature requires compilation with FATDB support.")); } } diff --git a/alethzero/Main.ui b/alethzero/Main.ui index f798437e6..97853e174 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -11,7 +11,7 @@ - AlethZero Ethereum Client + AlethZero ++Ethereum true @@ -44,14 +44,14 @@ 0 bytes used - - - - - - - - + + + + + + + + @@ -192,10 +192,14 @@ + + + + - + @@ -224,6 +228,7 @@ &Config + @@ -703,7 +708,7 @@ - + QDockWidget::DockWidgetFeatureMask @@ -1145,7 +1150,7 @@ font-size: 14pt 0 - + @@ -1696,17 +1701,6 @@ font-size: 14pt &Clear Pending - - - true - - - false - - - Use &LLVM-EVM - - &Kill Account @@ -1782,6 +1776,40 @@ font-size: 14pt &Gas Prices... + + + true + + + Interpreter + + + + + true + + + JIT + + + + + true + + + Smart + + + + + &Sentinel... + + + + + &Rewind Chain... + + @@ -1792,7 +1820,7 @@ font-size: 14pt 1 - DownloadView + SyncView QWidget
DownloadView.h
1 diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 821022abc..60c07fd8d 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -136,6 +136,12 @@ Main::Main(QWidget *parent) : QtWebEngine::initialize(); setWindowFlags(Qt::Window); ui->setupUi(this); + + if (c_network == eth::Network::Olympic) + setWindowTitle("AlethZero Olympic"); + else if (c_network == eth::Network::Frontier) + setWindowTitle("AlethZero Frontier"); + g_logPost = [=](string const& s, char const* c) { simpleDebugOut(s, c); @@ -239,18 +245,31 @@ Main::Main(QWidget *parent) : ethereum()->setDefault(LatestBlock); + m_vmSelectionGroup = new QActionGroup{ui->menu_Debug}; + m_vmSelectionGroup->addAction(ui->vmInterpreter); + m_vmSelectionGroup->addAction(ui->vmJIT); + m_vmSelectionGroup->addAction(ui->vmSmart); + m_vmSelectionGroup->setExclusive(true); + +#if ETH_EVMJIT + ui->vmSmart->setChecked(true); // Default when JIT enabled + on_vmSmart_triggered(); +#else + ui->vmInterpreter->setChecked(true); + ui->vmJIT->setEnabled(false); + ui->vmSmart->setEnabled(false); +#endif + readSettings(); m_transact = new Transact(this, this); m_transact->setWindowFlags(Qt::Dialog); m_transact->setWindowModality(Qt::WindowModal); + connect(ui->blockChainDockWidget, &QDockWidget::visibilityChanged, [=]() { refreshBlockChain(); }); + #if !ETH_FATDB removeDockWidget(ui->dockWidget_accounts); -#endif -#if !ETH_EVMJIT - ui->jitvm->setEnabled(false); - ui->jitvm->setChecked(false); #endif installWatches(); startTimer(100); @@ -296,6 +315,14 @@ void Main::on_gasPrices_triggered() } } +void Main::on_sentinel_triggered() +{ + bool ok; + QString sentinel = QInputDialog::getText(nullptr, "Enter sentinel address", "Enter the sentinel address for bad block reporting (e.g. http://badblockserver.com:8080). Enter nothing to disable.", QLineEdit::Normal, QString::fromStdString(ethereum()->sentinel()), &ok); + if (ok) + ethereum()->setSentinel(sentinel.toStdString()); +} + void Main::on_newIdentity_triggered() { KeyPair kp = KeyPair::create(); @@ -723,7 +750,8 @@ void Main::writeSettings() s.setValue("url", ui->urlEdit->text()); s.setValue("privateChain", m_privateChain); s.setValue("verbosity", ui->verbosity->value()); - s.setValue("jitvm", ui->jitvm->isChecked()); + if (auto vm = m_vmSelectionGroup->checkedAction()) + s.setValue("vm", vm->text()); bytes d = m_webThree->saveNetwork(); if (!d.empty()) @@ -814,8 +842,28 @@ void Main::readSettings(bool _skipGeometry) m_privateChain = s.value("privateChain", "").toString(); ui->usePrivate->setChecked(m_privateChain.size()); ui->verbosity->setValue(s.value("verbosity", 1).toInt()); - ui->jitvm->setChecked(s.value("jitvm", true).toBool()); - on_jitvm_triggered(); + +#if ETH_EVMJIT // We care only if JIT is enabled. Otherwise it can cause misconfiguration. + auto vmName = s.value("vm").toString(); + if (!vmName.isEmpty()) + { + if (vmName == ui->vmInterpreter->text()) + { + ui->vmInterpreter->setChecked(true); + on_vmInterpreter_triggered(); + } + else if (vmName == ui->vmJIT->text()) + { + ui->vmJIT->setChecked(true); + on_vmJIT_triggered(); + } + else if (vmName == ui->vmSmart->text()) + { + ui->vmSmart->setChecked(true); + on_vmSmart_triggered(); + } + } +#endif ui->urlEdit->setText(s.value("url", "about:blank").toString()); //http://gavwood.com/gavcoin.html on_urlEdit_returnPressed(); @@ -992,10 +1040,19 @@ void Main::on_usePrivate_triggered() on_killBlockchain_triggered(); } -void Main::on_jitvm_triggered() +void Main::on_vmInterpreter_triggered() { VMFactory::setKind(VMKind::Interpreter); } +void Main::on_vmJIT_triggered() { VMFactory::setKind(VMKind::JIT); } +void Main::on_vmSmart_triggered() { VMFactory::setKind(VMKind::Smart); } + +void Main::on_rewindChain_triggered() { - bool jit = ui->jitvm->isChecked(); - VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter); + bool ok; + int n = QInputDialog::getInt(this, "Rewind Chain", "Enter the number of the new chain head.", ethereum()->number() * 9 / 10, 1, ethereum()->number(), 1, &ok); + if (ok) + { + ethereum()->rewind(n); + refreshAll(); + } } void Main::on_urlEdit_returnPressed() @@ -1252,7 +1309,7 @@ void Main::refreshBlockCount() auto d = ethereum()->blockChain().details(); BlockQueueStatus b = ethereum()->blockQueueStatus(); SyncStatus sync = ethereum()->syncStatus(); - QString syncStatus = EthereumHost::stateName(sync.state); + QString syncStatus = QString("PV%1 %2").arg(sync.protocolVersion).arg(EthereumHost::stateName(sync.state)); if (sync.state == SyncState::Hashes) syncStatus += QString(": %1/%2%3").arg(sync.hashesReceived).arg(sync.hashesEstimated ? "~" : "").arg(sync.hashesTotal); if (sync.state == SyncState::Blocks || sync.state == SyncState::NewBlocks) @@ -1269,7 +1326,7 @@ void Main::on_turboMining_triggered() void Main::refreshBlockChain() { - if (!ui->blocks->isVisible() && isVisible()) + if (!(ui->blockChainDockWidget->isVisible() || !tabifiedDockWidgets(ui->blockChainDockWidget).isEmpty())) return; DEV_TIMED_FUNCTION_ABOVE(500); @@ -1947,12 +2004,12 @@ void Main::on_net_triggered() web3()->setNetworkPreferences(netPrefs(), ui->dropPeers->isChecked()); ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256()); web3()->startNetwork(); - ui->downloadView->setDownloadMan(ethereum()->downloadMan()); + ui->downloadView->setEthereum(ethereum()); ui->enode->setText(QString::fromStdString(web3()->enode())); } else { - ui->downloadView->setDownloadMan(nullptr); + ui->downloadView->setEthereum(nullptr); writeSettings(); web3()->stopNetwork(); } diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index f8a6fa6c7..0e944b042 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -44,6 +44,7 @@ #include "Connect.h" class QListWidgetItem; +class QActionGroup; namespace Ui { class Main; @@ -182,8 +183,11 @@ private slots: void on_forceMining_triggered(); void on_usePrivate_triggered(); void on_turboMining_triggered(); - void on_jitvm_triggered(); void on_retryUnknown_triggered(); + void on_vmInterpreter_triggered(); + void on_vmJIT_triggered(); + void on_vmSmart_triggered(); + void on_rewindChain_triggered(); // Debugger void on_debugCurrent_triggered(); @@ -196,6 +200,7 @@ private slots: // Config void on_gasPrices_triggered(); + void on_sentinel_triggered(); void refreshWhisper(); void refreshBlockChain(); @@ -271,6 +276,8 @@ private: dev::Address m_nameReg; dev::Address m_beneficiary; + QActionGroup* m_vmSelectionGroup = nullptr; + QList> m_consoleHistory; QMutex m_logLock; QString m_logHistory; @@ -286,6 +293,6 @@ private: std::unique_ptr m_dappHost; DappLoader* m_dappLoader; QWebEnginePage* m_webPage; - + Connect m_connect; }; diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index aaeffa16b..056b0460d 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -99,10 +99,11 @@ bool OurAccountHolder::showUnknownCallNotice(TransactionSkeleton const& _t, bool "REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"); } -void OurAccountHolder::authenticate(TransactionSkeleton const& _t) +h256 OurAccountHolder::authenticate(TransactionSkeleton const& _t) { Guard l(x_queued); m_queued.push(_t); + return h256(); } void OurAccountHolder::doValidations() @@ -130,7 +131,7 @@ void OurAccountHolder::doValidations() else // sign and submit. if (Secret s = m_main->retrieveSecret(t.from)) - m_main->ethereum()->submitTransaction(s, t); + m_main->ethereum()->submitTransaction(t, s); } } diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index cc950027e..26053ae36 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -43,7 +43,7 @@ protected: // easiest to return keyManager.addresses(); virtual dev::AddressHash realAccounts() const override; // use web3 to submit a signed transaction to accept - virtual void authenticate(dev::eth::TransactionSkeleton const& _t) override; + virtual dev::h256 authenticate(dev::eth::TransactionSkeleton const& _t) override; private: bool showAuthenticationPopup(std::string const& _title, std::string const& _text); diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index 6701cf824..5fcb7d353 100644 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -47,9 +47,10 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") add_compile_options(/MP /EHsc /wd4068 /wd4996 /wd4503 /wd4267 /wd4180 /wd4290 /wd4244 /wd4800 -D_WIN32_WINNT=0x0501 /DNOMINMAX /DMINIUPNP_STATICLIB) # disable empty object file warning set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") - # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification + # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification # warning LNK4099: pdb was not found with lib - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075") + # stack size 16MB + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216") # windows likes static if (NOT ETH_STATIC) diff --git a/cmake/Findv8.cmake b/cmake/Findv8.cmake index 2451c708f..e46ae7e39 100644 --- a/cmake/Findv8.cmake +++ b/cmake/Findv8.cmake @@ -31,12 +31,32 @@ set(V8_LIBRARIES ${V8_LIBRARY}) if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") find_library( - V8_LIBRARY_DEBUG - NAMES v8d - DOC "v8 debug library" + V8_LIBRARY + NAMES v8_base + DOC "v8 base library" + ) + + find_library( + V8_NO_SNAPSHOT_LIBRARY + NAMES v8_nosnapshot + DOC "v8 nosnapshot library" ) - set(V8_LIBRARIES optimized ${V8_LIBRARIES} debug ${V8_LIBRARY_DEBUG}) + set(V8_LIBRARIES ${V8_LIBRARY} ${V8_NO_SNAPSHOT_LIBRARY}) + + find_library( + V8_LIBRARY_DEBUG + NAMES v8_based + DOC "v8 base library" + ) + + find_library( + V8_NO_SNAPSHOT_LIBRARY_DEBUG + NAMES v8_nosnapshotd + DOC "v8 nosnapshot library" + ) + + set(V8_LIBRARIES "ws2_32" "winmm" optimized ${V8_LIBRARIES} debug ${V8_LIBRARY_DEBUG} ${V8_NO_SNAPSHOT_LIBRARY_DEBUG}) endif() diff --git a/eth/main.cpp b/eth/main.cpp index 4361598d4..24520d8c4 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -74,12 +75,8 @@ void interactiveHelp() << "Commands:" << endl << " netstart Starts the network subsystem on a specific port." << endl << " netstop Stops the network subsystem." << endl - << " jsonstart Starts the JSON-RPC server." << endl - << " jsonstop Stops the JSON-RPC server." << endl << " connect Connects to a specific peer." << endl << " verbosity () Gets or sets verbosity level." << endl - << " setetherprice

Resets the ether price." << endl - << " setpriority

Resets the transaction priority." << endl << " minestart Starts mining." << endl << " minestop Stops mining." << endl << " mineforce Forces mining, even when there are no transactions." << endl @@ -115,6 +112,7 @@ void interactiveHelp() << " reprocess Reprocess a given block." << endl << " dumptrace Dumps a transaction trace" << endl << "to . should be one of pretty, standard, standard+." << endl << " dumpreceipt Dumps a transation receipt." << endl + << " hashrate Print the current hashrate in hashes per second if the client is mining." << endl << " exit Exits the application." << endl; } @@ -133,6 +131,7 @@ void help() #endif << " -K,--kill First kill the blockchain." << endl << " -R,--rebuild Rebuild the blockchain from the existing database." << endl + << " --rescue Attempt to rescue a corrupt database." << endl << " --genesis-nonce Set the Genesis Nonce to the given hex nonce." << endl << " -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 @@ -193,7 +192,7 @@ void help() << "General Options:" << endl << " -d,--db-path Load database from path (default: " << getDataDir() << ")" << endl #if ETH_EVMJIT || !ETH_TRUE - << " -J,--jit Enable EVM JIT (default: off)." << endl + << " --vm Select VM. Options are: interpreter, jit, smart. (default: interpreter)" << endl #endif << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl << " -V,--version Show the version and exit." << endl @@ -284,1569 +283,1484 @@ void stopMiningAfterXBlocks(eth::Client* _c, unsigned _start, unsigned _mining) this_thread::sleep_for(chrono::milliseconds(100)); } -int main(int argc, char** argv) +void interactiveMode(eth::Client* c, std::shared_ptr gasPricer, WebThreeDirect& web3, KeyManager& keyManager, string& logbuf, string& additional, function getPassword, function getAccountPassword, NetworkPreferences netPrefs, Address beneficiary, Address signingKey, TransactionPriority priority) { - // Init defaults - Defaults::get(); - - /// Operating mode. - OperationMode mode = OperationMode::Node; - string dbPath; - unsigned prime = 0; - bool yesIReallyKnowWhatImDoing = false; - - /// File name for import/export. - string filename; - bool safeImport = false; - - /// Hashes/numbers for export range. - string exportFrom = "1"; - string exportTo = "latest"; - Format exportFormat = Format::Binary; - - /// General params for Node operation - NodeMode nodeMode = NodeMode::Full; - bool interactive = false; -#if ETH_JSONRPC - int jsonrpc = -1; -#endif - string jsonAdmin; - bool upnp = true; - WithExisting killChain = WithExisting::Trust; - bool jit = false; - string sentinel; - - /// Networking params. - string clientName; - string listenIP; - unsigned short listenPort = 30303; - string publicIP; - string remoteHost; - unsigned short remotePort = 30303; - unsigned peers = 11; - bool bootstrap = false; - bool disableDiscovery = false; - bool pinning = false; - unsigned networkId = 0; - - /// Mining params - unsigned mining = 0; - bool forceMining = false; - bool mineOnWrongChain = false; - Address signingKey; - Address sessionKey; - Address beneficiary = signingKey; - - /// Structured logging params - bool structuredLogging = false; - string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S"; - string structuredLoggingURL; - - /// Transaction params - TransactionPriority priority = TransactionPriority::Medium; -// double etherPrice = 30.679; -// double blockFees = 15.0; - u256 askPrice("500000000000"); - u256 bidPrice("500000000000"); - - // javascript console - bool useConsole = false; - - /// Wallet password stuff - string masterPassword; - - string configFile = getDataDir() + "/config.rlp"; - bytes b = contents(configFile); - - strings passwordsToNote; - Secrets toImport; - if (b.size()) + additional = "Press Enter"; + string l; + while (!g_exit) { - RLP config(b); - if (config[0].size() == 32) // secret key - import and forget. + g_silence = false; + cout << logbuf << "Press Enter" << flush; + std::getline(cin, l); + logbuf.clear(); + g_silence = true; + +#if ETH_READLINE + if (l.size()) + add_history(l.c_str()); + if (auto c = readline("> ")) { - Secret s = config[0].toHash(); - toImport.push_back(s); + l = c; + free(c); } - else // new format - just use it as an address. - signingKey = config[0].toHash

(); - beneficiary = config[1].toHash
(); - } - - MinerCLI m(MinerCLI::OperationMode::None); - - for (int i = 1; i < argc; ++i) - { - string arg = argv[i]; - 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) + else + break; +#else + string l; + cout << "> " << flush; + std::getline(cin, l); +#endif + istringstream iss(l); + string cmd; + iss >> cmd; + boost::to_lower(cmd); + if (cmd == "netstart") { - if (arg == "-l") - cerr << "-l is DEPRECATED. It will be removed for the Frontier. Use --listen-port instead." << endl; - listenPort = (short)atoi(argv[++i]); + iss >> netPrefs.listenPort; + web3.setNetworkPreferences(netPrefs); + web3.startNetwork(); } - else if ((arg == "-u" || arg == "--public-ip" || arg == "--public") && i + 1 < argc) + else if (cmd == "connect") { - if (arg == "-u") - cerr << "-u is DEPRECATED. It will be removed for the Frontier. Use --public-ip instead." << endl; - publicIP = argv[++i]; + string addrPort; + iss >> addrPort; + web3.addNode(p2p::NodeId(), addrPort); } - else if ((arg == "-r" || arg == "--remote") && i + 1 < argc) - remoteHost = argv[++i]; - else if ((arg == "-p" || arg == "--port") && i + 1 < argc) + else if (cmd == "netstop") + web3.stopNetwork(); + else if (c && cmd == "minestart") + c->startMining(); + else if (c && cmd == "minestop") + c->stopMining(); + else if (c && cmd == "mineforce") { - if (arg == "-p") - cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl; - remotePort = (short)atoi(argv[++i]); + string enable; + iss >> enable; + c->setForceMining(isTrue(enable)); } - else if (arg == "--password" && i + 1 < argc) - passwordsToNote.push_back(argv[++i]); - else if (arg == "--master" && i + 1 < argc) - masterPassword = argv[++i]; - else if ((arg == "-I" || arg == "--import") && i + 1 < argc) + else if (cmd == "verbosity") { - mode = OperationMode::Import; - filename = argv[++i]; + if (iss.peek() != -1) + iss >> g_logVerbosity; + cout << "Verbosity: " << g_logVerbosity << endl; } - else if (arg == "--dont-check") - safeImport = true; - else if ((arg == "-E" || arg == "--export") && i + 1 < argc) + else if (cmd == "address") { - mode = OperationMode::Export; - filename = argv[++i]; + cout << "Current mining beneficiary:" << endl << beneficiary << endl; + cout << "Current signing account:" << endl << signingKey << endl; } - else if (arg == "--prime" && i + 1 < argc) - try - { - prime = stoi(argv[++i]); - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; - } - else if (arg == "--yes-i-really-know-what-im-doing") - yesIReallyKnowWhatImDoing = true; - else if (arg == "--sentinel" && i + 1 < argc) - sentinel = argv[++i]; - else if (arg == "--mine-on-wrong-chain") - mineOnWrongChain = true; - else if (arg == "--format" && i + 1 < argc) + else if (c && cmd == "blockhashfromnumber") { - string m = argv[++i]; - if (m == "binary") - exportFormat = Format::Binary; - else if (m == "hex") - exportFormat = Format::Hex; - else if (m == "human") - exportFormat = Format::Human; - else + if (iss.peek() != -1) { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; + unsigned number; + iss >> number; + cout << " hash of block: " << c->hashFromNumber(number).hex() << endl; } } - else if (arg == "--to" && i + 1 < argc) - exportTo = argv[++i]; - else if (arg == "--from" && i + 1 < argc) - exportFrom = argv[++i]; - else if (arg == "--only" && i + 1 < argc) - exportTo = exportFrom = argv[++i]; - else if ((arg == "-n" || arg == "-u" || arg == "--upnp") && i + 1 < argc) + else if (c && cmd == "numberfromblockhash") { - if (arg == "-n") - cerr << "-n is DEPRECATED. It will be removed for the Frontier. Use --upnp instead." << endl; - string m = argv[++i]; - if (isTrue(m)) - upnp = true; - else if (isFalse(m)) - upnp = false; - else + if (iss.peek() != -1) { - cerr << "Bad " << arg << " option: " << m << endl; - return -1; + string stringHash; + iss >> stringHash; + + h256 hash = h256(fromHex(stringHash)); + cout << " number of block: " << c->numberFromHash(hash) << endl; } } - else if (arg == "--network-id" && i + 1 < argc) - try { - networkId = 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") - killChain = WithExisting::Verify; - else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) + else if (c && cmd == "block") + cout << "Current block: " << c->blockChain().details().number << endl; + else if (c && cmd == "blockqueue") + cout << "Current blockqueue status: " << endl << c->blockQueueStatus() << endl; + else if (c && cmd == "sync") + cout << "Current sync status: " << endl << c->syncStatus() << endl; + else if (c && cmd == "hashrate") + cout << "Current hash rate: " << toString(c->hashrate()) << " hashes per second." << endl; + else if (c && cmd == "findblock") { - if (arg == "-c") - cerr << "-c is DEPRECATED. It will be removed for the Frontier. Use --client-name instead." << endl; - clientName = argv[++i]; - } - else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) - try { - beneficiary = h160(fromHex(argv[++i], WhenError::Throw)); - } - catch (BadHexCharacter&) + if (iss.peek() != -1) { - cerr << "Bad hex in " << arg << " option: " << argv[i] << endl; - return -1; - } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; + string stringHash; + iss >> stringHash; + + h256 hash = h256(fromHex(stringHash)); + + // search in blockchain + cout << "search in blockchain... " << endl; + try + { + cout << c->blockInfo(hash) << endl; + } + catch(Exception& _e) + { + cout << "block not in blockchain" << endl; + cout << boost::diagnostic_information(_e) << endl; + } + + cout << "search in blockqueue... " << endl; + + switch(c->blockQueue().blockStatus(hash)) + { + case QueueStatus::Ready: + cout << "Ready" << endl; + break; + case QueueStatus::Importing: + cout << "Importing" << endl; + break; + case QueueStatus::UnknownParent: + cout << "UnknownParent" << endl; + break; + case QueueStatus::Bad: + cout << "Bad" << endl; + break; + case QueueStatus::Unknown: + cout << "Unknown" << endl; + break; + default: + cout << "invalid queueStatus" << endl; + } } - else if ((arg == "-s" || arg == "--import-secret") && i + 1 < argc) - { - Secret s(fromHex(argv[++i])); - toImport.push_back(s); - signingKey = toAddress(s); - } - else if ((arg == "-S" || arg == "--import-session-secret") && i + 1 < argc) - { - Secret s(fromHex(argv[++i])); - toImport.push_back(s); - sessionKey = toAddress(s); + else + cwarn << "Require parameter: findblock HASH"; } - else if ((arg == "--sign-key") && i + 1 < argc) - sessionKey = Address(fromHex(argv[++i])); - else if ((arg == "--session-sign-key") && i + 1 < argc) - sessionKey = Address(fromHex(argv[++i])); - else if (arg == "--structured-logging-format" && i + 1 < argc) - structuredLoggingFormat = string(argv[++i]); - else if (arg == "--structured-logging") - structuredLogging = true; - else if (arg == "--structured-logging-url" && i + 1 < argc) + else if (c && cmd == "firstunknown") + cout << "first unknown blockhash: " << c->blockQueue().firstUnknown().hex() << endl; + else if (c && cmd == "retryunknown") + c->retryUnknown(); + else if (cmd == "peers") { - structuredLogging = true; - structuredLoggingURL = argv[++i]; + for (auto it: web3.peers()) + cout << it.host << ":" << it.port << ", " << it.clientVersion << ", " + << std::chrono::duration_cast(it.lastPing).count() << "ms" + << endl; } - else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) - dbPath = argv[++i]; - else if (arg == "--genesis-nonce" && i + 1 < argc) + else if (cmd == "newaccount") { - try - { - CanonBlockChain::setGenesisNonce(Nonce(argv[++i])); + 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(); + } } - catch (...) + if (!password.empty()) { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; + 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 ((arg == "-B" || arg == "--block-fees") && i + 1 < argc) + else if (c && cmd == "accounts") { - try + cout << "Accounts:" << endl; + u256 total = 0; + for (auto const& address: keyManager.accounts()) { - blockFees = stof(argv[++i]); + auto b = c->balanceAt(address); + cout << ((address == signingKey) ? "SIGNING " : " ") << ((address == beneficiary) ? "COINBASE " : " ") << keyManager.accountName(address) << " (" << address << "): " << formatBalance(b) << " = " << b << " wei" << endl; + total += b; } - catch (...) - { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; + cout << "Total: " << formatBalance(total) << " = " << total << " wei" << endl; + } + else if (c && cmd == "transact") + { + auto const& bc =c->blockChain(); + auto h = bc.currentHash(); + auto blockData = bc.block(h); + BlockInfo info(blockData); + if (iss.peek() != -1) + { + string hexAddr; + u256 amount; + u256 gasPrice; + u256 gas; + string sechex; + string sdata; + + iss >> hexAddr >> amount >> gasPrice >> gas >> sechex >> sdata; + + if (!gasPrice) + gasPrice = gasPricer->bid(priority); + + cnote << "Data:"; + cnote << sdata; + bytes data = dev::eth::parseData(sdata); + cnote << "Bytes:"; + string sbd = asString(data); + bytes bbd = asBytes(sbd); + stringstream ssbd; + ssbd << bbd; + cnote << ssbd.str(); + int ssize = sechex.length(); + int size = hexAddr.length(); + u256 minGas = (u256)Transaction::gasRequired(data, 0); + if (size < 40) + { + if (size > 0) + cwarn << "Invalid address length:" << size; + } + else if (gas < minGas) + cwarn << "Minimum gas amount is" << minGas; + else if (ssize < 40) + { + if (ssize > 0) + cwarn << "Invalid secret length:" << ssize; + } + else + { + try + { + Secret secret = h256(fromHex(sechex)); + Address dest = h160(fromHex(hexAddr)); + c->submitTransaction(secret, amount, dest, data, gas, gasPrice); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } + } } + else + cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA"; } - else if ((arg == "-e" || arg == "--ether-price") && i + 1 < argc) + + else if (c && cmd == "transactnonce") { - try + auto const& bc =c->blockChain(); + auto h = bc.currentHash(); + auto blockData = bc.block(h); + BlockInfo info(blockData); + if (iss.peek() != -1) + { + string hexAddr; + u256 amount; + u256 gasPrice; + u256 gas; + string sechex; + string sdata; + u256 nonce; + + iss >> hexAddr >> amount >> gasPrice >> gas >> sechex >> sdata >> nonce; + + if (!gasPrice) + gasPrice = gasPricer->bid(priority); + + cnote << "Data:"; + cnote << sdata; + bytes data = dev::eth::parseData(sdata); + cnote << "Bytes:"; + string sbd = asString(data); + bytes bbd = asBytes(sbd); + stringstream ssbd; + ssbd << bbd; + cnote << ssbd.str(); + int ssize = sechex.length(); + int size = hexAddr.length(); + u256 minGas = (u256)Transaction::gasRequired(data, 0); + if (size < 40) + { + if (size > 0) + cwarn << "Invalid address length:" << size; + } + else if (gas < minGas) + cwarn << "Minimum gas amount is" << minGas; + else if (ssize < 40) + { + if (ssize > 0) + cwarn << "Invalid secret length:" << ssize; + } + else + { + try + { + Secret secret = h256(fromHex(sechex)); + Address dest = h160(fromHex(hexAddr)); + c->submitTransaction(secret, amount, dest, data, gas, gasPrice, nonce); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } + } + } + else + cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA NONCE"; + } + + else if (c && cmd == "txcreate") + { + auto const& bc =c->blockChain(); + auto h = bc.currentHash(); + auto blockData = bc.block(h); + BlockInfo info(blockData); + if (iss.peek() != -1) + { + u256 amount; + u256 gasPrice; + u256 gas; + string sechex; + string sdata; + + iss >> amount >> gasPrice >> gas >> sechex >> sdata; + + if (!gasPrice) + gasPrice = gasPricer->bid(priority); + + cnote << "Data:"; + cnote << sdata; + bytes data = dev::eth::parseData(sdata); + cnote << "Bytes:"; + string sbd = asString(data); + bytes bbd = asBytes(sbd); + stringstream ssbd; + ssbd << bbd; + cnote << ssbd.str(); + int ssize = sechex.length(); + u256 minGas = (u256)Transaction::gasRequired(data, 0); + if (gas < minGas) + cwarn << "Minimum gas amount is" << minGas; + else if (ssize < 40) + { + if (ssize > 0) + cwarn << "Invalid secret length:" << ssize; + } + else + { + try + { + Secret secret = h256(fromHex(sechex)); + cout << " new contract address : " << c->submitTransaction(secret, amount, data, gas, gasPrice) << endl; + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } + } + } + else + cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET INIT"; + } +#if ETH_FATDB + else if (c && cmd == "listcontracts") + { + auto acs =c->addresses(); + string ss; + for (auto const& i: acs) + if ( c->codeAt(i, PendingBlock).size()) + { + ss = toString(i) + " : " + toString( c->balanceAt(i)) + " [" + toString((unsigned) c->countAt(i)) + "]"; + cout << ss << endl; + } + } + else if (c && cmd == "listaccounts") + { + auto acs =c->addresses(); + string ss; + for (auto const& i: acs) + if ( c->codeAt(i, PendingBlock).empty()) + { + ss = toString(i) + " : " + toString( c->balanceAt(i)) + " [" + toString((unsigned) c->countAt(i)) + "]"; + cout << ss << endl; + } + } + else if (c && cmd == "balanceat") + { + if (iss.peek() != -1) { - etherPrice = stof(argv[++i]); + string stringHash; + iss >> stringHash; + + Address address = h160(fromHex(stringHash)); + + cout << "balance of " << stringHash << " is: " << toString(c->balanceAt(address)) << endl; } - catch (...) + } + else if (c && cmd == "balanceatblock") + { + if (iss.peek() != -1) { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; + string stringHash; + unsigned blocknumber; + iss >> stringHash >> blocknumber; + + Address address = h160(fromHex(stringHash)); + + cout << "balance of " << stringHash << " is: " << toString(c->balanceAt(address, blocknumber)) << endl; } - }*/ - else if (arg == "--ask" && i + 1 < argc) + } + else if (c && cmd == "storageat") { - try + if (iss.peek() != -1) { - askPrice = u256(argv[++i]); + string stringHash; + iss >> stringHash; + + Address address = h160(fromHex(stringHash)); + + cout << "storage at " << stringHash << " is: " << endl; + for (auto s: c->storageAt(address)) + cout << toHex(s.first) << " : " << toHex(s.second) << endl; } - catch (...) + } + else if (c && cmd == "storageatblock") + { + if (iss.peek() != -1) { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; + string stringHash; + unsigned blocknumber; + iss >> stringHash >> blocknumber; + + Address address = h160(fromHex(stringHash)); + + cout << "storage at " << stringHash << " is: " << endl; + for (auto s: c->storageAt(address, blocknumber)) + cout << "\"0x" << toHex(s.first) << "\" : \"0x" << toHex(s.second) << "\"," << endl; } } - else if (arg == "--bid" && i + 1 < argc) + else if (c && cmd == "codeat") { - try + if (iss.peek() != -1) { - bidPrice = u256(argv[++i]); + string stringHash; + iss >> stringHash; + + Address address = h160(fromHex(stringHash)); + + cout << "code at " << stringHash << " is: " << toHex(c->codeAt(address)) << endl; } - catch (...) + } +#endif + + else if (c && cmd == "send") + { + if (iss.peek() != -1) { - cerr << "Bad " << arg << " option: " << argv[i] << endl; - return -1; + string hexAddr; + u256 amount; + + iss >> hexAddr >> amount; + int size = hexAddr.length(); + if (size < 40) + { + if (size > 0) + cwarn << "Invalid address length:" << size; + } + else + { + auto const& bc =c->blockChain(); + auto h = bc.currentHash(); + auto blockData = bc.block(h); + BlockInfo info(blockData); + u256 minGas = (u256)Transaction::gasRequired(bytes(), 0); + try + { + Address dest = h160(fromHex(hexAddr, WhenError::Throw)); + c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), amount, dest, bytes(), minGas); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, transaction rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "transaction rejected"; + } + } } + else + cwarn << "Require parameters: send ADDRESS AMOUNT"; } - else if ((arg == "-P" || arg == "--priority") && i + 1 < argc) + else if (c && cmd == "contract") { - string m = boost::to_lower_copy(string(argv[++i])); - if (m == "lowest") - priority = TransactionPriority::Lowest; - else if (m == "low") - priority = TransactionPriority::Low; - else if (m == "medium" || m == "mid" || m == "default" || m == "normal") - priority = TransactionPriority::Medium; - else if (m == "high") - priority = TransactionPriority::High; - else if (m == "highest") - priority = TransactionPriority::Highest; + auto const& bc =c->blockChain(); + auto h = bc.currentHash(); + auto blockData = bc.block(h); + BlockInfo info(blockData); + if (iss.peek() != -1) + { + u256 endowment; + u256 gas; + u256 gasPrice; + string sinit; + iss >> endowment >> gasPrice >> gas >> sinit; + trim_all(sinit); + int size = sinit.length(); + bytes init; + cnote << "Init:"; + cnote << sinit; + cnote << "Code size:" << size; + if (size < 1) + cwarn << "No code submitted"; + else + { + cnote << "Assembled:"; + stringstream ssc; + try + { + init = fromHex(sinit, WhenError::Throw); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, code rejected"; + cwarn << boost::diagnostic_information(_e); + init = bytes(); + } + catch (...) + { + cwarn << "code rejected"; + init = bytes(); + } + ssc.str(string()); + ssc << disassemble(init); + cnote << "Init:"; + cnote << ssc.str(); + } + u256 minGas = (u256)Transaction::gasRequired(init, 0); + if (!init.size()) + cwarn << "Contract creation aborted, no init code."; + else if (endowment < 0) + cwarn << "Invalid endowment"; + else if (gas < minGas) + cwarn << "Minimum gas amount is" << minGas; + else + c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), endowment, init, gas, gasPrice); + } else - try { - priority = (TransactionPriority)(max(0, min(100, stoi(m))) * 8 / 100); + cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX"; + } + else if (c && cmd == "dumpreceipt") + { + unsigned block; + unsigned index; + iss >> block >> index; + dev::eth::TransactionReceipt r = c->blockChain().receipts(c->blockChain().numberHash(block)).receipts[index]; + auto rb = r.rlp(); + cout << "RLP: " << RLP(rb) << endl; + cout << "Hex: " << toHex(rb) << endl; + cout << r << endl; + } + else if (c && cmd == "reprocess") + { + string block; + iss >> block; + h256 blockHash; + try + { + if (block.size() == 64 || block.size() == 66) + blockHash = h256(block); + else + blockHash = c->blockChain().numberHash(stoi(block)); + c->state(blockHash); + } + catch (...) + {} + } + else if (c && cmd == "dumptrace") + { + unsigned block; + unsigned index; + string filename; + string format; + iss >> block >> index >> filename >> format; + ofstream f; + f.open(filename); + + dev::eth::State state = c->state(index + 1,c->blockChain().numberHash(block)); + if (index < state.pending().size()) + { + Executive e(state, c->blockChain(), 0); + Transaction t = state.pending()[index]; + state = state.fromPending(index); + try + { + OnOpFunc oof; + if (format == "pretty") + oof = [&](uint64_t steps, Instruction instr, bigint newMemSize, bigint gasCost, bigint gas, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM) + { + dev::eth::VM* vm = vvm; + dev::eth::ExtVM const* ext = static_cast(vextVM); + f << endl << " STACK" << endl; + for (auto i: vm->stack()) + f << (h256)i << endl; + f << " MEMORY" << endl << dev::memDump(vm->memory()); + f << " STORAGE" << endl; + for (auto const& i: ext->state().storage(ext->myAddress)) + f << showbase << hex << i.first << ": " << i.second << endl; + f << dec << ext->depth << " | " << ext->myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm->curPC() << " : " << dev::eth::instructionInfo(instr).name << " | " << dec << gas << " | -" << dec << gasCost << " | " << newMemSize << "x32"; + }; + else if (format == "standard") + oof = [&](uint64_t, Instruction instr, bigint, bigint, bigint gas, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM) + { + dev::eth::VM* vm = vvm; + dev::eth::ExtVM const* ext = static_cast(vextVM); + f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)gas, 1)) << endl; + }; + else if (format == "standard+") + oof = [&](uint64_t, Instruction instr, bigint, bigint, bigint gas, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM) + { + dev::eth::VM* vm = vvm; + dev::eth::ExtVM const* ext = static_cast(vextVM); + if (instr == Instruction::STOP || instr == Instruction::RETURN || instr == Instruction::SUICIDE) + for (auto const& i: ext->state().storage(ext->myAddress)) + f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl; + f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)gas, 1)) << endl; + }; + e.initialize(t); + if (!e.execute()) + e.go(oof); + e.finalize(); } - catch (...) { - cerr << "Unknown " << arg << " option: " << m << endl; - return -1; + catch(Exception const& _e) + { + // TODO: a bit more information here. this is probably quite worrying as the transaction is already in the blockchain. + cwarn << diagnostic_information(_e); } + } } - else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) + else if (c && cmd == "inspect") { - string m = argv[++i]; - if (isTrue(m)) - mining = ~(unsigned)0; - else if (isFalse(m)) - mining = 0; + string rechex; + iss >> rechex; + + if (rechex.length() != 40) + cwarn << "Invalid address length"; else - try { - mining = stoi(m); + { + auto h = h160(fromHex(rechex)); + stringstream s; + + try + { + auto storage =c->storageAt(h, PendingBlock); + for (auto const& i: storage) + s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << endl; + s << endl << disassemble( c->codeAt(h, PendingBlock)) << endl; + + string outFile = getDataDir() + "/" + rechex + ".evm"; + ofstream ofs; + ofs.open(outFile, ofstream::binary); + ofs.write(s.str().c_str(), s.str().length()); + ofs.close(); + + cnote << "Saved" << rechex << "to" << outFile; } - catch (...) { - cerr << "Unknown " << arg << " option: " << m << endl; - return -1; + catch (dev::InvalidTrie) + { + cwarn << "Corrupted trie."; } + } } - else if (arg == "-b" || arg == "--bootstrap") - bootstrap = true; - else if (arg == "--no-discovery") - disableDiscovery = true; - else if (arg == "--pin") - pinning = true; - else if (arg == "-f" || arg == "--force-mining") - forceMining = true; - else if (arg == "-i" || arg == "--interactive") - interactive = true; -#if ETH_JSONRPC - else if ((arg == "-j" || arg == "--json-rpc")) - jsonrpc = jsonrpc == -1 ? SensibleHttpPort : jsonrpc; - else if (arg == "--json-rpc-port" && i + 1 < argc) - jsonrpc = atoi(argv[++i]); - else if (arg == "--json-admin" && i + 1 < argc) - jsonAdmin = argv[++i]; -#endif -#if ETH_JSCONSOLE - else if (arg == "--console") - useConsole = true; -#endif - else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) - g_logVerbosity = atoi(argv[++i]); - else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) - peers = atoi(argv[++i]); - else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) + else if (cmd == "setsigningkey") { - string m = argv[++i]; - if (m == "full") - nodeMode = NodeMode::Full; - else if (m == "peer") - nodeMode = NodeMode::PeerServer; + if (iss.peek() != -1) + { + string hexSec; + iss >> hexSec; + signingKey = Address(fromHex(hexSec)); + } else + cwarn << "Require parameter: setSecret HEXSECRETKEY"; + } + else if (cmd == "setaddress") + { + if (iss.peek() != -1) { - cerr << "Unknown mode: " << m << endl; - return -1; + string hexAddr; + iss >> hexAddr; + if (hexAddr.length() != 40) + cwarn << "Invalid address length: " << hexAddr.length(); + else + { + try + { + beneficiary = h160(fromHex(hexAddr, WhenError::Throw)); + } + catch (BadHexCharacter& _e) + { + cwarn << "invalid hex character, coinbase rejected"; + cwarn << boost::diagnostic_information(_e); + } + catch (...) + { + cwarn << "coinbase rejected"; + } + } } + else + cwarn << "Require parameter: setAddress HEXADDRESS"; } -#if ETH_EVMJIT - else if (arg == "-J" || arg == "--jit") + else if (cmd == "exportconfig") { - jit = true; + if (iss.peek() != -1) + { + string path; + iss >> path; + writeFile(path, rlpList(signingKey, beneficiary)); + } + else + cwarn << "Require parameter: exportConfig PATH"; } -#endif - else if (arg == "-h" || arg == "--help") - help(); - else if (arg == "-V" || arg == "--version") - version(); - else + else if (cmd == "importconfig") { - cerr << "Invalid argument: " << arg << endl; - exit(-1); + if (iss.peek() != -1) + { + string path; + iss >> path; + bytes b = contents(path); + if (b.size()) + { + RLP config(b); + signingKey = config[0].toHash
(); + beneficiary = config[1].toHash
(); + } + else + cwarn << path << "has no content!"; + } + else + cwarn << "Require parameter: importConfig PATH"; } + else if (cmd == "help") + interactiveHelp(); + else if (cmd == "exit") + break; + else + cout << "Unrecognised command. Type 'help' for help in interactive mode." << endl; } +} - m.execute(); +int main(int argc, char** argv) +{ + // Init defaults + Defaults::get(); - KeyManager keyManager; - for (auto const& s: passwordsToNote) - keyManager.notePassword(s); + /// Operating mode. + OperationMode mode = OperationMode::Node; + string dbPath; + unsigned prime = 0; + bool yesIReallyKnowWhatImDoing = false; - { - RLPStream config(2); - config << signingKey << beneficiary; - writeFile(configFile, config.out()); - } + /// File name for import/export. + string filename; + bool safeImport = false; - if (sessionKey) - signingKey = sessionKey; + /// Hashes/numbers for export range. + string exportFrom = "1"; + string exportTo = "latest"; + Format exportFormat = Format::Binary; - if (!clientName.empty()) - clientName += "/"; + /// General params for Node operation + NodeMode nodeMode = NodeMode::Full; + bool interactive = false; +#if ETH_JSONRPC + int jsonrpc = -1; +#endif + string jsonAdmin; + bool upnp = true; + WithExisting withExisting = WithExisting::Trust; + bool jit = false; + string sentinel; - string logbuf; - std::string additional; - if (interactive) - g_logPost = [&](std::string const& a, char const*){ - static SpinLock s_lock; - SpinGuard l(s_lock); - - if (g_silence) - logbuf += a + "\n"; - else - cout << "\r \r" << a << endl << additional << flush; + /// Networking params. + string clientName; + string listenIP; + unsigned short listenPort = 30303; + string publicIP; + string remoteHost; + unsigned short remotePort = 30303; + unsigned peers = 11; + bool bootstrap = false; + bool disableDiscovery = false; + bool pinning = false; + unsigned networkId = 0; - // helpful to use OutputDebugString on windows - #ifdef _WIN32 - { - OutputDebugStringA(a.data()); - OutputDebugStringA("\n"); - } - #endif - }; + /// Mining params + unsigned mining = 0; + bool forceMining = false; + bool mineOnWrongChain = false; + Address signingKey; + Address sessionKey; + Address beneficiary = signingKey; - auto getPassword = [&](string const& prompt){ - auto s = g_silence; - g_silence = true; - cout << endl; - string ret = dev::getPassword(prompt); - g_silence = s; - return ret; - }; - auto getAccountPassword = [&](Address const& a){ - return getPassword("Enter password for address " + keyManager.accountName(a) + " (" + a.abridged() + "; hint:" + keyManager.passwordHint(a) + "): "); - }; + /// Structured logging params + bool structuredLogging = false; + string structuredLoggingFormat = "%Y-%m-%dT%H:%M:%S"; + string structuredLoggingURL; - 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); - netPrefs.discovery = !disableDiscovery; - netPrefs.pin = pinning; - auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); - dev::WebThreeDirect web3( - WebThreeDirect::composeClientVersion("++eth", clientName), - dbPath, - killChain, - nodeMode == NodeMode::Full ? set{"eth"/*, "shh"*/} : set(), - netPrefs, - &nodesState); - web3.ethereum()->setMineOnBadChain(mineOnWrongChain); - web3.ethereum()->setSentinel(sentinel); + /// Transaction params + TransactionPriority priority = TransactionPriority::Medium; +// double etherPrice = 30.679; +// double blockFees = 15.0; + u256 askPrice("500000000000"); + u256 bidPrice("500000000000"); - auto toNumber = [&](string const& s) -> unsigned { - if (s == "latest") - return web3.ethereum()->number(); - if (s.size() == 64 || (s.size() == 66 && s.substr(0, 2) == "0x")) - return web3.ethereum()->blockChain().number(h256(s)); - try { - return stol(s); - } - catch (...) - { - cerr << "Bad block number/hash option: " << s << endl; - exit(-1); - } - }; + // javascript console + bool useConsole = false; - if (mode == OperationMode::Export) - { - ofstream fout(filename, std::ofstream::binary); - ostream& out = (filename.empty() || filename == "--") ? cout : fout; + /// Wallet password stuff + string masterPassword; - unsigned last = toNumber(exportTo); - for (unsigned i = toNumber(exportFrom); i <= last; ++i) + string configFile = getDataDir() + "/config.rlp"; + bytes b = contents(configFile); + + strings passwordsToNote; + Secrets toImport; + if (b.size()) + { + RLP config(b); + if (config[0].size() == 32) // secret key - import and forget. { - bytes block = web3.ethereum()->blockChain().block(web3.ethereum()->blockChain().numberHash(i)); - switch (exportFormat) - { - case Format::Binary: out.write((char const*)block.data(), block.size()); break; - case Format::Hex: out << toHex(block) << endl; break; - case Format::Human: out << RLP(block) << endl; break; - default:; - } + Secret s = config[0].toHash(); + toImport.push_back(s); } - return 0; + else // new format - just use it as an address. + signingKey = config[0].toHash
(); + beneficiary = config[1].toHash
(); } - if (mode == OperationMode::Import) + MinerCLI m(MinerCLI::OperationMode::None); + + for (int i = 1; i < argc; ++i) { - ifstream fin(filename, std::ifstream::binary); - istream& in = (filename.empty() || filename == "--") ? cin : fin; - unsigned alreadyHave = 0; - unsigned good = 0; - unsigned futureTime = 0; - unsigned unknownParent = 0; - unsigned bad = 0; - chrono::steady_clock::time_point t = chrono::steady_clock::now(); - double last = 0; - unsigned lastImported = 0; - unsigned imported = 0; - while (in.peek() != -1) + string arg = argv[i]; + 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) { - bytes block(8); - in.read((char*)block.data(), 8); - block.resize(RLP(block, RLP::LaisezFaire).actualSize()); - in.read((char*)block.data() + 8, block.size() - 8); - - switch (web3.ethereum()->queueBlock(block, safeImport)) - { - case ImportResult::Success: good++; break; - case ImportResult::AlreadyKnown: alreadyHave++; break; - case ImportResult::UnknownParent: unknownParent++; break; - case ImportResult::FutureTimeUnknown: unknownParent++; futureTime++; break; - case ImportResult::FutureTimeKnown: futureTime++; break; - default: bad++; break; - } - - // sync chain with queue - tuple r = web3.ethereum()->syncQueue(10); - imported += get<2>(r); - - double e = chrono::duration_cast(chrono::steady_clock::now() - t).count() / 1000.0; - if ((unsigned)e >= last + 10) - { - auto i = imported - lastImported; - auto d = e - last; - cout << i << " more imported at " << (round(i * 10 / d) / 10) << " blocks/s. " << imported << " imported in " << e << " seconds at " << (round(imported * 10 / e) / 10) << " blocks/s (#" << web3.ethereum()->number() << ")" << endl; - last = (unsigned)e; - lastImported = imported; - } + if (arg == "-l") + cerr << "-l is DEPRECATED. It will be removed for the Frontier. Use --listen-port instead." << endl; + listenPort = (short)atoi(argv[++i]); } - - while (web3.ethereum()->blockQueue().items().first + web3.ethereum()->blockQueue().items().second > 0) + else if ((arg == "-u" || arg == "--public-ip" || arg == "--public") && i + 1 < argc) { - this_thread::sleep_for(chrono::seconds(1)); - web3.ethereum()->syncQueue(100000); + if (arg == "-u") + cerr << "-u is DEPRECATED. It will be removed for the Frontier. Use --public-ip instead." << endl; + publicIP = argv[++i]; } - double e = chrono::duration_cast(chrono::steady_clock::now() - t).count() / 1000.0; - cout << imported << " imported in " << e << " seconds at " << (round(imported * 10 / e) / 10) << " blocks/s (#" << web3.ethereum()->number() << ")" << endl; - return 0; - } - - if (c_network == eth::Network::Frontier && !yesIReallyKnowWhatImDoing) - { - auto pd = contents(getDataDir() + "primes"); - unordered_set primes = RLP(pd).toUnorderedSet(); - while (true) + else if ((arg == "-r" || arg == "--remote") && i + 1 < argc) + remoteHost = argv[++i]; + else if ((arg == "-p" || arg == "--port") && i + 1 < argc) { - if (!prime) - try - { - prime = stoi(getPassword("To enter the Frontier, enter a 6 digit prime that you have not entered before: ")); - } - catch (...) {} - if (isPrime(prime) && !primes.count(prime)) - break; - prime = 0; + if (arg == "-p") + cerr << "-p is DEPRECATED. It will be removed for the Frontier. Use --port instead (or place directly as host:port)." << endl; + remotePort = (short)atoi(argv[++i]); } - primes.insert(prime); - writeFile(getDataDir() + "primes", rlp(primes)); - } - - if (keyManager.exists()) - { - if (masterPassword.empty() || !keyManager.load(masterPassword)) - while (true) - { - masterPassword = getPassword("Please enter your MASTER password: "); - if (keyManager.load(masterPassword)) - break; - cout << "Password invalid. Try again." << endl; - } - } - else - { - while (masterPassword.empty()) + else if (arg == "--password" && i + 1 < argc) + passwordsToNote.push_back(argv[++i]); + else if (arg == "--master" && i + 1 < argc) + masterPassword = argv[++i]; + else if ((arg == "-I" || arg == "--import") && i + 1 < argc) { - masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): "); - string confirm = getPassword("Please confirm the password by entering it again: "); - if (masterPassword != confirm) - { - cout << "Passwords were different. Try again." << endl; - masterPassword.clear(); - } + mode = OperationMode::Import; + filename = argv[++i]; } - keyManager.create(masterPassword); - } - - for (auto const& s: toImport) - { - keyManager.import(s, "Imported key (UNSAFE)"); - if (!signingKey) - signingKey = toAddress(s); - } - - 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)); - std::shared_ptr gasPricer = make_shared(askPrice, bidPrice); - eth::Client* c = nodeMode == NodeMode::Full ? web3.ethereum() : nullptr; - StructuredLogger::starting(WebThreeDirect::composeClientVersion("++eth", clientName), 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; - - if (bootstrap || !remoteHost.empty()) - { - web3.startNetwork(); - cout << "Node ID: " << web3.enode() << endl; - } - else - cout << "Networking disabled. To start, use netstart or pass -b or a remote host." << endl; - -#if ETH_JSONRPC || !ETH_TRUE - shared_ptr jsonrpcServer; - unique_ptr jsonrpcConnector; - if (jsonrpc > -1) - { - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new dev::WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector(), keyManager, *gasPricer)); - jsonrpcServer->setMiningBenefactorChanger([&](Address const& a) { beneficiary = a; }); - jsonrpcServer->StartListening(); - if (jsonAdmin.empty()) - jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Priviledge::Admin}}); - else - jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Priviledge::Admin}}); - cout << "JSONRPC Admin Session Key: " << jsonAdmin << endl; - } -#endif - - if (bootstrap) - for (auto const& i: Host::pocHosts()) - web3.requirePeer(i.first, i.second); - if (!remoteHost.empty()) - web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); - - signal(SIGABRT, &sighandler); - signal(SIGTERM, &sighandler); - signal(SIGINT, &sighandler); - - if (interactive) - { - additional = "Press Enter"; - string l; - while (!g_exit) + else if (arg == "--dont-check") + safeImport = true; + else if ((arg == "-E" || arg == "--export") && i + 1 < argc) { - g_silence = false; - cout << logbuf << "Press Enter" << flush; - std::getline(cin, l); - logbuf.clear(); - g_silence = true; - -#if ETH_READLINE - if (l.size()) - add_history(l.c_str()); - if (auto c = readline("> ")) - { - l = c; - free(c); - } - else - break; -#else - string l; - cout << "> " << flush; - std::getline(cin, l); -#endif - istringstream iss(l); - string cmd; - iss >> cmd; - boost::to_lower(cmd); - if (cmd == "netstart") - { - iss >> netPrefs.listenPort; - web3.setNetworkPreferences(netPrefs); - web3.startNetwork(); - } - else if (cmd == "connect") - { - string addrPort; - iss >> addrPort; - web3.addNode(p2p::NodeId(), addrPort); - } - else if (cmd == "netstop") - { - web3.stopNetwork(); - } - else if (c && cmd == "minestart") - { - c->startMining(); - } - else if (c && cmd == "minestop") - { - c->stopMining(); - } - else if (c && cmd == "mineforce") - { - string enable; - iss >> enable; - c->setForceMining(isTrue(enable)); - } -/* else if (c && cmd == "setblockfees") - { - iss >> blockFees; - try - { - gasPricer->setRefBlockFees(u256(blockFees * 1000)); - } - catch (Overflow const& _e) - { - cout << boost::diagnostic_information(_e); - } - - cout << "Block fees: " << blockFees << endl; - } - else if (c && cmd == "setetherprice") + mode = OperationMode::Export; + filename = argv[++i]; + } + else if (arg == "--prime" && i + 1 < argc) + try { - iss >> etherPrice; - if (etherPrice == 0) - cout << "ether price cannot be set to zero" << endl; - else - { - try - { - gasPricer->setRefPrice(u256(double(ether / 1000) / etherPrice)); - } - catch (Overflow const& _e) - { - cout << boost::diagnostic_information(_e); - } - } - cout << "ether Price: " << etherPrice << endl; + prime = stoi(argv[++i]); } - else if (c && cmd == "setpriority") - { - string m; - iss >> m; - boost::to_lower(m); - if (m == "lowest") - priority = TransactionPriority::Lowest; - else if (m == "low") - priority = TransactionPriority::Low; - else if (m == "medium" || m == "mid" || m == "default" || m == "normal") - priority = TransactionPriority::Medium; - else if (m == "high") - priority = TransactionPriority::High; - else if (m == "highest") - priority = TransactionPriority::Highest; - else - try { - priority = (TransactionPriority)(max(0, min(100, stoi(m))) * 8 / 100); - } - catch (...) { - cerr << "Unknown priority: " << m << endl; - } - cout << "Priority: " << (int)priority << "/8" << endl; - }*/ - else if (cmd == "verbosity") + catch (...) { - if (iss.peek() != -1) - iss >> g_logVerbosity; - cout << "Verbosity: " << g_logVerbosity << endl; + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } -#if ETH_JSONRPC || !ETH_TRUE - else if (cmd == "jsonport") + else if (arg == "--yes-i-really-know-what-im-doing") + yesIReallyKnowWhatImDoing = true; + else if (arg == "--sentinel" && i + 1 < argc) + sentinel = argv[++i]; + else if (arg == "--mine-on-wrong-chain") + mineOnWrongChain = true; + else if (arg == "--format" && i + 1 < argc) + { + string m = argv[++i]; + if (m == "binary") + exportFormat = Format::Binary; + else if (m == "hex") + exportFormat = Format::Hex; + else if (m == "human") + exportFormat = Format::Human; + else { - if (iss.peek() != -1) - iss >> jsonrpc; - cout << "JSONRPC Port: " << jsonrpc << endl; + cerr << "Bad " << arg << " option: " << m << endl; + return -1; } - else if (cmd == "jsonstart") + } + else if (arg == "--to" && i + 1 < argc) + exportTo = argv[++i]; + else if (arg == "--from" && i + 1 < argc) + exportFrom = argv[++i]; + else if (arg == "--only" && i + 1 < argc) + exportTo = exportFrom = argv[++i]; + else if ((arg == "-n" || arg == "-u" || arg == "--upnp") && i + 1 < argc) + { + if (arg == "-n") + cerr << "-n is DEPRECATED. It will be removed for the Frontier. Use --upnp instead." << endl; + string m = argv[++i]; + if (isTrue(m)) + upnp = true; + else if (isFalse(m)) + upnp = false; + else { - if (jsonrpc < 0) - jsonrpc = SensibleHttpPort; - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); - jsonrpcServer = shared_ptr(new dev::WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector(), keyManager, *gasPricer)); - jsonrpcServer->setMiningBenefactorChanger([&](Address const& a) { beneficiary = a; }); - jsonrpcServer->StartListening(); - if (jsonAdmin.empty()) - jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Priviledge::Admin}}); - else - jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Priviledge::Admin}}); - cout << "JSONRPC Admin Session Key: " << jsonAdmin << endl; + cerr << "Bad " << arg << " option: " << m << endl; + return -1; } - else if (cmd == "jsonstop") - { - if (jsonrpcServer.get()) - jsonrpcServer->StopListening(); - jsonrpcServer.reset(); + } + else if (arg == "--network-id" && i + 1 < argc) + try { + networkId = stol(argv[++i]); } -#endif - else if (cmd == "address") + catch (...) { - cout << "Current mining beneficiary:" << endl << beneficiary << endl; - cout << "Current signing account:" << endl << signingKey << endl; + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } - else if (c && cmd == "blockhashfromnumber") - { - if (iss.peek() != -1) - { - unsigned number; - iss >> number; - cout << " hash of block: " << c->hashFromNumber(number).hex() << endl; - } + else if (arg == "-K" || arg == "--kill-blockchain" || arg == "--kill") + withExisting = WithExisting::Kill; + else if (arg == "-R" || arg == "--rebuild") + withExisting = WithExisting::Verify; + else if (arg == "-R" || arg == "--rescue") + withExisting = WithExisting::Rescue; + else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) + { + if (arg == "-c") + cerr << "-c is DEPRECATED. It will be removed for the Frontier. Use --client-name instead." << endl; + clientName = argv[++i]; + } + else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) + try { + beneficiary = h160(fromHex(argv[++i], WhenError::Throw)); } - else if (c && cmd == "numberfromblockhash") + catch (BadHexCharacter&) { - if (iss.peek() != -1) - { - string stringHash; - iss >> stringHash; - - h256 hash = h256(fromHex(stringHash)); - cout << " number of block: " << c->numberFromHash(hash) << endl; - } + cerr << "Bad hex in " << arg << " option: " << argv[i] << endl; + return -1; } - else if (c && cmd == "block") + catch (...) { - cout << "Current block: " << c->blockChain().details().number << endl; + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } - else if (c && cmd == "blockqueue") + else if ((arg == "-s" || arg == "--import-secret") && i + 1 < argc) + { + Secret s(fromHex(argv[++i])); + toImport.push_back(s); + signingKey = toAddress(s); + } + else if ((arg == "-S" || arg == "--import-session-secret") && i + 1 < argc) + { + Secret s(fromHex(argv[++i])); + toImport.push_back(s); + sessionKey = toAddress(s); + } + else if ((arg == "--sign-key") && i + 1 < argc) + sessionKey = Address(fromHex(argv[++i])); + else if ((arg == "--session-sign-key") && i + 1 < argc) + sessionKey = Address(fromHex(argv[++i])); + else if (arg == "--structured-logging-format" && i + 1 < argc) + structuredLoggingFormat = string(argv[++i]); + else if (arg == "--structured-logging") + structuredLogging = true; + 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 == "--genesis-nonce" && i + 1 < argc) + { + try { - cout << "Current blockqueue status: " << endl << c->blockQueueStatus() << endl; + CanonBlockChain::setGenesisNonce(Nonce(argv[++i])); } - else if (c && cmd == "findblock") + catch (...) { - if (iss.peek() != -1) - { - string stringHash; - iss >> stringHash; - - h256 hash = h256(fromHex(stringHash)); - - // search in blockchain - cout << "search in blockchain... " << endl; - try - { - cout << c->blockInfo(hash) << endl; - } - catch(Exception& _e) - { - cout << "block not in blockchain" << endl; - cout << boost::diagnostic_information(_e) << endl; - } - - cout << "search in blockqueue... " << endl; - - switch(c->blockQueue().blockStatus(hash)) - { - case QueueStatus::Ready: - cout << "Ready" << endl; - break; - case QueueStatus::Importing: - cout << "Importing" << endl; - break; - case QueueStatus::UnknownParent: - cout << "UnknownParent" << endl; - break; - case QueueStatus::Bad: - cout << "Bad" << endl; - break; - case QueueStatus::Unknown: - cout << "Unknown" << endl; - break; - default: - cout << "invalid queueStatus" << endl; - } - } - else - cwarn << "Require parameter: findblock HASH"; + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } - else if (c && cmd == "firstunknown") + } +/* else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc) + { + try { - cout << "first unknown blockhash: " << c->blockQueue().firstUnknown().hex() << endl; + blockFees = stof(argv[++i]); } - else if (c && cmd == "retryunknown") + catch (...) { - c->retryUnknown(); + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } - else if (cmd == "peers") + } + else if ((arg == "-e" || arg == "--ether-price") && i + 1 < argc) + { + try { - for (auto it: web3.peers()) - cout << it.host << ":" << it.port << ", " << it.clientVersion << ", " - << std::chrono::duration_cast(it.lastPing).count() << "ms" - << endl; + etherPrice = stof(argv[++i]); } - else if (cmd == "newaccount") + catch (...) { - 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); + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } - else if (c && cmd == "accounts") + }*/ + else if (arg == "--ask" && i + 1 < argc) + { + try { - cout << "Accounts:" << endl; - u256 total = 0; - for (auto const& address: keyManager.accounts()) - { - auto b = c->balanceAt(address); - cout << ((address == signingKey) ? "SIGNING " : " ") << ((address == beneficiary) ? "COINBASE " : " ") << keyManager.accountName(address) << " (" << address << "): " << formatBalance(b) << " = " << b << " wei" << endl; - total += b; - } - cout << "Total: " << formatBalance(total) << " = " << total << " wei" << endl; + askPrice = u256(argv[++i]); } - else if (c && cmd == "transact") + catch (...) { - auto const& bc =c->blockChain(); - auto h = bc.currentHash(); - auto blockData = bc.block(h); - BlockInfo info(blockData); - if (iss.peek() != -1) - { - string hexAddr; - u256 amount; - u256 gasPrice; - u256 gas; - string sechex; - string sdata; - - iss >> hexAddr >> amount >> gasPrice >> gas >> sechex >> sdata; - - if (!gasPrice) - gasPrice = gasPricer->bid(priority); - - cnote << "Data:"; - cnote << sdata; - bytes data = dev::eth::parseData(sdata); - cnote << "Bytes:"; - string sbd = asString(data); - bytes bbd = asBytes(sbd); - stringstream ssbd; - ssbd << bbd; - cnote << ssbd.str(); - int ssize = sechex.length(); - int size = hexAddr.length(); - u256 minGas = (u256)Transaction::gasRequired(data, 0); - if (size < 40) - { - if (size > 0) - cwarn << "Invalid address length:" << size; - } - else if (gas < minGas) - cwarn << "Minimum gas amount is" << minGas; - else if (ssize < 40) - { - if (ssize > 0) - cwarn << "Invalid secret length:" << ssize; - } - else - { - try - { - Secret secret = h256(fromHex(sechex)); - Address dest = h160(fromHex(hexAddr)); - c->submitTransaction(secret, amount, dest, data, gas, gasPrice); - } - catch (BadHexCharacter& _e) - { - cwarn << "invalid hex character, transaction rejected"; - cwarn << boost::diagnostic_information(_e); - } - catch (...) - { - cwarn << "transaction rejected"; - } - } - } - else - cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA"; + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } - - else if (c && cmd == "transactnonce") + } + else if (arg == "--bid" && i + 1 < argc) + { + try { - auto const& bc =c->blockChain(); - auto h = bc.currentHash(); - auto blockData = bc.block(h); - BlockInfo info(blockData); - if (iss.peek() != -1) - { - string hexAddr; - u256 amount; - u256 gasPrice; - u256 gas; - string sechex; - string sdata; - u256 nonce; - - iss >> hexAddr >> amount >> gasPrice >> gas >> sechex >> sdata >> nonce; - - if (!gasPrice) - gasPrice = gasPricer->bid(priority); - - cnote << "Data:"; - cnote << sdata; - bytes data = dev::eth::parseData(sdata); - cnote << "Bytes:"; - string sbd = asString(data); - bytes bbd = asBytes(sbd); - stringstream ssbd; - ssbd << bbd; - cnote << ssbd.str(); - int ssize = sechex.length(); - int size = hexAddr.length(); - u256 minGas = (u256)Transaction::gasRequired(data, 0); - if (size < 40) - { - if (size > 0) - cwarn << "Invalid address length:" << size; - } - else if (gas < minGas) - cwarn << "Minimum gas amount is" << minGas; - else if (ssize < 40) - { - if (ssize > 0) - cwarn << "Invalid secret length:" << ssize; - } - else - { - try - { - Secret secret = h256(fromHex(sechex)); - Address dest = h160(fromHex(hexAddr)); - c->submitTransaction(secret, amount, dest, data, gas, gasPrice, nonce); - } - catch (BadHexCharacter& _e) - { - cwarn << "invalid hex character, transaction rejected"; - cwarn << boost::diagnostic_information(_e); - } - catch (...) - { - cwarn << "transaction rejected"; - } - } - } - else - cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET DATA NONCE"; + bidPrice = u256(argv[++i]); } - - else if (c && cmd == "txcreate") + catch (...) { - auto const& bc =c->blockChain(); - auto h = bc.currentHash(); - auto blockData = bc.block(h); - BlockInfo info(blockData); - if (iss.peek() != -1) - { - u256 amount; - u256 gasPrice; - u256 gas; - string sechex; - string sdata; - - iss >> amount >> gasPrice >> gas >> sechex >> sdata; - - if (!gasPrice) - gasPrice = gasPricer->bid(priority); - - cnote << "Data:"; - cnote << sdata; - bytes data = dev::eth::parseData(sdata); - cnote << "Bytes:"; - string sbd = asString(data); - bytes bbd = asBytes(sbd); - stringstream ssbd; - ssbd << bbd; - cnote << ssbd.str(); - int ssize = sechex.length(); - u256 minGas = (u256)Transaction::gasRequired(data, 0); - if (gas < minGas) - cwarn << "Minimum gas amount is" << minGas; - else if (ssize < 40) - { - if (ssize > 0) - cwarn << "Invalid secret length:" << ssize; - } - else - { - try - { - Secret secret = h256(fromHex(sechex)); - cout << " new contract address : " << c->submitTransaction(secret, amount, data, gas, gasPrice) << endl; - } - catch (BadHexCharacter& _e) - { - cwarn << "invalid hex character, transaction rejected"; - cwarn << boost::diagnostic_information(_e); - } - catch (...) - { - cwarn << "transaction rejected"; - } - } - } - else - cwarn << "Require parameters: submitTransaction ADDRESS AMOUNT GASPRICE GAS SECRET INIT"; + cerr << "Bad " << arg << " option: " << argv[i] << endl; + return -1; } -#if ETH_FATDB - else if (c && cmd == "listcontracts") + } + else if ((arg == "-P" || arg == "--priority") && i + 1 < argc) + { + string m = boost::to_lower_copy(string(argv[++i])); + if (m == "lowest") + priority = TransactionPriority::Lowest; + else if (m == "low") + priority = TransactionPriority::Low; + else if (m == "medium" || m == "mid" || m == "default" || m == "normal") + priority = TransactionPriority::Medium; + else if (m == "high") + priority = TransactionPriority::High; + else if (m == "highest") + priority = TransactionPriority::Highest; + else + try { + priority = (TransactionPriority)(max(0, min(100, stoi(m))) * 8 / 100); + } + catch (...) { + cerr << "Unknown " << arg << " option: " << m << endl; + return -1; + } + } + else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) + { + string m = argv[++i]; + if (isTrue(m)) + mining = ~(unsigned)0; + else if (isFalse(m)) + mining = 0; + else + try { + mining = stoi(m); + } + catch (...) { + cerr << "Unknown " << arg << " option: " << m << endl; + return -1; + } + } + else if (arg == "-b" || arg == "--bootstrap") + bootstrap = true; + else if (arg == "--no-discovery") + disableDiscovery = true; + else if (arg == "--pin") + pinning = true; + else if (arg == "-f" || arg == "--force-mining") + forceMining = true; + else if (arg == "-i" || arg == "--interactive") + interactive = true; +#if ETH_JSONRPC + else if ((arg == "-j" || arg == "--json-rpc")) + jsonrpc = jsonrpc == -1 ? SensibleHttpPort : jsonrpc; + else if (arg == "--json-rpc-port" && i + 1 < argc) + jsonrpc = atoi(argv[++i]); + else if (arg == "--json-admin" && i + 1 < argc) + jsonAdmin = argv[++i]; +#endif +#if ETH_JSCONSOLE + else if (arg == "--console") + useConsole = true; +#endif + else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) + g_logVerbosity = atoi(argv[++i]); + else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) + peers = atoi(argv[++i]); + else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) + { + string m = argv[++i]; + if (m == "full") + nodeMode = NodeMode::Full; + else if (m == "peer") + nodeMode = NodeMode::PeerServer; + else { - auto acs =c->addresses(); - string ss; - for (auto const& i: acs) - if ( c->codeAt(i, PendingBlock).size()) - { - ss = toString(i) + " : " + toString( c->balanceAt(i)) + " [" + toString((unsigned) c->countAt(i)) + "]"; - cout << ss << endl; - } + cerr << "Unknown mode: " << m << endl; + return -1; } - else if (c && cmd == "listaccounts") + } +#if ETH_EVMJIT + else if (arg == "--vm" && i + 1 < argc) + { + string vmKind = argv[++i]; + if (vmKind == "interpreter") + VMFactory::setKind(VMKind::Interpreter); + else if (vmKind == "jit") + VMFactory::setKind(VMKind::JIT); + else if (vmKind == "smart") + VMFactory::setKind(VMKind::Smart); + else { - auto acs =c->addresses(); - string ss; - for (auto const& i: acs) - if ( c->codeAt(i, PendingBlock).empty()) - { - ss = toString(i) + " : " + toString( c->balanceAt(i)) + " [" + toString((unsigned) c->countAt(i)) + "]"; - cout << ss << endl; - } + cerr << "Unknown VM kind: " << vmKind << endl; + return -1; } - else if (c && cmd == "balanceat") - { - if (iss.peek() != -1) - { - string stringHash; - iss >> stringHash; + } +#endif + else if (arg == "-h" || arg == "--help") + help(); + else if (arg == "-V" || arg == "--version") + version(); + else + { + cerr << "Invalid argument: " << arg << endl; + exit(-1); + } + } + + if (g_logVerbosity > 0) + { + cout << EthGrayBold "(++)Ethereum" EthReset << endl; + if (c_network == eth::Network::Olympic) + cout << "Welcome to Olympic!" << endl; + else if (c_network == eth::Network::Frontier) + cout << "Welcome to the " EthMaroonBold "Frontier" EthReset "!" << endl; + } - Address address = h160(fromHex(stringHash)); + m.execute(); - cout << "balance of " << stringHash << " is: " << toString(c->balanceAt(address)) << endl; - } - } - else if (c && cmd == "balanceatblock") - { - if (iss.peek() != -1) - { - string stringHash; - unsigned blocknumber; - iss >> stringHash >> blocknumber; + KeyManager keyManager; + for (auto const& s: passwordsToNote) + keyManager.notePassword(s); - Address address = h160(fromHex(stringHash)); + writeFile(configFile, rlpList(signingKey, beneficiary)); - cout << "balance of " << stringHash << " is: " << toString(c->balanceAt(address, blocknumber)) << endl; - } - } - else if (c && cmd == "storageat") + if (sessionKey) + signingKey = sessionKey; + + if (!clientName.empty()) + clientName += "/"; + + string logbuf; + std::string additional; + if (interactive) + g_logPost = [&](std::string const& a, char const*){ + static SpinLock s_lock; + SpinGuard l(s_lock); + + if (g_silence) + logbuf += a + "\n"; + else + cout << "\r \r" << a << endl << additional << flush; + + // helpful to use OutputDebugString on windows + #ifdef _WIN32 { - if (iss.peek() != -1) - { - string stringHash; - iss >> stringHash; + OutputDebugStringA(a.data()); + OutputDebugStringA("\n"); + } + #endif + }; + + auto getPassword = [&](string const& prompt){ + auto s = g_silence; + g_silence = true; + cout << endl; + string ret = dev::getPassword(prompt); + g_silence = s; + return ret; + }; + auto getAccountPassword = [&](Address const& a){ + return getPassword("Enter password for address " + keyManager.accountName(a) + " (" + a.abridged() + "; hint:" + keyManager.passwordHint(a) + "): "); + }; + + 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); + netPrefs.discovery = !disableDiscovery; + netPrefs.pin = pinning; + auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp"); + dev::WebThreeDirect web3( + WebThreeDirect::composeClientVersion("++eth", clientName), + dbPath, + withExisting, + nodeMode == NodeMode::Full ? set{"eth"/*, "shh"*/} : set(), + netPrefs, + &nodesState); + web3.ethereum()->setMineOnBadChain(mineOnWrongChain); + web3.ethereum()->setSentinel(sentinel); + + auto toNumber = [&](string const& s) -> unsigned { + if (s == "latest") + return web3.ethereum()->number(); + if (s.size() == 64 || (s.size() == 66 && s.substr(0, 2) == "0x")) + return web3.ethereum()->blockChain().number(h256(s)); + try { + return stol(s); + } + catch (...) + { + cerr << "Bad block number/hash option: " << s << endl; + exit(-1); + } + }; - Address address = h160(fromHex(stringHash)); + if (mode == OperationMode::Export) + { + ofstream fout(filename, std::ofstream::binary); + ostream& out = (filename.empty() || filename == "--") ? cout : fout; - cout << "storage at " << stringHash << " is: " << endl; - for (auto s: c->storageAt(address)) - cout << toHex(s.first) << " : " << toHex(s.second) << endl; - } - } - else if (c && cmd == "storageatblock") + unsigned last = toNumber(exportTo); + for (unsigned i = toNumber(exportFrom); i <= last; ++i) + { + bytes block = web3.ethereum()->blockChain().block(web3.ethereum()->blockChain().numberHash(i)); + switch (exportFormat) { - if (iss.peek() != -1) - { - string stringHash; - unsigned blocknumber; - iss >> stringHash >> blocknumber; - - Address address = h160(fromHex(stringHash)); - - cout << "storage at " << stringHash << " is: " << endl; - for (auto s: c->storageAt(address, blocknumber)) - cout << "\"0x" << toHex(s.first) << "\" : \"0x" << toHex(s.second) << "\"," << endl; - } + case Format::Binary: out.write((char const*)block.data(), block.size()); break; + case Format::Hex: out << toHex(block) << endl; break; + case Format::Human: out << RLP(block) << endl; break; + default:; } - else if (c && cmd == "codeat") - { - if (iss.peek() != -1) - { - string stringHash; - iss >> stringHash; + } + return 0; + } - Address address = h160(fromHex(stringHash)); + if (mode == OperationMode::Import) + { + ifstream fin(filename, std::ifstream::binary); + istream& in = (filename.empty() || filename == "--") ? cin : fin; + unsigned alreadyHave = 0; + unsigned good = 0; + unsigned futureTime = 0; + unsigned unknownParent = 0; + unsigned bad = 0; + chrono::steady_clock::time_point t = chrono::steady_clock::now(); + double last = 0; + unsigned lastImported = 0; + unsigned imported = 0; + while (in.peek() != -1) + { + bytes block(8); + in.read((char*)block.data(), 8); + block.resize(RLP(block, RLP::LaissezFaire).actualSize()); + in.read((char*)block.data() + 8, block.size() - 8); - cout << "code at " << stringHash << " is: " << toHex(c->codeAt(address)) << endl; - } + switch (web3.ethereum()->queueBlock(block, safeImport)) + { + case ImportResult::Success: good++; break; + case ImportResult::AlreadyKnown: alreadyHave++; break; + case ImportResult::UnknownParent: unknownParent++; break; + case ImportResult::FutureTimeUnknown: unknownParent++; futureTime++; break; + case ImportResult::FutureTimeKnown: futureTime++; break; + default: bad++; break; } -#endif - else if (c && cmd == "send") - { - if (iss.peek() != -1) - { - string hexAddr; - u256 amount; + // sync chain with queue + tuple r = web3.ethereum()->syncQueue(10); + imported += get<2>(r); - iss >> hexAddr >> amount; - int size = hexAddr.length(); - if (size < 40) - { - if (size > 0) - cwarn << "Invalid address length:" << size; - } - else - { - auto const& bc =c->blockChain(); - auto h = bc.currentHash(); - auto blockData = bc.block(h); - BlockInfo info(blockData); - u256 minGas = (u256)Transaction::gasRequired(bytes(), 0); - try - { - Address dest = h160(fromHex(hexAddr, WhenError::Throw)); - c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), amount, dest, bytes(), minGas); - } - catch (BadHexCharacter& _e) - { - cwarn << "invalid hex character, transaction rejected"; - cwarn << boost::diagnostic_information(_e); - } - catch (...) - { - cwarn << "transaction rejected"; - } - } - } - else - cwarn << "Require parameters: send ADDRESS AMOUNT"; - } - else if (c && cmd == "contract") - { - auto const& bc =c->blockChain(); - auto h = bc.currentHash(); - auto blockData = bc.block(h); - BlockInfo info(blockData); - if (iss.peek() != -1) - { - u256 endowment; - u256 gas; - u256 gasPrice; - string sinit; - iss >> endowment >> gasPrice >> gas >> sinit; - trim_all(sinit); - int size = sinit.length(); - bytes init; - cnote << "Init:"; - cnote << sinit; - cnote << "Code size:" << size; - if (size < 1) - cwarn << "No code submitted"; - else - { - cnote << "Assembled:"; - stringstream ssc; - try - { - init = fromHex(sinit, WhenError::Throw); - } - catch (BadHexCharacter& _e) - { - cwarn << "invalid hex character, code rejected"; - cwarn << boost::diagnostic_information(_e); - init = bytes(); - } - catch (...) - { - cwarn << "code rejected"; - init = bytes(); - } - ssc.str(string()); - ssc << disassemble(init); - cnote << "Init:"; - cnote << ssc.str(); - } - u256 minGas = (u256)Transaction::gasRequired(init, 0); - if (!init.size()) - cwarn << "Contract creation aborted, no init code."; - else if (endowment < 0) - cwarn << "Invalid endowment"; - else if (gas < minGas) - cwarn << "Minimum gas amount is" << minGas; - else - c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), endowment, init, gas, gasPrice); - } - else - cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX"; - } - else if (c && cmd == "dumpreceipt") - { - unsigned block; - unsigned index; - iss >> block >> index; - dev::eth::TransactionReceipt r = c->blockChain().receipts(c->blockChain().numberHash(block)).receipts[index]; - auto rb = r.rlp(); - cout << "RLP: " << RLP(rb) << endl; - cout << "Hex: " << toHex(rb) << endl; - cout << r << endl; - } - else if (c && cmd == "reprocess") - { - string block; - iss >> block; - h256 blockHash; - try - { - if (block.size() == 64 || block.size() == 66) - blockHash = h256(block); - else - blockHash = c->blockChain().numberHash(stoi(block)); - c->state(blockHash); - } - catch (...) - {} - } - else if (c && cmd == "dumptrace") + double e = chrono::duration_cast(chrono::steady_clock::now() - t).count() / 1000.0; + if ((unsigned)e >= last + 10) { - unsigned block; - unsigned index; - string filename; - string format; - iss >> block >> index >> filename >> format; - ofstream f; - f.open(filename); - - dev::eth::State state = c->state(index + 1,c->blockChain().numberHash(block)); - if (index < state.pending().size()) - { - Executive e(state, c->blockChain(), 0); - Transaction t = state.pending()[index]; - state = state.fromPending(index); - try - { - OnOpFunc oof; - if (format == "pretty") - oof = [&](uint64_t steps, Instruction instr, bigint newMemSize, bigint gasCost, bigint gas, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM) - { - dev::eth::VM* vm = vvm; - dev::eth::ExtVM const* ext = static_cast(vextVM); - f << endl << " STACK" << endl; - for (auto i: vm->stack()) - f << (h256)i << endl; - f << " MEMORY" << endl << dev::memDump(vm->memory()); - f << " STORAGE" << endl; - for (auto const& i: ext->state().storage(ext->myAddress)) - f << showbase << hex << i.first << ": " << i.second << endl; - f << dec << ext->depth << " | " << ext->myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm->curPC() << " : " << dev::eth::instructionInfo(instr).name << " | " << dec << gas << " | -" << dec << gasCost << " | " << newMemSize << "x32"; - }; - else if (format == "standard") - oof = [&](uint64_t, Instruction instr, bigint, bigint, bigint gas, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM) - { - dev::eth::VM* vm = vvm; - dev::eth::ExtVM const* ext = static_cast(vextVM); - f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)gas, 1)) << endl; - }; - else if (format == "standard+") - oof = [&](uint64_t, Instruction instr, bigint, bigint, bigint gas, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM) - { - dev::eth::VM* vm = vvm; - dev::eth::ExtVM const* ext = static_cast(vextVM); - if (instr == Instruction::STOP || instr == Instruction::RETURN || instr == Instruction::SUICIDE) - for (auto const& i: ext->state().storage(ext->myAddress)) - f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl; - f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)gas, 1)) << endl; - }; - e.initialize(t); - if (!e.execute()) - e.go(oof); - e.finalize(); - } - catch(Exception const& _e) - { - // TODO: a bit more information here. this is probably quite worrying as the transaction is already in the blockchain. - cwarn << diagnostic_information(_e); - } - } + auto i = imported - lastImported; + auto d = e - last; + cout << i << " more imported at " << (round(i * 10 / d) / 10) << " blocks/s. " << imported << " imported in " << e << " seconds at " << (round(imported * 10 / e) / 10) << " blocks/s (#" << web3.ethereum()->number() << ")" << endl; + last = (unsigned)e; + lastImported = imported; +// cout << web3.ethereum()->blockQueueStatus() << endl; } - else if (c && cmd == "inspect") - { - string rechex; - iss >> rechex; + } - if (rechex.length() != 40) - cwarn << "Invalid address length"; - else - { - auto h = h160(fromHex(rechex)); - stringstream s; + while (web3.ethereum()->blockQueue().items().first + web3.ethereum()->blockQueue().items().second > 0) + { + this_thread::sleep_for(chrono::seconds(1)); + web3.ethereum()->syncQueue(100000); + } + double e = chrono::duration_cast(chrono::steady_clock::now() - t).count() / 1000.0; + cout << imported << " imported in " << e << " seconds at " << (round(imported * 10 / e) / 10) << " blocks/s (#" << web3.ethereum()->number() << ")" << endl; + return 0; + } - try - { - auto storage =c->storageAt(h, PendingBlock); - for (auto const& i: storage) - s << "@" << showbase << hex << i.first << " " << showbase << hex << i.second << endl; - s << endl << disassemble( c->codeAt(h, PendingBlock)) << endl; - - string outFile = getDataDir() + "/" + rechex + ".evm"; - ofstream ofs; - ofs.open(outFile, ofstream::binary); - ofs.write(s.str().c_str(), s.str().length()); - ofs.close(); - - cnote << "Saved" << rechex << "to" << outFile; - } - catch (dev::InvalidTrie) - { - cwarn << "Corrupted trie."; - } - } - } - else if (cmd == "setsigningkey") - { - if (iss.peek() != -1) - { - string hexSec; - iss >> hexSec; - signingKey = Address(fromHex(hexSec)); - } - else - cwarn << "Require parameter: setSecret HEXSECRETKEY"; - } - else if (cmd == "setaddress") - { - if (iss.peek() != -1) + if (c_network == eth::Network::Frontier && !yesIReallyKnowWhatImDoing) + { + auto pd = contents(getDataDir() + "primes"); + unordered_set primes = RLP(pd).toUnorderedSet(); + while (true) + { + if (!prime) + try { - string hexAddr; - iss >> hexAddr; - if (hexAddr.length() != 40) - cwarn << "Invalid address length: " << hexAddr.length(); - else - { - try - { - beneficiary = h160(fromHex(hexAddr, WhenError::Throw)); - } - catch (BadHexCharacter& _e) - { - cwarn << "invalid hex character, coinbase rejected"; - cwarn << boost::diagnostic_information(_e); - } - catch (...) - { - cwarn << "coinbase rejected"; - } - } + prime = stoi(getPassword("To enter the Frontier, enter a 6 digit prime that you have not entered before: ")); } - else - cwarn << "Require parameter: setAddress HEXADDRESS"; - } - else if (cmd == "exportconfig") + catch (...) {} + if (isPrime(prime) && !primes.count(prime)) + break; + prime = 0; + } + primes.insert(prime); + writeFile(getDataDir() + "primes", rlp(primes)); + } + + if (keyManager.exists()) + { + if (masterPassword.empty() || !keyManager.load(masterPassword)) + while (true) { - if (iss.peek() != -1) - { - string path; - iss >> path; - RLPStream config(2); - config << signingKey << beneficiary; - writeFile(path, config.out()); - } - else - cwarn << "Require parameter: exportConfig PATH"; + masterPassword = getPassword("Please enter your MASTER password: "); + if (keyManager.load(masterPassword)) + break; + cout << "Password invalid. Try again." << endl; } - else if (cmd == "importconfig") + } + else + { + while (masterPassword.empty()) + { + masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): "); + string confirm = getPassword("Please confirm the password by entering it again: "); + if (masterPassword != confirm) { - if (iss.peek() != -1) - { - string path; - iss >> path; - bytes b = contents(path); - if (b.size()) - { - RLP config(b); - signingKey = config[0].toHash
(); - beneficiary = config[1].toHash
(); - } - else - cwarn << path << "has no content!"; - } - else - cwarn << "Require parameter: importConfig PATH"; + cout << "Passwords were different. Try again." << endl; + masterPassword.clear(); } - else if (cmd == "help") - interactiveHelp(); - else if (cmd == "exit") - break; - else - cout << "Unrecognised command. Type 'help' for help in interactive mode." << endl; } -#if ETH_JSONRPC - if (jsonrpcServer.get()) - jsonrpcServer->StopListening(); -#endif + keyManager.create(masterPassword); + } + + for (auto const& s: toImport) + { + keyManager.import(s, "Imported key (UNSAFE)"); + if (!signingKey) + signingKey = toAddress(s); + } + + 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)); + std::shared_ptr gasPricer = make_shared(askPrice, bidPrice); + eth::Client* c = nodeMode == NodeMode::Full ? web3.ethereum() : nullptr; + StructuredLogger::starting(WebThreeDirect::composeClientVersion("++eth", clientName), 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; + + if (bootstrap || !remoteHost.empty() || disableDiscovery) + { + web3.startNetwork(); + cout << "Node ID: " << web3.enode() << endl; + } + else + cout << "Networking disabled. To start, use netstart or pass -b or a remote host." << endl; + + if (useConsole && jsonrpc == -1) + jsonrpc = SensibleHttpPort; + +#if ETH_JSONRPC || !ETH_TRUE + shared_ptr jsonrpcServer; + unique_ptr jsonrpcConnector; + if (jsonrpc > -1) + { + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); + jsonrpcServer = make_shared(*jsonrpcConnector.get(), web3, make_shared([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector(), keyManager, *gasPricer); + jsonrpcServer->setMiningBenefactorChanger([&](Address const& a) { beneficiary = a; }); + jsonrpcServer->StartListening(); + if (jsonAdmin.empty()) + jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Priviledge::Admin}}); + else + jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Priviledge::Admin}}); + cout << "JSONRPC Admin Session Key: " << jsonAdmin << endl; } +#endif + + if (bootstrap) + for (auto const& i: Host::pocHosts()) + web3.requirePeer(i.first, i.second); + if (!remoteHost.empty()) + web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort)); + + signal(SIGABRT, &sighandler); + signal(SIGTERM, &sighandler); + signal(SIGINT, &sighandler); + + if (interactive) + interactiveMode(c, gasPricer, web3, keyManager, logbuf, additional, getPassword, getAccountPassword, netPrefs, beneficiary, signingKey, priority); else if (c) { - unsigned n =c->blockChain().details().number; + unsigned n = c->blockChain().details().number; if (mining) c->startMining(); if (useConsole) { -#if ETH_JSCONSOLE +#if ETH_JSCONSOLE || !ETH_TRUE JSLocalConsole console; - - jsonrpcServer = shared_ptr(new dev::WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector(), keyManager, *gasPricer)); - jsonrpcServer->setMiningBenefactorChanger([&](Address const& a) { beneficiary = a; }); - jsonrpcServer->StartListening(); - if (jsonAdmin.empty()) - jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Priviledge::Admin}}); - else - jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Priviledge::Admin}}); - cout << "JSONRPC Admin Session Key: " << jsonAdmin << endl; - + shared_ptr rpcServer = make_shared(*console.connector(), web3, make_shared([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector(), keyManager, *gasPricer); while (!g_exit) { console.readExpression(); stopMiningAfterXBlocks(c, n, mining); } - - jsonrpcServer->StopListening(); + rpcServer->StopListening(); #endif } else @@ -1857,10 +1771,14 @@ int main(int argc, char** argv) while (!g_exit) this_thread::sleep_for(chrono::milliseconds(1000)); +#if ETH_JSONRPC + if (jsonrpcServer.get()) + jsonrpcServer->StopListening(); +#endif + StructuredLogger::stopping(WebThreeDirect::composeClientVersion("++eth", clientName), dev::Version); auto netData = web3.saveNetwork(); if (!netData.empty()) writeFile((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp", netData); return 0; } - diff --git a/ethconsole/CMakeLists.txt b/ethconsole/CMakeLists.txt index 08fa7ca83..0101320d0 100644 --- a/ethconsole/CMakeLists.txt +++ b/ethconsole/CMakeLists.txt @@ -13,9 +13,7 @@ set(EXECUTABLE ethconsole) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) - target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) -target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${CURL_LIBRARIES}) if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW) diff --git a/ethkey/KeyAux.h b/ethkey/KeyAux.h index ae8eaed92..af7d8e048 100644 --- a/ethkey/KeyAux.h +++ b/ethkey/KeyAux.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "BuildInfo.h" using namespace std; using namespace dev; @@ -105,7 +106,9 @@ public: ImportWithAddress, Export, Recode, - Kill + Kill, + SignTx, + DecodeTx, }; KeyCLI(OperationMode _mode = OperationMode::None): m_mode(_mode) {} @@ -131,8 +134,13 @@ public: auto v = argv[++i]; m_kdfParams[n] = v; } - else if (arg == "--new-bare") - m_mode = OperationMode::NewBare; + else if (arg == "--sign-tx" && i + 1 < argc) + { + m_mode = OperationMode::SignTx; + m_signKey = argv[++i]; + } + else if (arg == "--decode-tx") + m_mode = OperationMode::DecodeTx; else if (arg == "--import-bare") m_mode = OperationMode::ImportBare; else if (arg == "--list-bare") @@ -173,7 +181,7 @@ public: m_mode = OperationMode::Recode; else if (arg == "--no-icap") m_icap = false; - else if (m_mode == OperationMode::ImportBare || m_mode == OperationMode::InspectBare || m_mode == OperationMode::KillBare || m_mode == OperationMode::Recode || m_mode == OperationMode::Export || m_mode == OperationMode::RecodeBare || m_mode == OperationMode::ExportBare) + else if (m_mode == OperationMode::DecodeTx || m_mode == OperationMode::SignTx || m_mode == OperationMode::ImportBare || m_mode == OperationMode::InspectBare || m_mode == OperationMode::KillBare || m_mode == OperationMode::Recode || m_mode == OperationMode::Export || m_mode == OperationMode::RecodeBare || m_mode == OperationMode::ExportBare) m_inputs.push_back(arg); else return false; @@ -209,6 +217,127 @@ public: } } } + else if (m_mode == OperationMode::DecodeTx) + { + string const& i = m_inputs[0]; + bytes b = fromHex(i); + if (b.empty()) + { + std::string s = contentsString(i); + b = fromHex(s); + if (b.empty()) + b = asBytes(s); + } + if (b.empty()) + cerr << "Unknown file or bad hex: " << i << endl; + else + try + { + TransactionBase t(b, CheckTransaction::Everything); + cout << "Transaction " << t.sha3().hex() << endl; + if (t.isCreation()) + { + cout << " type: creation" << endl; + cout << " code: " << toHex(t.data()) << endl; + } + else + { + cout << " type: message" << endl; + cout << " to: " << t.to().hex() << endl; + cout << " data: " << (t.data().empty() ? "none" : toHex(t.data())) << endl; + } + cout << " from: " << t.from().hex() << endl; + cout << " value: " << formatBalance(t.value()) << " (" << t.value() << " wei)" << endl; + cout << " nonce: " << t.nonce() << endl; + cout << " gas: " << t.gas() << endl; + cout << " gas price: " << formatBalance(t.gasPrice()) << " (" << t.gasPrice() << " wei)" << endl; + cout << " signing hash: " << t.sha3(WithoutSignature).hex() << endl; + cout << " v: " << (int)t.signature().v << endl; + cout << " r: " << t.signature().r << endl; + cout << " s: " << t.signature().s << endl; + } + catch (Exception& ex) + { + cerr << "Invalid transaction: " << ex.what() << endl; + } + } + else if (m_mode == OperationMode::SignTx) + { + Secret s; + + string json = contentsString(m_signKey); + if (!json.empty()) + { + SecretStore store(m_secretsPath); + s = Secret(store.secret(store.readKeyContent(json), [&](){ return getPassword("Enter password for key: "); })); + } + else + { + if (h128 u = fromUUID(m_signKey)) + { + SecretStore store(m_secretsPath); + s = Secret(store.secret(u, [&](){ return getPassword("Enter password for key: "); })); + } + else if (Address a = Address(m_signKey)) + { + KeyManager wallet(m_walletPath, m_secretsPath); + if (wallet.exists()) + { + openWallet(wallet); + s = wallet.secret(a, [&](){ return getPassword("Enter password for key: "); }); + } + else + { + cerr << "Wallet doesn't exist." << endl; + exit(-1); + } + } + else + { + cerr << "Bad file, UUID and address: " << m_signKey << endl; + exit(-1); + } + } + if (!s) + { + cerr << "UUID/address not found: " << m_signKey << endl; + exit(-1); + } + + for (string const& i: m_inputs) + { + bytes b = fromHex(i); + bool isFile = false; + if (b.empty()) + { + isFile = true; + std::string s = contentsString(i); + b = fromHex(s); + if (b.empty()) + b = asBytes(s); + } + if (b.empty()) + cerr << "Unknown file or bad hex: " << i << endl; + else + try + { + TransactionBase t(b, CheckTransaction::None); + t.sign(s); + cout << t.sha3() << ": "; + if (isFile) + { + writeFile(i + ".signed", t.data()); + cout << i + ".signed" << endl; + } + else + cout << toHex(t.data()) << endl; + } + catch (Exception& ex) + { + cerr << "Invalid transaction: " << ex.what() << endl; + } + } + } else if (m_mode < OperationMode::CreateWallet) { SecretStore store(m_secretsPath); @@ -297,17 +426,7 @@ public: { KeyManager wallet(m_walletPath, m_secretsPath); if (wallet.exists()) - while (true) - { - if (wallet.load(m_masterPassword)) - break; - if (!m_masterPassword.empty()) - { - cout << "Password invalid. Try again." << endl; - m_masterPassword.clear(); - } - m_masterPassword = getPassword("Please enter your MASTER password: "); - } + openWallet(wallet); else { cerr << "Couldn't open wallet. Does it exist?" << endl; @@ -419,6 +538,10 @@ public: << " --wallet-path Specify Ethereum wallet path (default: " << KeyManager::defaultPath() << ")" << endl << " -m, --master Specify wallet (master) password." << endl << endl + << "Transaction operating modes:" << endl + << " -d,--decode-tx [|] Decode given transaction." << endl + << " -s,--sign-tx [
|| ] [ | , ... ] (Re-)Sign given transaction." << endl + << endl << "Encryption configuration:" << endl << " --kdf Specify KDF to use when encrypting (default: sc rypt)" << endl << " --kdf-param Specify a parameter for the KDF." << endl @@ -445,6 +568,21 @@ public: } private: + void openWallet(KeyManager& _w) + { + while (true) + { + if (_w.load(m_masterPassword)) + break; + if (!m_masterPassword.empty()) + { + cout << "Password invalid. Try again." << endl; + m_masterPassword.clear(); + } + m_masterPassword = getPassword("Please enter your MASTER password: "); + } + } + KDF kdf() const { return m_kdf == "pbkdf2" ? KDF::PBKDF2_SHA256 : KDF::Scrypt; } /// Operating mode. @@ -468,6 +606,9 @@ private: /// Importing strings m_inputs; + /// Signing + string m_signKey; + string m_kdf = "scrypt"; map m_kdfParams; // string m_cipher; diff --git a/ethminer/CMakeLists.txt b/ethminer/CMakeLists.txt index df828bc47..90889ae12 100644 --- a/ethminer/CMakeLists.txt +++ b/ethminer/CMakeLists.txt @@ -9,6 +9,9 @@ if (JSONRPC) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) endif() +if (ETHASHCL) + include_directories(${OpenCL_INCLUDE_DIRS}) +endif () set(EXECUTABLE ethminer) @@ -40,4 +43,3 @@ if (APPLE) else() eth_install_executable(${EXECUTABLE}) endif() - diff --git a/ethminer/MinerAux.h b/ethminer/MinerAux.h index ec6ee57e7..ff28132b1 100644 --- a/ethminer/MinerAux.h +++ b/ethminer/MinerAux.h @@ -40,6 +40,9 @@ #include #include #include +#if ETH_ETHASHCL || !ETH_TRUE +#include +#endif #if ETH_JSONRPC || !ETH_TRUE #include #include @@ -78,6 +81,12 @@ inline std::string credits() } class BadArgument: public Exception {}; +struct MiningChannel: public LogChannel +{ + static const char* name() { return EthGreen "miner"; } + static const int verbosity = 2; +}; +#define minelog clog(MiningChannel) class MinerCLI { @@ -128,6 +137,35 @@ public: cerr << "Bad " << arg << " option: " << argv[i] << endl; BOOST_THROW_EXCEPTION(BadArgument()); } +#if ETH_ETHASHCL || !ETH_TRUE + else if (arg == "--cl-global-work" && i + 1 < argc) + try { + m_globalWorkSizeMultiplier = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + BOOST_THROW_EXCEPTION(BadArgument()); + } + else if (arg == "--cl-local-work" && i + 1 < argc) + try { + m_localWorkSize = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + BOOST_THROW_EXCEPTION(BadArgument()); + } + else if (arg == "--cl-ms-per-batch" && i + 1 < argc) + try { + m_msPerBatch = stol(argv[++i]); + } + catch (...) + { + cerr << "Bad " << arg << " option: " << argv[i] << endl; + BOOST_THROW_EXCEPTION(BadArgument()); + } +#endif else if (arg == "--list-devices") m_shouldListDevices = true; else if (arg == "--allow-opencl-cpu") @@ -217,7 +255,7 @@ public: 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); + auto r = EthashAux::eval(seedHash, powHash, bi.nonce); bool valid = r.value < boundary; cout << (valid ? "VALID :-)" : "INVALID :-(") << endl; cout << r.value << (valid ? " < " : " >= ") << boundary << endl; @@ -265,18 +303,23 @@ public: ProofOfWork::CPUMiner::setNumInstances(m_miningThreads); else if (m_minerType == MinerType::GPU) { +#if ETH_ETHASHCL || !ETH_TRUE if (!ProofOfWork::GPUMiner::configureGPU( + m_localWorkSize, + m_globalWorkSizeMultiplier, + m_msPerBatch, m_openclPlatform, m_openclDevice, m_clAllowCPU, m_extraGPUMemory, m_currentBlock )) - { - cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl; exit(1); - } ProofOfWork::GPUMiner::setNumInstances(m_miningThreads); +#else + cerr << "Selected GPU mining without having compiled with -DETHASHCL=1" << endl; + exit(1); +#endif } if (mode == OperationMode::DAGInit) doInitDAG(m_initDAG); @@ -317,7 +360,12 @@ public: << " --allow-opencl-cpu Allows CPU to be considered as an OpenCL device if the OpenCL platform supports it." << endl << " --list-devices List the detected OpenCL devices and exit." << endl << " --current-block Let the miner know the current block number at configuration time. Will help determine DAG size and required GPU memory." << endl +#if ETH_ETHASHCL || !ETH_TRUE << " --cl-extragpu-mem Set the memory (in MB) you believe your GPU requires for stuff other than mining. Windows rendering e.t.c.." << endl + << " --cl-local-work Set the OpenCL local work size. Default is " << toString(ethash_cl_miner::c_defaultLocalWorkSize) << endl + << " --cl-global-work Set the OpenCL global work size as a multiple of the local work size. Default is " << toString(ethash_cl_miner::c_defaultGlobalWorkSizeMultiplier) << " * " << toString(ethash_cl_miner::c_defaultLocalWorkSize) << endl + << " --cl-ms-per-batch Set the OpenCL target milliseconds per batch (global workgroup size). Default is " << toString(ethash_cl_miner::c_defaultMSPerBatch) << ". If 0 is given then no autoadjustment of global work size will happen" << endl +#endif ; } @@ -442,14 +490,14 @@ private: for (unsigned i = 0; !completed; ++i) { if (current) - cnote << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); + minelog << "Mining on PoWhash" << current.headerHash << ": " << f.miningProgress(); else - cnote << "Getting work package..."; + minelog << "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; + minelog << "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 (m_precompute) @@ -459,10 +507,10 @@ private: 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(); + minelog << "Got work package:"; + minelog << " Header-hash:" << current.headerHash.hex(); + minelog << " Seedhash:" << current.seedHash.hex(); + minelog << " Target: " << h256(current.boundary).hex(); f.setWork(current); } this_thread::sleep_for(chrono::milliseconds(_recheckPeriod)); @@ -506,7 +554,12 @@ private: unsigned m_miningThreads = UINT_MAX; bool m_shouldListDevices = false; bool m_clAllowCPU = false; - boost::optional m_currentBlock; +#if ETH_ETHASHCL || !ETH_TRUE + unsigned m_globalWorkSizeMultiplier = ethash_cl_miner::c_defaultGlobalWorkSizeMultiplier; + unsigned m_localWorkSize = ethash_cl_miner::c_defaultLocalWorkSize; + unsigned m_msPerBatch = ethash_cl_miner::c_defaultMSPerBatch; +#endif + uint64_t m_currentBlock = 0; // default value is 350MB of GPU memory for other stuff (windows system rendering, e.t.c.) unsigned m_extraGPUMemory = 350000000; diff --git a/ethvm/main.cpp b/ethvm/main.cpp index 4ca733ed0..46442d4ee 100644 --- a/ethvm/main.cpp +++ b/ethvm/main.cpp @@ -46,8 +46,7 @@ void help() #if ETH_EVMJIT || !ETH_TRUE << endl << "VM options:" << endl - << " -J,--jit Enable LLVM VM (default: off)." << endl - << " --smart Enable smart VM (default: off)." << endl + << " --vm Select VM. Options are: interpreter, jit, smart. (default: interpreter)" << endl #endif << endl << "Options for trace:" << endl @@ -97,10 +96,21 @@ int main(int argc, char** argv) else if (arg == "-V" || arg == "--version") version(); #if ETH_EVMJIT - else if (arg == "-J" || arg == "--jit") - VMFactory::setKind(VMKind::JIT); - else if (arg == "--smart") - VMFactory::setKind(VMKind::Smart); + else if (arg == "--vm" && i + 1 < argc) + { + string vmKind = argv[++i]; + if (vmKind == "interpreter") + VMFactory::setKind(VMKind::Interpreter); + else if (vmKind == "jit") + VMFactory::setKind(VMKind::JIT); + else if (vmKind == "smart") + VMFactory::setKind(VMKind::Smart); + else + { + cerr << "Unknown VM kind: " << vmKind << endl; + return -1; + } + } #endif else if (arg == "--mnemonics") st.setShowMnemonics(); diff --git a/evmjit/CMakeLists.txt b/evmjit/CMakeLists.txt index 70d3e1dda..77fb1bf27 100644 --- a/evmjit/CMakeLists.txt +++ b/evmjit/CMakeLists.txt @@ -29,7 +29,3 @@ add_subdirectory(libevmjit) if(EVMJIT_CPP) add_subdirectory(libevmjit-cpp) endif() - -if(EVMJIT_TOOLS) - add_subdirectory(evmcc) -endif() diff --git a/evmjit/evmcc/CMakeLists.txt b/evmjit/evmcc/CMakeLists.txt deleted file mode 100644 index 4ffbf5fb5..000000000 --- a/evmjit/evmcc/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -set(TARGET_NAME evmcc) - -set(SOURCES - evmcc.cpp -) -source_group("" FILES ${SOURCES}) - -add_executable(${TARGET_NAME} ${SOURCES}) -set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "tools") - -include_directories(../..) -include_directories(${LLVM_INCLUDE_DIRS}) -include_directories(${Boost_INCLUDE_DIRS}) - -target_link_libraries(${TARGET_NAME} ethereum) -target_link_libraries(${TARGET_NAME} ${Boost_PROGRAM_OPTIONS_LIBRARIES}) - -install(TARGETS ${TARGET_NAME} DESTINATION bin ) \ No newline at end of file diff --git a/evmjit/evmcc/evmcc.cpp b/evmjit/evmcc/evmcc.cpp deleted file mode 100644 index e86f948f2..000000000 --- a/evmjit/evmcc/evmcc.cpp +++ /dev/null @@ -1,210 +0,0 @@ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - - -void parseProgramOptions(int _argc, char** _argv, boost::program_options::variables_map& _varMap) -{ - namespace opt = boost::program_options; - - opt::options_description explicitOpts("Allowed options"); - explicitOpts.add_options() - ("help,h", "show usage information") - ("compile,c", "compile the code to LLVM IR") - ("interpret,i", "compile the code to LLVM IR and execute") - ("gas,g", opt::value(), "set initial gas for execution") - ("disassemble,d", "dissassemble the code") - ("dump-cfg", "dump control flow graph to graphviz file") - ("dont-optimize", "turn off optimizations") - ("optimize-stack", "optimize stack use between basic blocks (default: on)") - ("rewrite-switch", "rewrite LLVM switch to branches (default: on)") - ("output-ll", opt::value(), "dump generated LLVM IR to file") - ("output-bc", opt::value(), "dump generated LLVM bitcode to file") - ("show-logs", "output LOG statements to stderr") - ("verbose,V", "enable verbose output"); - - opt::options_description implicitOpts("Input files"); - implicitOpts.add_options() - ("input-file", opt::value(), "input file"); - - opt::options_description allOpts(""); - allOpts.add(explicitOpts).add(implicitOpts); - - opt::positional_options_description inputOpts; - inputOpts.add("input-file", 1); - - const char* errorMsg = nullptr; - try - { - auto parser = opt::command_line_parser(_argc, _argv).options(allOpts).positional(inputOpts); - opt::store(parser.run(), _varMap); - opt::notify(_varMap); - } - catch (boost::program_options::error& err) - { - errorMsg = err.what(); - } - - if (!errorMsg && _varMap.count("input-file") == 0) - errorMsg = "missing input file name"; - - if (_varMap.count("disassemble") == 0 - && _varMap.count("compile") == 0 - && _varMap.count("interpret") == 0) - { - errorMsg = "at least one of -c, -i, -d is required"; - } - - if (errorMsg || _varMap.count("help")) - { - if (errorMsg) - std::cerr << "Error: " << errorMsg << std::endl; - - std::cout << "Usage: " << _argv[0] << " input-file " << std::endl - << explicitOpts << std::endl; - std::exit(errorMsg ? 1 : 0); - } -} - -int main(int argc, char** argv) -{ - llvm::sys::PrintStackTraceOnErrorSignal(); - llvm::PrettyStackTraceProgram X(argc, argv); - - boost::program_options::variables_map options; - parseProgramOptions(argc, argv, options); - - auto inputFile = options["input-file"].as(); - std::ifstream ifs(inputFile); - if (!ifs.is_open()) - { - std::cerr << "cannot open input file " << inputFile << std::endl; - exit(1); - } - - std::string src((std::istreambuf_iterator(ifs)), - (std::istreambuf_iterator())); - - boost::algorithm::trim(src); - - using namespace dev; - - bytes bytecode = fromHex(src); - - if (options.count("disassemble")) - { - std::string assembly = eth::disassemble(bytecode); - std::cout << assembly << std::endl; - } - - if (options.count("compile") || options.count("interpret")) - { - size_t initialGas = 10000; - - if (options.count("gas")) - initialGas = options["gas"].as(); - - auto compilationStartTime = std::chrono::high_resolution_clock::now(); - - eth::jit::Compiler::Options compilerOptions; - compilerOptions.dumpCFG = options.count("dump-cfg") > 0; - bool optimize = options.count("dont-optimize") == 0; - compilerOptions.optimizeStack = optimize || options.count("optimize-stack") > 0; - compilerOptions.rewriteSwitchToBranches = optimize || options.count("rewrite-switch") > 0; - - auto compiler = eth::jit::Compiler(compilerOptions); - auto module = compiler.compile(bytecode, "main"); - - auto compilationEndTime = std::chrono::high_resolution_clock::now(); - - module->dump(); - - if (options.count("output-ll")) - { - auto outputFile = options["output-ll"].as(); - std::ofstream ofs(outputFile); - if (!ofs.is_open()) - { - std::cerr << "cannot open output file " << outputFile << std::endl; - exit(1); - } - llvm::raw_os_ostream ros(ofs); - module->print(ros, nullptr); - ofs.close(); - } - - if (options.count("output-bc")) - { - auto outputFile = options["output-bc"].as(); - std::ofstream ofs(outputFile); - if (!ofs.is_open()) - { - std::cerr << "cannot open output file " << outputFile << std::endl; - exit(1); - } - llvm::raw_os_ostream ros(ofs); - llvm::WriteBitcodeToFile(module.get(), ros); - ros.flush(); - ofs.close(); - } - - if (options.count("verbose")) - { - std::cerr << "*** Compilation time: " - << std::chrono::duration_cast(compilationEndTime - compilationStartTime).count() - << std::endl; - } - - if (options.count("interpret")) - { - using namespace eth::jit; - - ExecutionEngine engine; - eth::jit::u256 gas = initialGas; - - // Create random runtime data - RuntimeData data; - data.set(RuntimeData::Gas, gas); - data.set(RuntimeData::Address, (u160)Address(1122334455667788)); - data.set(RuntimeData::Caller, (u160)Address(0xfacefacefaceface)); - data.set(RuntimeData::Origin, (u160)Address(101010101010101010)); - data.set(RuntimeData::CallValue, 0xabcd); - data.set(RuntimeData::CallDataSize, 3); - data.set(RuntimeData::GasPrice, 1003); - data.set(RuntimeData::CoinBase, (u160)Address(101010101010101015)); - data.set(RuntimeData::TimeStamp, 1005); - data.set(RuntimeData::Number, 1006); - data.set(RuntimeData::Difficulty, 16); - data.set(RuntimeData::GasLimit, 1008); - data.set(RuntimeData::CodeSize, bytecode.size()); - data.callData = (uint8_t*)"abc"; - data.code = bytecode.data(); - - // BROKEN: env_* functions must be implemented & RuntimeData struct created - // TODO: Do not compile module again - auto result = engine.run(bytecode, &data, nullptr); - return static_cast(result); - } - } - - return 0; -} diff --git a/evmjit/include/evmjit/DataTypes.h b/evmjit/include/evmjit/DataTypes.h deleted file mode 100644 index 179d9a372..000000000 --- a/evmjit/include/evmjit/DataTypes.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include -#include - -namespace dev -{ -namespace evmjit -{ - -struct h256 -{ - uint64_t words[4]; -}; - -inline bool operator==(h256 _h1, h256 _h2) -{ - return _h1.words[0] == _h2.words[0] && - _h1.words[1] == _h2.words[1] && - _h1.words[2] == _h2.words[2] && - _h1.words[3] == _h2.words[3]; -} - -/// Representation of 256-bit value binary compatible with LLVM i256 -struct i256 -{ - uint64_t a = 0; - uint64_t b = 0; - uint64_t c = 0; - uint64_t d = 0; - - i256() = default; - i256(h256 _h) - { - a = _h.words[0]; - b = _h.words[1]; - c = _h.words[2]; - d = _h.words[3]; - } -}; - -} -} - -namespace std -{ -template<> struct hash -{ - size_t operator()(dev::evmjit::h256 const& _h) const - { - /// This implementation expects the argument to be a full 256-bit Keccak hash. - /// It does nothing more than returning a slice of the input hash. - return static_cast(_h.words[0]); - }; -}; -} diff --git a/evmjit/include/evmjit/JIT.h b/evmjit/include/evmjit/JIT.h index c9ddde705..901c351d9 100644 --- a/evmjit/include/evmjit/JIT.h +++ b/evmjit/include/evmjit/JIT.h @@ -1,19 +1,147 @@ #pragma once -#include "evmjit/DataTypes.h" +#include +#include +#include + +#ifdef _MSC_VER +#define EXPORT __declspec(dllexport) +#define _ALLOW_KEYWORD_MACROS +#define noexcept throw() +#else +#define EXPORT +#endif namespace dev { -namespace eth +namespace evmjit { -namespace jit + +using byte = uint8_t; +using bytes_ref = std::tuple; + +/// Representation of 256-bit hash value +struct h256 { - class ExecutionEngine; -} + uint64_t words[4]; +}; + +inline bool operator==(h256 const& _h1, h256 const& _h2) +{ + return _h1.words[0] == _h2.words[0] && + _h1.words[1] == _h2.words[1] && + _h1.words[2] == _h2.words[2] && + _h1.words[3] == _h2.words[3]; } -namespace evmjit +/// Representation of 256-bit value binary compatible with LLVM i256 +struct i256 +{ + uint64_t words[4]; + + i256() = default; + i256(h256 const& _h) { std::memcpy(this, &_h, sizeof(*this)); } +}; + +// TODO: Merge with ExecutionContext +struct RuntimeData +{ + enum Index + { + Gas, + GasPrice, + CallData, + CallDataSize, + Address, + Caller, + Origin, + CallValue, + CoinBase, + Difficulty, + GasLimit, + Number, + Timestamp, + Code, + CodeSize, + + SuicideDestAddress = Address, ///< Suicide balance destination address + ReturnData = CallData, ///< Return data pointer (set only in case of RETURN) + ReturnDataSize = CallDataSize, ///< Return data size (set only in case of RETURN) + }; + + static size_t const numElements = CodeSize + 1; + + int64_t gas = 0; + int64_t gasPrice = 0; + byte const* callData = nullptr; + uint64_t callDataSize = 0; + i256 address; + i256 caller; + i256 origin; + i256 callValue; + i256 coinBase; + i256 difficulty; + i256 gasLimit; + uint64_t number = 0; + int64_t timestamp = 0; + byte const* code = nullptr; + uint64_t codeSize = 0; + h256 codeHash; +}; + +/// VM Environment (ExtVM) opaque type +struct Env; + +enum class ReturnCode { + // Success codes + Stop = 0, + Return = 1, + Suicide = 2, + + // Standard error codes + OutOfGas = -1, + StackUnderflow = -2, + BadJumpDestination = -3, + BadInstruction = -4, + Rejected = -5, ///< Input data (code, gas, block info, etc.) does not meet JIT requirement and execution request has been rejected + + // Internal error codes + LLVMError = -101, + + UnexpectedException = -111, + + LinkerWorkaround = -299, +}; + +class ExecutionContext +{ +public: + ExecutionContext() = default; + ExecutionContext(RuntimeData& _data, Env* _env) { init(_data, _env); } + ExecutionContext(ExecutionContext const&) = delete; + ExecutionContext& operator=(ExecutionContext const&) = delete; + EXPORT ~ExecutionContext(); + + void init(RuntimeData& _data, Env* _env) { m_data = &_data; m_env = _env; } + + byte const* code() const { return m_data->code; } + uint64_t codeSize() const { return m_data->codeSize; } + h256 const& codeHash() const { return m_data->codeHash; } + + bytes_ref getReturnData() const; + +protected: + RuntimeData* m_data = nullptr; ///< Pointer to data. Expected by compiled contract. + Env* m_env = nullptr; ///< Pointer to environment proxy. Expected by compiled contract. + byte* m_memData = nullptr; + uint64_t m_memSize = 0; + uint64_t m_memCap = 0; + +public: + /// Reference to returned data (RETURN opcode used) + bytes_ref returnData; +}; class JIT { @@ -23,14 +151,26 @@ public: /// Returns `true` if the EVM code has been compiled and loaded into memory. /// In this case the code can be executed without overhead. /// \param _codeHash The Keccak hash of the EVM code. - static bool isCodeReady(h256 _codeHash); + EXPORT static bool isCodeReady(h256 const& _codeHash); -private: - friend class dev::eth::jit::ExecutionEngine; + /// Compile the given EVM code to machine code and make available for execution. + EXPORT static void compile(byte const* _code, uint64_t _codeSize, h256 const& _codeHash); - static uint64_t getCode(h256 _codeHash); - static void mapCode(h256 _codeHash, uint64_t _funcAddr); + EXPORT static ReturnCode exec(ExecutionContext& _context); }; } } + +namespace std +{ +template<> struct hash +{ + size_t operator()(dev::evmjit::h256 const& _h) const + { + /// This implementation expects the argument to be a full 256-bit Keccak hash. + /// It does nothing more than returning a slice of the input hash. + return static_cast(_h.words[0]); + }; +}; +} diff --git a/evmjit/libevmjit-cpp/Env.cpp b/evmjit/libevmjit-cpp/Env.cpp index 4d7865bd0..3f59765f6 100644 --- a/evmjit/libevmjit-cpp/Env.cpp +++ b/evmjit/libevmjit-cpp/Env.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "Utils.h" @@ -21,15 +20,15 @@ extern "C" EXPORT void env_sload(ExtVMFace* _env, i256* _index, i256* o_value) { - auto index = llvm2eth(*_index); + auto index = jit2eth(*_index); auto value = _env->store(index); // Interface uses native endianness - *o_value = eth2llvm(value); + *o_value = eth2jit(value); } EXPORT void env_sstore(ExtVMFace* _env, i256* _index, i256* _value) { - auto index = llvm2eth(*_index); - auto value = llvm2eth(*_value); + auto index = jit2eth(*_index); + auto value = jit2eth(*_value); if (value == 0 && _env->store(index) != 0) // If delete _env->sub.refunds += c_sstoreRefundGas; // Increase refund counter @@ -40,17 +39,17 @@ extern "C" EXPORT void env_balance(ExtVMFace* _env, h256* _address, i256* o_value) { auto u = _env->balance(right160(*_address)); - *o_value = eth2llvm(u); + *o_value = eth2jit(u); } EXPORT void env_blockhash(ExtVMFace* _env, i256* _number, h256* o_hash) { - *o_hash = _env->blockhash(llvm2eth(*_number)); + *o_hash = _env->blockhash(jit2eth(*_number)); } EXPORT void env_create(ExtVMFace* _env, int64_t* io_gas, i256* _endowment, byte* _initBeg, uint64_t _initSize, h256* o_address) { - auto endowment = llvm2eth(*_endowment); + auto endowment = jit2eth(*_endowment); if (_env->balance(_env->myAddress) >= endowment && _env->depth < 1024) { u256 gas = *io_gas; @@ -65,7 +64,7 @@ extern "C" EXPORT bool env_call(ExtVMFace* _env, int64_t* io_gas, int64_t _callGas, h256* _receiveAddress, i256* _value, byte* _inBeg, uint64_t _inSize, byte* _outBeg, uint64_t _outSize, h256* _codeAddress) { CallParameters params; - params.value = llvm2eth(*_value); + params.value = jit2eth(*_value); params.senderAddress = _env->myAddress; params.receiveAddress = right160(*_receiveAddress); params.codeAddress = right160(*_codeAddress); diff --git a/evmjit/libevmjit-cpp/JitVM.cpp b/evmjit/libevmjit-cpp/JitVM.cpp index 68161526d..2fb2a0e67 100644 --- a/evmjit/libevmjit-cpp/JitVM.cpp +++ b/evmjit/libevmjit-cpp/JitVM.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include "Utils.h" @@ -20,8 +19,6 @@ extern "C" void env_sload(); // fake declaration for linker symbol stripping wor bytesConstRef JitVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) { - using namespace jit; - auto rejected = false; // TODO: Rejecting transactions with gas limit > 2^63 can be used by attacker to take JIT out of scope rejected |= io_gas > std::numeric_limits::max(); // Do not accept requests with gas > 2^63 (int64 max) @@ -40,36 +37,38 @@ bytesConstRef JitVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _on m_data.gasPrice = static_cast(_ext.gasPrice); m_data.callData = _ext.data.data(); m_data.callDataSize = _ext.data.size(); - m_data.address = eth2llvm(fromAddress(_ext.myAddress)); - m_data.caller = eth2llvm(fromAddress(_ext.caller)); - m_data.origin = eth2llvm(fromAddress(_ext.origin)); - m_data.callValue = eth2llvm(_ext.value); - m_data.coinBase = eth2llvm(fromAddress(_ext.currentBlock.coinbaseAddress)); - m_data.difficulty = eth2llvm(_ext.currentBlock.difficulty); - m_data.gasLimit = eth2llvm(_ext.currentBlock.gasLimit); + m_data.address = eth2jit(fromAddress(_ext.myAddress)); + m_data.caller = eth2jit(fromAddress(_ext.caller)); + m_data.origin = eth2jit(fromAddress(_ext.origin)); + m_data.callValue = eth2jit(_ext.value); + m_data.coinBase = eth2jit(fromAddress(_ext.currentBlock.coinbaseAddress)); + m_data.difficulty = eth2jit(_ext.currentBlock.difficulty); + m_data.gasLimit = eth2jit(_ext.currentBlock.gasLimit); m_data.number = static_cast(_ext.currentBlock.number); m_data.timestamp = static_cast(_ext.currentBlock.timestamp); m_data.code = _ext.code.data(); m_data.codeSize = _ext.code.size(); - m_data.codeHash = eth2llvm(_ext.codeHash); + m_data.codeHash = eth2jit(_ext.codeHash); - auto env = reinterpret_cast(&_ext); - auto exitCode = m_engine.run(&m_data, env); + // Pass pointer to ExtVMFace casted to evmjit::Env* opaque type. + // JIT will do nothing with the pointer, just pass it to Env callback functions implemented in Env.cpp. + m_context.init(m_data, reinterpret_cast(&_ext)); + auto exitCode = evmjit::JIT::exec(m_context); switch (exitCode) { - case ReturnCode::Suicide: - _ext.suicide(right160(llvm2eth(m_data.address))); + case evmjit::ReturnCode::Suicide: + _ext.suicide(right160(jit2eth(m_data.address))); break; - case ReturnCode::BadJumpDestination: + case evmjit::ReturnCode::BadJumpDestination: BOOST_THROW_EXCEPTION(BadJumpDestination()); - case ReturnCode::OutOfGas: + case evmjit::ReturnCode::OutOfGas: BOOST_THROW_EXCEPTION(OutOfGas()); - case ReturnCode::StackUnderflow: + case evmjit::ReturnCode::StackUnderflow: // FIXME: Remove support for detail errors BOOST_THROW_EXCEPTION(StackUnderflow()); - case ReturnCode::BadInstruction: + case evmjit::ReturnCode::BadInstruction: BOOST_THROW_EXCEPTION(BadInstruction()); - case ReturnCode::LinkerWorkaround: // never happens + case evmjit::ReturnCode::LinkerWorkaround: // never happens env_sload(); // but forces linker to include env_* JIT callback functions break; default: @@ -77,7 +76,7 @@ bytesConstRef JitVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _on } io_gas = m_data.gas; - return {std::get<0>(m_engine.returnData), std::get<1>(m_engine.returnData)}; + return {std::get<0>(m_context.returnData), std::get<1>(m_context.returnData)}; } } diff --git a/evmjit/libevmjit-cpp/JitVM.h b/evmjit/libevmjit-cpp/JitVM.h index e97abd83b..43933ebe4 100644 --- a/evmjit/libevmjit-cpp/JitVM.h +++ b/evmjit/libevmjit-cpp/JitVM.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include namespace dev { @@ -14,8 +14,8 @@ public: virtual bytesConstRef execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) override final; private: - jit::RuntimeData m_data; - jit::ExecutionEngine m_engine; + evmjit::RuntimeData m_data; + evmjit::ExecutionContext m_context; std::unique_ptr m_fallbackVM; ///< VM used in case of input data rejected by JIT }; diff --git a/evmjit/libevmjit-cpp/Utils.h b/evmjit/libevmjit-cpp/Utils.h index f9b9b2ef4..ebb6ad97d 100644 --- a/evmjit/libevmjit-cpp/Utils.h +++ b/evmjit/libevmjit-cpp/Utils.h @@ -1,40 +1,41 @@ #pragma once -#include +#include namespace dev { namespace eth { -inline u256 llvm2eth(evmjit::i256 _i) +/// Converts EVM JIT representation of 256-bit integer to eth type dev::u256. +inline u256 jit2eth(evmjit::i256 _i) { - u256 u = 0; - u |= _i.d; + u256 u = _i.words[3]; u <<= 64; - u |= _i.c; + u |= _i.words[2]; u <<= 64; - u |= _i.b; + u |= _i.words[1]; u <<= 64; - u |= _i.a; + u |= _i.words[0]; return u; } -inline evmjit::i256 eth2llvm(u256 _u) +/// Converts eth type dev::u256 to EVM JIT representation of 256-bit integer. +inline evmjit::i256 eth2jit(u256 _u) { evmjit::i256 i; - u256 mask = 0xFFFFFFFFFFFFFFFF; - i.a = static_cast(_u & mask); + i.words[0] = static_cast(_u); _u >>= 64; - i.b = static_cast(_u & mask); + i.words[1] = static_cast(_u); _u >>= 64; - i.c = static_cast(_u & mask); + i.words[2] = static_cast(_u); _u >>= 64; - i.d = static_cast(_u & mask); + i.words[3] = static_cast(_u); return i; } -inline evmjit::h256 eth2llvm(h256 _u) +/// Converts eth type dev::h256 to EVM JIT representation of 256-bit hash value. +inline evmjit::h256 eth2jit(h256 _u) { /// Just directly copies memory return *(evmjit::h256*)&_u; diff --git a/evmjit/libevmjit/Arith256.cpp b/evmjit/libevmjit/Arith256.cpp index 95ca2aee5..76c53c78d 100644 --- a/evmjit/libevmjit/Arith256.cpp +++ b/evmjit/libevmjit/Arith256.cpp @@ -4,6 +4,7 @@ #include #include "preprocessor/llvm_includes_start.h" +#include #include #include "preprocessor/llvm_includes_end.h" @@ -32,186 +33,364 @@ void Arith256::debug(llvm::Value* _value, char _c) createCall(m_debug, {m_builder.CreateZExtOrTrunc(_value, Type::Word), m_builder.getInt8(_c)}); } -llvm::Function* Arith256::getMulFunc() +llvm::Function* Arith256::getMulFunc(llvm::Module& _module) { - auto& func = m_mul; - if (!func) - { - llvm::Type* argTypes[] = {Type::Word, Type::Word}; - func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "mul", getModule()); - func->setDoesNotThrow(); - func->setDoesNotAccessMemory(); + static const auto funcName = "evm.mul.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + llvm::Type* argTypes[] = {Type::Word, Type::Word}; + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto y = x->getNextNode(); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = llvm::IRBuilder<>{bb}; + auto i64 = Type::Size; + auto i128 = builder.getIntNTy(128); + auto i256 = Type::Word; + auto c64 = Constant::get(64); + auto c128 = Constant::get(128); + auto c192 = Constant::get(192); + + auto x_lo = builder.CreateTrunc(x, i64, "x.lo"); + auto y_lo = builder.CreateTrunc(y, i64, "y.lo"); + auto x_mi = builder.CreateTrunc(builder.CreateLShr(x, c64), i64); + auto y_mi = builder.CreateTrunc(builder.CreateLShr(y, c64), i64); + auto x_hi = builder.CreateTrunc(builder.CreateLShr(x, c128), i128); + auto y_hi = builder.CreateTrunc(builder.CreateLShr(y, c128), i128); + + auto t1 = builder.CreateMul(builder.CreateZExt(x_lo, i128), builder.CreateZExt(y_lo, i128)); + auto t2 = builder.CreateMul(builder.CreateZExt(x_lo, i128), builder.CreateZExt(y_mi, i128)); + auto t3 = builder.CreateMul(builder.CreateZExt(x_lo, i128), y_hi); + auto t4 = builder.CreateMul(builder.CreateZExt(x_mi, i128), builder.CreateZExt(y_lo, i128)); + auto t5 = builder.CreateMul(builder.CreateZExt(x_mi, i128), builder.CreateZExt(y_mi, i128)); + auto t6 = builder.CreateMul(builder.CreateZExt(x_mi, i128), y_hi); + auto t7 = builder.CreateMul(x_hi, builder.CreateZExt(y_lo, i128)); + auto t8 = builder.CreateMul(x_hi, builder.CreateZExt(y_mi, i128)); + + auto p = builder.CreateZExt(t1, i256); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t2, i256), c64)); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t3, i256), c128)); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t4, i256), c64)); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t5, i256), c128)); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t6, i256), c192)); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t7, i256), c128)); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t8, i256), c192)); + builder.CreateRet(p); + return func; +} - auto x = &func->getArgumentList().front(); - x->setName("x"); - auto y = x->getNextNode(); - y->setName("y"); +llvm::Function* Arith256::getMul512Func(llvm::Module& _module) +{ + static const auto funcName = "evm.mul.i512"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto i512Ty = llvm::IntegerType::get(_module.getContext(), 512); + auto func = llvm::Function::Create(llvm::FunctionType::get(i512Ty, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto y = x->getNextNode(); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = llvm::IRBuilder<>{bb}; + + auto i128 = builder.getIntNTy(128); + auto i256 = Type::Word; + auto x_lo = builder.CreateZExt(builder.CreateTrunc(x, i128, "x.lo"), i256); + auto y_lo = builder.CreateZExt(builder.CreateTrunc(y, i128, "y.lo"), i256); + auto x_hi = builder.CreateZExt(builder.CreateTrunc(builder.CreateLShr(x, Constant::get(128)), i128, "x.hi"), i256); + auto y_hi = builder.CreateZExt(builder.CreateTrunc(builder.CreateLShr(y, Constant::get(128)), i128, "y.hi"), i256); + + auto mul256Func = getMulFunc(_module); + auto t1 = builder.CreateCall(mul256Func, {x_lo, y_lo}); + auto t2 = builder.CreateCall(mul256Func, {x_lo, y_hi}); + auto t3 = builder.CreateCall(mul256Func, {x_hi, y_lo}); + auto t4 = builder.CreateCall(mul256Func, {x_hi, y_hi}); + + auto p = builder.CreateZExt(t1, i512Ty); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t2, i512Ty), builder.getIntN(512, 128))); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t3, i512Ty), builder.getIntN(512, 128))); + p = builder.CreateAdd(p, builder.CreateShl(builder.CreateZExt(t4, i512Ty), builder.getIntN(512, 256))); + builder.CreateRet(p); - InsertPointGuard guard{m_builder}; - auto bb = llvm::BasicBlock::Create(m_builder.getContext(), {}, func); - m_builder.SetInsertPoint(bb); - auto i64 = Type::Size; - auto i128 = m_builder.getIntNTy(128); - auto i256 = Type::Word; - auto c64 = Constant::get(64); - auto c128 = Constant::get(128); - auto c192 = Constant::get(192); - - auto x_lo = m_builder.CreateTrunc(x, i64, "x.lo"); - auto y_lo = m_builder.CreateTrunc(y, i64, "y.lo"); - auto x_mi = m_builder.CreateTrunc(m_builder.CreateLShr(x, c64), i64); - auto y_mi = m_builder.CreateTrunc(m_builder.CreateLShr(y, c64), i64); - auto x_hi = m_builder.CreateTrunc(m_builder.CreateLShr(x, c128), i128); - auto y_hi = m_builder.CreateTrunc(m_builder.CreateLShr(y, c128), i128); - - auto t1 = m_builder.CreateMul(m_builder.CreateZExt(x_lo, i128), m_builder.CreateZExt(y_lo, i128)); - auto t2 = m_builder.CreateMul(m_builder.CreateZExt(x_lo, i128), m_builder.CreateZExt(y_mi, i128)); - auto t3 = m_builder.CreateMul(m_builder.CreateZExt(x_lo, i128), y_hi); - auto t4 = m_builder.CreateMul(m_builder.CreateZExt(x_mi, i128), m_builder.CreateZExt(y_lo, i128)); - auto t5 = m_builder.CreateMul(m_builder.CreateZExt(x_mi, i128), m_builder.CreateZExt(y_mi, i128)); - auto t6 = m_builder.CreateMul(m_builder.CreateZExt(x_mi, i128), y_hi); - auto t7 = m_builder.CreateMul(x_hi, m_builder.CreateZExt(y_lo, i128)); - auto t8 = m_builder.CreateMul(x_hi, m_builder.CreateZExt(y_mi, i128)); - - auto p = m_builder.CreateZExt(t1, i256); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t2, i256), c64)); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t3, i256), c128)); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t4, i256), c64)); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t5, i256), c128)); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t6, i256), c192)); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t7, i256), c128)); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t8, i256), c192)); - m_builder.CreateRet(p); - } return func; } -llvm::Function* Arith256::getMul512Func() +namespace { - auto& func = m_mul512; - if (!func) - { - auto i512 = m_builder.getIntNTy(512); - llvm::Type* argTypes[] = {Type::Word, Type::Word}; - func = llvm::Function::Create(llvm::FunctionType::get(i512, argTypes, false), llvm::Function::PrivateLinkage, "mul512", getModule()); - func->setDoesNotThrow(); - func->setDoesNotAccessMemory(); +llvm::Function* createUDivRemFunc(llvm::Type* _type, llvm::Module& _module, char const* _funcName) +{ + // Based of "Improved shift divisor algorithm" from "Software Integer Division" by Microsoft Research + // The following algorithm also handles divisor of value 0 returning 0 for both quotient and remainder + + auto retType = llvm::VectorType::get(_type, 2); + auto func = llvm::Function::Create(llvm::FunctionType::get(retType, {_type, _type}, false), llvm::Function::PrivateLinkage, _funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto zero = llvm::ConstantInt::get(_type, 0); + auto one = llvm::ConstantInt::get(_type, 1); + + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto yArg = x->getNextNode(); + yArg->setName("y"); + + auto entryBB = llvm::BasicBlock::Create(_module.getContext(), "Entry", func); + auto mainBB = llvm::BasicBlock::Create(_module.getContext(), "Main", func); + auto loopBB = llvm::BasicBlock::Create(_module.getContext(), "Loop", func); + auto continueBB = llvm::BasicBlock::Create(_module.getContext(), "Continue", func); + auto returnBB = llvm::BasicBlock::Create(_module.getContext(), "Return", func); + + auto builder = llvm::IRBuilder<>{entryBB}; + auto yLEx = builder.CreateICmpULE(yArg, x); + auto r0 = x; + builder.CreateCondBr(yLEx, mainBB, returnBB); + + builder.SetInsertPoint(mainBB); + auto ctlzIntr = llvm::Intrinsic::getDeclaration(&_module, llvm::Intrinsic::ctlz, _type); + // both y and r are non-zero + auto yLz = builder.CreateCall(ctlzIntr, {yArg, builder.getInt1(true)}, "y.lz"); + auto rLz = builder.CreateCall(ctlzIntr, {r0, builder.getInt1(true)}, "r.lz"); + auto i0 = builder.CreateNUWSub(yLz, rLz, "i0"); + auto y0 = builder.CreateShl(yArg, i0); + builder.CreateBr(loopBB); + + builder.SetInsertPoint(loopBB); + auto yPhi = builder.CreatePHI(_type, 2, "y.phi"); + auto rPhi = builder.CreatePHI(_type, 2, "r.phi"); + auto iPhi = builder.CreatePHI(_type, 2, "i.phi"); + auto qPhi = builder.CreatePHI(_type, 2, "q.phi"); + auto rUpdate = builder.CreateNUWSub(rPhi, yPhi); + auto qUpdate = builder.CreateOr(qPhi, one); // q += 1, q lowest bit is 0 + auto rGEy = builder.CreateICmpUGE(rPhi, yPhi); + auto r1 = builder.CreateSelect(rGEy, rUpdate, rPhi, "r1"); + auto q1 = builder.CreateSelect(rGEy, qUpdate, qPhi, "q"); + auto iZero = builder.CreateICmpEQ(iPhi, zero); + builder.CreateCondBr(iZero, returnBB, continueBB); + + builder.SetInsertPoint(continueBB); + auto i2 = builder.CreateNUWSub(iPhi, one); + auto q2 = builder.CreateShl(q1, one); + auto y2 = builder.CreateLShr(yPhi, one); + builder.CreateBr(loopBB); + + yPhi->addIncoming(y0, mainBB); + yPhi->addIncoming(y2, continueBB); + rPhi->addIncoming(r0, mainBB); + rPhi->addIncoming(r1, continueBB); + iPhi->addIncoming(i0, mainBB); + iPhi->addIncoming(i2, continueBB); + qPhi->addIncoming(zero, mainBB); + qPhi->addIncoming(q2, continueBB); + + builder.SetInsertPoint(returnBB); + auto qRet = builder.CreatePHI(_type, 2, "q.ret"); + qRet->addIncoming(zero, entryBB); + qRet->addIncoming(q1, loopBB); + auto rRet = builder.CreatePHI(_type, 2, "r.ret"); + rRet->addIncoming(r0, entryBB); + rRet->addIncoming(r1, loopBB); + auto ret = builder.CreateInsertElement(llvm::UndefValue::get(retType), qRet, uint64_t(0), "ret0"); + ret = builder.CreateInsertElement(ret, rRet, 1, "ret"); + builder.CreateRet(ret); - auto x = &func->getArgumentList().front(); - x->setName("x"); - auto y = x->getNextNode(); - y->setName("y"); + return func; +} +} + +llvm::Function* Arith256::getUDivRem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.udivrem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + return createUDivRemFunc(Type::Word, _module, funcName); +} + +llvm::Function* Arith256::getUDivRem512Func(llvm::Module& _module) +{ + static const auto funcName = "evm.udivrem.i512"; + if (auto func = _module.getFunction(funcName)) + return func; + + return createUDivRemFunc(llvm::IntegerType::get(_module.getContext(), 512), _module, funcName); +} + +llvm::Function* Arith256::getUDiv256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.udiv.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto udivremFunc = getUDivRem256Func(_module); + + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto y = x->getNextNode(); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = llvm::IRBuilder<>{bb}; + auto udivrem = builder.CreateCall(udivremFunc, {x, y}); + auto udiv = builder.CreateExtractElement(udivrem, uint64_t(0)); + builder.CreateRet(udiv); - InsertPointGuard guard{m_builder}; - auto bb = llvm::BasicBlock::Create(m_builder.getContext(), {}, func); - m_builder.SetInsertPoint(bb); - auto i128 = m_builder.getIntNTy(128); - auto i256 = Type::Word; - auto x_lo = m_builder.CreateZExt(m_builder.CreateTrunc(x, i128, "x.lo"), i256); - auto y_lo = m_builder.CreateZExt(m_builder.CreateTrunc(y, i128, "y.lo"), i256); - auto x_hi = m_builder.CreateZExt(m_builder.CreateTrunc(m_builder.CreateLShr(x, Constant::get(128)), i128, "x.hi"), i256); - auto y_hi = m_builder.CreateZExt(m_builder.CreateTrunc(m_builder.CreateLShr(y, Constant::get(128)), i128, "y.hi"), i256); - - auto t1 = createCall(getMulFunc(), {x_lo, y_lo}); - auto t2 = createCall(getMulFunc(), {x_lo, y_hi}); - auto t3 = createCall(getMulFunc(), {x_hi, y_lo}); - auto t4 = createCall(getMulFunc(), {x_hi, y_hi}); - - auto p = m_builder.CreateZExt(t1, i512); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t2, i512), m_builder.getIntN(512, 128))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t3, i512), m_builder.getIntN(512, 128))); - p = m_builder.CreateAdd(p, m_builder.CreateShl(m_builder.CreateZExt(t4, i512), m_builder.getIntN(512, 256))); - m_builder.CreateRet(p); - } return func; } -llvm::Function* Arith256::getDivFunc(llvm::Type* _type) +namespace +{ +llvm::Function* createURemFunc(llvm::Type* _type, llvm::Module& _module, char const* _funcName) { - auto& func = _type == Type::Word ? m_div : m_div512; + auto udivremFunc = _type == Type::Word ? Arith256::getUDivRem256Func(_module) : Arith256::getUDivRem512Func(_module); - if (!func) - { - // Based of "Improved shift divisor algorithm" from "Software Integer Division" by Microsoft Research - // The following algorithm also handles divisor of value 0 returning 0 for both quotient and reminder + auto func = llvm::Function::Create(llvm::FunctionType::get(_type, {_type, _type}, false), llvm::Function::PrivateLinkage, _funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); - llvm::Type* argTypes[] = {_type, _type}; - auto retType = llvm::StructType::get(m_builder.getContext(), llvm::ArrayRef{argTypes}); - auto funcName = _type == Type::Word ? "div" : "div512"; - func = llvm::Function::Create(llvm::FunctionType::get(retType, argTypes, false), llvm::Function::PrivateLinkage, funcName, getModule()); - func->setDoesNotThrow(); - func->setDoesNotAccessMemory(); + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto y = x->getNextNode(); + y->setName("y"); - auto zero = llvm::ConstantInt::get(_type, 0); - auto one = llvm::ConstantInt::get(_type, 1); + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = llvm::IRBuilder<>{bb}; + auto udivrem = builder.CreateCall(udivremFunc, {x, y}); + auto r = builder.CreateExtractElement(udivrem, uint64_t(1)); + builder.CreateRet(r); - auto x = &func->getArgumentList().front(); - x->setName("x"); - auto yArg = x->getNextNode(); - yArg->setName("y"); + return func; +} +} - InsertPointGuard guard{m_builder}; +llvm::Function* Arith256::getURem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.urem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + return createURemFunc(Type::Word, _module, funcName); +} - auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), "Entry", func); - auto mainBB = llvm::BasicBlock::Create(m_builder.getContext(), "Main", func); - auto loopBB = llvm::BasicBlock::Create(m_builder.getContext(), "Loop", func); - auto continueBB = llvm::BasicBlock::Create(m_builder.getContext(), "Continue", func); - auto returnBB = llvm::BasicBlock::Create(m_builder.getContext(), "Return", func); +llvm::Function* Arith256::getURem512Func(llvm::Module& _module) +{ + static const auto funcName = "evm.urem.i512"; + if (auto func = _module.getFunction(funcName)) + return func; + return createURemFunc(llvm::IntegerType::get(_module.getContext(), 512), _module, funcName); +} - m_builder.SetInsertPoint(entryBB); - auto yNonZero = m_builder.CreateICmpNE(yArg, zero); - auto yLEx = m_builder.CreateICmpULE(yArg, x); - auto r0 = m_builder.CreateSelect(yNonZero, x, zero, "r0"); - m_builder.CreateCondBr(m_builder.CreateAnd(yLEx, yNonZero), mainBB, returnBB); - - m_builder.SetInsertPoint(mainBB); - auto ctlzIntr = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::ctlz, _type); - // both y and r are non-zero - auto yLz = m_builder.CreateCall(ctlzIntr, {yArg, m_builder.getInt1(true)}, "y.lz"); - auto rLz = m_builder.CreateCall(ctlzIntr, {r0, m_builder.getInt1(true)}, "r.lz"); - auto i0 = m_builder.CreateNUWSub(yLz, rLz, "i0"); - auto y0 = m_builder.CreateShl(yArg, i0); - m_builder.CreateBr(loopBB); - - m_builder.SetInsertPoint(loopBB); - auto yPhi = m_builder.CreatePHI(_type, 2, "y.phi"); - auto rPhi = m_builder.CreatePHI(_type, 2, "r.phi"); - auto iPhi = m_builder.CreatePHI(_type, 2, "i.phi"); - auto qPhi = m_builder.CreatePHI(_type, 2, "q.phi"); - auto rUpdate = m_builder.CreateNUWSub(rPhi, yPhi); - auto qUpdate = m_builder.CreateOr(qPhi, one); // q += 1, q lowest bit is 0 - auto rGEy = m_builder.CreateICmpUGE(rPhi, yPhi); - auto r1 = m_builder.CreateSelect(rGEy, rUpdate, rPhi, "r1"); - auto q1 = m_builder.CreateSelect(rGEy, qUpdate, qPhi, "q"); - auto iZero = m_builder.CreateICmpEQ(iPhi, zero); - m_builder.CreateCondBr(iZero, returnBB, continueBB); +llvm::Function* Arith256::getSDivRem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.sdivrem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; - m_builder.SetInsertPoint(continueBB); - auto i2 = m_builder.CreateNUWSub(iPhi, one); - auto q2 = m_builder.CreateShl(q1, one); - auto y2 = m_builder.CreateLShr(yPhi, one); - m_builder.CreateBr(loopBB); - - yPhi->addIncoming(y0, mainBB); - yPhi->addIncoming(y2, continueBB); - rPhi->addIncoming(r0, mainBB); - rPhi->addIncoming(r1, continueBB); - iPhi->addIncoming(i0, mainBB); - iPhi->addIncoming(i2, continueBB); - qPhi->addIncoming(zero, mainBB); - qPhi->addIncoming(q2, continueBB); + auto udivremFunc = getUDivRem256Func(_module); + + auto retType = llvm::VectorType::get(Type::Word, 2); + auto func = llvm::Function::Create(llvm::FunctionType::get(retType, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto y = x->getNextNode(); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), "", func); + auto builder = llvm::IRBuilder<>{bb}; + auto xIsNeg = builder.CreateICmpSLT(x, Constant::get(0)); + auto xNeg = builder.CreateSub(Constant::get(0), x); + auto xAbs = builder.CreateSelect(xIsNeg, xNeg, x); + + auto yIsNeg = builder.CreateICmpSLT(y, Constant::get(0)); + auto yNeg = builder.CreateSub(Constant::get(0), y); + auto yAbs = builder.CreateSelect(yIsNeg, yNeg, y); + + auto res = builder.CreateCall(udivremFunc, {xAbs, yAbs}); + auto qAbs = builder.CreateExtractElement(res, uint64_t(0)); + auto rAbs = builder.CreateExtractElement(res, 1); + + // the remainder has the same sign as dividend + auto rNeg = builder.CreateSub(Constant::get(0), rAbs); + auto r = builder.CreateSelect(xIsNeg, rNeg, rAbs); + + auto qNeg = builder.CreateSub(Constant::get(0), qAbs); + auto xyOpposite = builder.CreateXor(xIsNeg, yIsNeg); + auto q = builder.CreateSelect(xyOpposite, qNeg, qAbs); + + auto ret = builder.CreateInsertElement(llvm::UndefValue::get(retType), q, uint64_t(0)); + ret = builder.CreateInsertElement(ret, r, 1); + builder.CreateRet(ret); + + return func; +} + +llvm::Function* Arith256::getSDiv256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.sdiv.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto sdivremFunc = getSDivRem256Func(_module); + + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto y = x->getNextNode(); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = llvm::IRBuilder<>{bb}; + auto sdivrem = builder.CreateCall(sdivremFunc, {x, y}); + auto q = builder.CreateExtractElement(sdivrem, uint64_t(0)); + builder.CreateRet(q); + + return func; +} + +llvm::Function* Arith256::getSRem256Func(llvm::Module& _module) +{ + static const auto funcName = "evm.srem.i256"; + if (auto func = _module.getFunction(funcName)) + return func; + + auto sdivremFunc = getSDivRem256Func(_module); + + auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Word, {Type::Word, Type::Word}, false), llvm::Function::PrivateLinkage, funcName, &_module); + func->setDoesNotThrow(); + func->setDoesNotAccessMemory(); + + auto x = &func->getArgumentList().front(); + x->setName("x"); + auto y = x->getNextNode(); + y->setName("y"); + + auto bb = llvm::BasicBlock::Create(_module.getContext(), {}, func); + auto builder = llvm::IRBuilder<>{bb}; + auto sdivrem = builder.CreateCall(sdivremFunc, {x, y}); + auto r = builder.CreateExtractElement(sdivrem, uint64_t(1)); + builder.CreateRet(r); - m_builder.SetInsertPoint(returnBB); - auto qRet = m_builder.CreatePHI(_type, 2, "q.ret"); - qRet->addIncoming(zero, entryBB); - qRet->addIncoming(q1, loopBB); - auto rRet = m_builder.CreatePHI(_type, 2, "r.ret"); - rRet->addIncoming(r0, entryBB); - rRet->addIncoming(r1, loopBB); - auto ret = m_builder.CreateInsertValue(llvm::UndefValue::get(retType), qRet, 0, "ret0"); - ret = m_builder.CreateInsertValue(ret, rRet, 1, "ret"); - m_builder.CreateRet(ret); - } return func; } @@ -260,14 +439,15 @@ llvm::Function* Arith256::getExpFunc() m_builder.CreateCondBr(eOdd, updateBB, continueBB); m_builder.SetInsertPoint(updateBB); - auto r0 = createCall(getMulFunc(), {r, b}); + auto mul256Func = getMulFunc(*getModule()); + auto r0 = createCall(mul256Func, {r, b}); m_builder.CreateBr(continueBB); m_builder.SetInsertPoint(continueBB); auto r1 = m_builder.CreatePHI(Type::Word, 2, "r1"); r1->addIncoming(r, bodyBB); r1->addIncoming(r0, updateBB); - auto b1 = createCall(getMulFunc(), {b, b}); + auto b1 = createCall(mul256Func, {b, b}); auto e1 = m_builder.CreateLShr(e, Constant::get(1), "e1"); m_builder.CreateBr(headerBB); @@ -284,137 +464,6 @@ llvm::Function* Arith256::getExpFunc() return m_exp; } -llvm::Function* Arith256::getAddModFunc() -{ - if (!m_addmod) - { - auto i512Ty = m_builder.getIntNTy(512); - llvm::Type* argTypes[] = {Type::Word, Type::Word, Type::Word}; - m_addmod = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "addmod", getModule()); - m_addmod->setDoesNotThrow(); - m_addmod->setDoesNotAccessMemory(); - - auto x = &m_addmod->getArgumentList().front(); - x->setName("x"); - auto y = x->getNextNode(); - y->setName("y"); - auto mod = y->getNextNode(); - mod->setName("m"); - - InsertPointGuard guard{m_builder}; - - auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), {}, m_addmod); - m_builder.SetInsertPoint(entryBB); - auto x512 = m_builder.CreateZExt(x, i512Ty, "x512"); - auto y512 = m_builder.CreateZExt(y, i512Ty, "y512"); - auto m512 = m_builder.CreateZExt(mod, i512Ty, "m512"); - auto s = m_builder.CreateAdd(x512, y512, "s"); - auto d = createCall(getDivFunc(i512Ty), {s, m512}); - auto r = m_builder.CreateExtractValue(d, 1, "r"); - m_builder.CreateRet(m_builder.CreateTrunc(r, Type::Word)); - } - return m_addmod; -} - -llvm::Function* Arith256::getMulModFunc() -{ - if (!m_mulmod) - { - llvm::Type* argTypes[] = {Type::Word, Type::Word, Type::Word}; - m_mulmod = llvm::Function::Create(llvm::FunctionType::get(Type::Word, argTypes, false), llvm::Function::PrivateLinkage, "mulmod", getModule()); - m_mulmod->setDoesNotThrow(); - m_mulmod->setDoesNotAccessMemory(); - - auto i512Ty = m_builder.getIntNTy(512); - auto x = &m_mulmod->getArgumentList().front(); - x->setName("x"); - auto y = x->getNextNode(); - y->setName("y"); - auto mod = y->getNextNode(); - mod->setName("mod"); - - InsertPointGuard guard{m_builder}; - - auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), {}, m_mulmod); - m_builder.SetInsertPoint(entryBB); - auto p = createCall(getMul512Func(), {x, y}); - auto m = m_builder.CreateZExt(mod, i512Ty, "m"); - auto d = createCall(getDivFunc(i512Ty), {p, m}); - auto r = m_builder.CreateExtractValue(d, 1, "r"); - r = m_builder.CreateTrunc(r, Type::Word); - m_builder.CreateRet(r); - } - return m_mulmod; -} - -llvm::Value* Arith256::mul(llvm::Value* _arg1, llvm::Value* _arg2) -{ - if (auto c1 = llvm::dyn_cast(_arg1)) - { - if (auto c2 = llvm::dyn_cast(_arg2)) - return Constant::get(c1->getValue() * c2->getValue()); - } - - return createCall(getMulFunc(), {_arg1, _arg2}); -} - -std::pair Arith256::div(llvm::Value* _arg1, llvm::Value* _arg2) -{ - // FIXME: Disabled because of llvm::APInt::urem bug -// if (auto c1 = llvm::dyn_cast(_arg1)) -// { -// if (auto c2 = llvm::dyn_cast(_arg2)) -// { -// if (!c2->getValue()) -// return std::make_pair(Constant::get(0), Constant::get(0)); -// auto div = Constant::get(c1->getValue().udiv(c2->getValue())); -// auto mod = Constant::get(c1->getValue().urem(c2->getValue())); -// return std::make_pair(div, mod); -// } -// } - - auto r = createCall(getDivFunc(Type::Word), {_arg1, _arg2}); - auto div = m_builder.CreateExtractValue(r, 0, "div"); - auto mod = m_builder.CreateExtractValue(r, 1, "mod"); - return std::make_pair(div, mod); -} - -std::pair Arith256::sdiv(llvm::Value* _x, llvm::Value* _y) -{ - // FIXME: Disabled because of llvm::APInt::urem bug -// if (auto c1 = llvm::dyn_cast(_x)) -// { -// if (auto c2 = llvm::dyn_cast(_y)) -// { -// if (!c2->getValue()) -// return std::make_pair(Constant::get(0), Constant::get(0)); -// auto div = Constant::get(c1->getValue().sdiv(c2->getValue())); -// auto mod = Constant::get(c1->getValue().srem(c2->getValue())); -// return std::make_pair(div, mod); -// } -// } - - auto xIsNeg = m_builder.CreateICmpSLT(_x, Constant::get(0)); - auto xNeg = m_builder.CreateSub(Constant::get(0), _x); - auto xAbs = m_builder.CreateSelect(xIsNeg, xNeg, _x); - - auto yIsNeg = m_builder.CreateICmpSLT(_y, Constant::get(0)); - auto yNeg = m_builder.CreateSub(Constant::get(0), _y); - auto yAbs = m_builder.CreateSelect(yIsNeg, yNeg, _y); - - auto res = div(xAbs, yAbs); - - // the reminder has the same sign as dividend - auto rNeg = m_builder.CreateSub(Constant::get(0), res.second); - res.second = m_builder.CreateSelect(xIsNeg, rNeg, res.second); - - auto qNeg = m_builder.CreateSub(Constant::get(0), res.first); - auto xyOpposite = m_builder.CreateXor(xIsNeg, yIsNeg); - res.first = m_builder.CreateSelect(xyOpposite, qNeg, res.first); - - return res; -} - llvm::Value* Arith256::exp(llvm::Value* _arg1, llvm::Value* _arg2) { // while (e != 0) { @@ -445,49 +494,6 @@ llvm::Value* Arith256::exp(llvm::Value* _arg1, llvm::Value* _arg2) return createCall(getExpFunc(), {_arg1, _arg2}); } -llvm::Value* Arith256::addmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3) -{ - // FIXME: Disabled because of llvm::APInt::urem bug -// if (auto c1 = llvm::dyn_cast(_arg1)) -// { -// if (auto c2 = llvm::dyn_cast(_arg2)) -// { -// if (auto c3 = llvm::dyn_cast(_arg3)) -// { -// if (!c3->getValue()) -// return Constant::get(0); -// auto s = c1->getValue().zext(256+64) + c2->getValue().zext(256+64); -// auto r = s.urem(c3->getValue().zext(256+64)).trunc(256); -// return Constant::get(r); -// } -// } -// } - - return createCall(getAddModFunc(), {_arg1, _arg2, _arg3}); -} - -llvm::Value* Arith256::mulmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3) -{ - // FIXME: Disabled because of llvm::APInt::urem bug -// if (auto c1 = llvm::dyn_cast(_arg1)) -// { -// if (auto c2 = llvm::dyn_cast(_arg2)) -// { -// if (auto c3 = llvm::dyn_cast(_arg3)) -// { -// if (!c3->getValue()) -// return Constant::get(0); -// auto p = c1->getValue().zext(512) * c2->getValue().zext(512); -// auto r = p.urem(c3->getValue().zext(512)).trunc(256); -// return Constant::get(r); -// } -// } -// } - - return createCall(getMulModFunc(), {_arg1, _arg2, _arg3}); -} - - } } } diff --git a/evmjit/libevmjit/Arith256.h b/evmjit/libevmjit/Arith256.h index 2513ca568..81535a792 100644 --- a/evmjit/libevmjit/Arith256.h +++ b/evmjit/libevmjit/Arith256.h @@ -14,30 +14,25 @@ class Arith256 : public CompilerHelper public: Arith256(llvm::IRBuilder<>& _builder); - llvm::Value* mul(llvm::Value* _arg1, llvm::Value* _arg2); - std::pair div(llvm::Value* _arg1, llvm::Value* _arg2); - std::pair sdiv(llvm::Value* _arg1, llvm::Value* _arg2); llvm::Value* exp(llvm::Value* _arg1, llvm::Value* _arg2); - llvm::Value* mulmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3); - llvm::Value* addmod(llvm::Value* _arg1, llvm::Value* _arg2, llvm::Value* _arg3); void debug(llvm::Value* _value, char _c); + static llvm::Function* getMulFunc(llvm::Module& _module); + static llvm::Function* getMul512Func(llvm::Module& _module); + static llvm::Function* getUDiv256Func(llvm::Module& _module); + static llvm::Function* getURem256Func(llvm::Module& _module); + static llvm::Function* getURem512Func(llvm::Module& _module); + static llvm::Function* getUDivRem256Func(llvm::Module& _module); + static llvm::Function* getSDiv256Func(llvm::Module& _module); + static llvm::Function* getSRem256Func(llvm::Module& _module); + static llvm::Function* getSDivRem256Func(llvm::Module& _module); + static llvm::Function* getUDivRem512Func(llvm::Module& _module); + private: - llvm::Function* getMulFunc(); - llvm::Function* getMul512Func(); - llvm::Function* getDivFunc(llvm::Type* _type); llvm::Function* getExpFunc(); - llvm::Function* getAddModFunc(); - llvm::Function* getMulModFunc(); - llvm::Function* m_mul = nullptr; - llvm::Function* m_mul512 = nullptr; - llvm::Function* m_div = nullptr; - llvm::Function* m_div512 = nullptr; llvm::Function* m_exp = nullptr; - llvm::Function* m_addmod = nullptr; - llvm::Function* m_mulmod = nullptr; llvm::Function* m_debug = nullptr; }; diff --git a/evmjit/libevmjit/Array.cpp b/evmjit/libevmjit/Array.cpp index 9a7f18597..96329afd5 100644 --- a/evmjit/libevmjit/Array.cpp +++ b/evmjit/libevmjit/Array.cpp @@ -6,7 +6,6 @@ #include "preprocessor/llvm_includes_end.h" #include "RuntimeManager.h" -#include "Runtime.h" #include "Utils.h" namespace dev @@ -17,7 +16,6 @@ namespace jit { static const auto c_reallocStep = 1; -static const auto c_reallocMultipier = 2; llvm::Value* LazyFunction::call(llvm::IRBuilder<>& _builder, std::initializer_list const& _args, llvm::Twine const& _name) { @@ -56,7 +54,6 @@ llvm::Function* Array::createArrayPushFunc() m_builder.SetInsertPoint(reallocBB); auto newCap = m_builder.CreateNUWAdd(cap, m_builder.getInt64(c_reallocStep), "newCap"); - //newCap = m_builder.CreateNUWMul(newCap, m_builder.getInt64(c_reallocMultipier)); auto reallocSize = m_builder.CreateShl(newCap, 5, "reallocSize"); // size in bytes: newCap * 32 auto bytes = m_builder.CreateBitCast(data, Type::BytePtr, "bytes"); auto newBytes = m_reallocFunc.call(m_builder, {bytes, reallocSize}, "newBytes"); diff --git a/evmjit/libevmjit/BasicBlock.h b/evmjit/libevmjit/BasicBlock.h index 5e19235a7..321499196 100644 --- a/evmjit/libevmjit/BasicBlock.h +++ b/evmjit/libevmjit/BasicBlock.h @@ -11,7 +11,7 @@ namespace eth { namespace jit { - +using namespace evmjit; using instr_idx = uint64_t; class BasicBlock diff --git a/evmjit/libevmjit/CMakeLists.txt b/evmjit/libevmjit/CMakeLists.txt index 4b15d52ac..80108e15b 100644 --- a/evmjit/libevmjit/CMakeLists.txt +++ b/evmjit/libevmjit/CMakeLists.txt @@ -1,26 +1,22 @@ set(TARGET_NAME evmjit) set(SOURCES + JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h Arith256.cpp Arith256.h Array.cpp Array.h BasicBlock.cpp BasicBlock.h Cache.cpp Cache.h - Common.h + Common.h Compiler.cpp Compiler.h CompilerHelper.cpp CompilerHelper.h - ${EVMJIT_INCLUDE_DIR}/evmjit/DataTypes.h Endianness.cpp Endianness.h ExecStats.cpp ExecStats.h - ExecutionEngine.cpp ExecutionEngine.h Ext.cpp Ext.h GasMeter.cpp GasMeter.h Instruction.cpp Instruction.h interface.cpp interface.h - JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h Memory.cpp Memory.h Optimizer.cpp Optimizer.h - Runtime.cpp Runtime.h - RuntimeData.h RuntimeManager.cpp RuntimeManager.h Stack.cpp Stack.h Type.cpp Type.h diff --git a/evmjit/libevmjit/Cache.cpp b/evmjit/libevmjit/Cache.cpp index 36dae3763..01b1c8766 100644 --- a/evmjit/libevmjit/Cache.cpp +++ b/evmjit/libevmjit/Cache.cpp @@ -12,15 +12,13 @@ #include #include "preprocessor/llvm_includes_end.h" -#include "ExecutionEngine.h" +#include "ExecStats.h" #include "Utils.h" #include "BuildInfo.gen.h" namespace dev { -namespace eth -{ -namespace jit +namespace evmjit { namespace @@ -29,7 +27,7 @@ namespace std::mutex x_cacheMutex; CacheMode g_mode; std::unique_ptr g_lastObject; - ExecutionEngineListener* g_listener; + JITListener* g_listener; static const size_t c_versionStampLength = 32; llvm::StringRef getLibVersionStamp() @@ -44,15 +42,25 @@ namespace } } -ObjectCache* Cache::getObjectCache(CacheMode _mode, ExecutionEngineListener* _listener) +ObjectCache* Cache::init(CacheMode _mode, JITListener* _listener) { - static ObjectCache objectCache; - Guard g{x_cacheMutex}; g_mode = _mode; g_listener = _listener; - return &objectCache; + + if (g_mode == CacheMode::clear) + { + Cache::clear(); + g_mode = CacheMode::off; + } + + if (g_mode != CacheMode::off) + { + static ObjectCache objectCache; + return &objectCache; + } + return nullptr; } void Cache::clear() @@ -185,4 +193,3 @@ std::unique_ptr ObjectCache::getObject(llvm::Module const* _ } } -} diff --git a/evmjit/libevmjit/Cache.h b/evmjit/libevmjit/Cache.h index 1d5927705..5de4222fc 100644 --- a/evmjit/libevmjit/Cache.h +++ b/evmjit/libevmjit/Cache.h @@ -14,11 +14,9 @@ namespace llvm namespace dev { -namespace eth +namespace evmjit { -namespace jit -{ -class ExecutionEngineListener; +class JITListener; enum class CacheMode { @@ -47,7 +45,7 @@ public: class Cache { public: - static ObjectCache* getObjectCache(CacheMode _mode, ExecutionEngineListener* _listener); + static ObjectCache* init(CacheMode _mode, JITListener* _listener); static std::unique_ptr getObject(std::string const& id); /// Clears cache storage @@ -59,4 +57,3 @@ public: } } -} diff --git a/evmjit/libevmjit/Common.h b/evmjit/libevmjit/Common.h index b519614fe..4a6d7b4f3 100644 --- a/evmjit/libevmjit/Common.h +++ b/evmjit/libevmjit/Common.h @@ -1,53 +1,16 @@ #pragma once -#include #include -#ifdef _MSC_VER -#define EXPORT __declspec(dllexport) -#define _ALLOW_KEYWORD_MACROS -#define noexcept throw() -#else -#define EXPORT -#endif - namespace dev { -namespace eth -{ -namespace jit +namespace evmjit { using byte = uint8_t; -using bytes_ref = std::tuple; using code_iterator = byte const*; -enum class ReturnCode -{ - // Success codes - Stop = 0, - Return = 1, - Suicide = 2, - - // Standard error codes - OutOfGas = -1, - StackUnderflow = -2, - BadJumpDestination = -3, - BadInstruction = -4, - Rejected = -5, ///< Input data (code, gas, block info, etc.) does not meet JIT requirement and execution request has been rejected - - // Internal error codes - LLVMConfigError = -101, - LLVMCompileError = -102, - LLVMLinkError = -103, - - UnexpectedException = -111, - - LinkerWorkaround = -299, -}; - #define UNTESTED assert(false) } } -} diff --git a/evmjit/libevmjit/Compiler.cpp b/evmjit/libevmjit/Compiler.cpp index e49979294..a44e4e890 100644 --- a/evmjit/libevmjit/Compiler.cpp +++ b/evmjit/libevmjit/Compiler.cpp @@ -49,6 +49,11 @@ void Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEn return _curr + offset; }; + // Skip all STOPs in the end + for (; _codeEnd != _codeBegin; --_codeEnd) + if (*(_codeEnd - 1) != static_cast(Instruction::STOP)) + break; + auto begin = _codeBegin; // begin of current block bool nextJumpDest = false; for (auto curr = begin, next = begin; curr != _codeEnd; curr = next) @@ -159,10 +164,10 @@ std::unique_ptr Compiler::compile(code_iterator _begin, code_itera // TODO: Create Stop basic block on demand m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc); - auto abortBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Abort", m_mainFunc); + m_abortBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Abort", m_mainFunc); auto firstBB = m_basicBlocks.empty() ? m_stopBB : m_basicBlocks.begin()->second.llvm(); - m_builder.CreateCondBr(normalFlow, firstBB, abortBB, Type::expectTrue); + m_builder.CreateCondBr(normalFlow, firstBB, m_abortBB, Type::expectTrue); for (auto basicBlockPairIt = m_basicBlocks.begin(); basicBlockPairIt != m_basicBlocks.end(); ++basicBlockPairIt) { @@ -178,7 +183,7 @@ std::unique_ptr Compiler::compile(code_iterator _begin, code_itera m_builder.SetInsertPoint(m_stopBB); runtimeManager.exit(ReturnCode::Stop); - m_builder.SetInsertPoint(abortBB); + m_builder.SetInsertPoint(m_abortBB); runtimeManager.exit(ReturnCode::OutOfGas); removeDeadBlocks(); @@ -270,44 +275,96 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti { auto lhs = stack.pop(); auto rhs = stack.pop(); - auto res = _arith.mul(lhs, rhs); + auto res = m_builder.CreateMul(lhs, rhs); stack.push(res); break; } case Instruction::DIV: { - auto lhs = stack.pop(); - auto rhs = stack.pop(); - auto res = _arith.div(lhs, rhs); - stack.push(res.first); + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateUDiv(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + stack.push(r); break; } case Instruction::SDIV: { - auto lhs = stack.pop(); - auto rhs = stack.pop(); - auto res = _arith.sdiv(lhs, rhs); - stack.push(res.first); + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + auto divByMinusOne = m_builder.CreateICmpEQ(n, Constant::get(-1)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateSDiv(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + auto dNeg = m_builder.CreateSub(Constant::get(0), d); + r = m_builder.CreateSelect(divByMinusOne, dNeg, r); // protect against undef i256.min / -1 + stack.push(r); break; } case Instruction::MOD: { - auto lhs = stack.pop(); - auto rhs = stack.pop(); - auto res = _arith.div(lhs, rhs); - stack.push(res.second); + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateURem(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + stack.push(r); break; } case Instruction::SMOD: { - auto lhs = stack.pop(); - auto rhs = stack.pop(); - auto res = _arith.sdiv(lhs, rhs); - stack.push(res.second); + auto d = stack.pop(); + auto n = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(n, Constant::get(0)); + auto divByMinusOne = m_builder.CreateICmpEQ(n, Constant::get(-1)); + n = m_builder.CreateSelect(divByZero, Constant::get(1), n); // protect against hardware signal + auto r = m_builder.CreateSRem(d, n); + r = m_builder.CreateSelect(divByZero, Constant::get(0), r); + r = m_builder.CreateSelect(divByMinusOne, Constant::get(0), r); // protect against undef i256.min / -1 + stack.push(r); + break; + } + + case Instruction::ADDMOD: + { + auto i512Ty = m_builder.getIntNTy(512); + auto a = stack.pop(); + auto b = stack.pop(); + auto m = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(m, Constant::get(0)); + a = m_builder.CreateZExt(a, i512Ty); + b = m_builder.CreateZExt(b, i512Ty); + m = m_builder.CreateZExt(m, i512Ty); + auto s = m_builder.CreateNUWAdd(a, b); + s = m_builder.CreateURem(s, m); + s = m_builder.CreateTrunc(s, Type::Word); + s = m_builder.CreateSelect(divByZero, Constant::get(0), s); + stack.push(s); + break; + } + + case Instruction::MULMOD: + { + auto i512Ty = m_builder.getIntNTy(512); + auto a = stack.pop(); + auto b = stack.pop(); + auto m = stack.pop(); + auto divByZero = m_builder.CreateICmpEQ(m, Constant::get(0)); + m = m_builder.CreateZExt(m, i512Ty); + // TODO: Add support for i256 x i256 -> i512 in LowerEVM pass + llvm::Value* p = m_builder.CreateCall(Arith256::getMul512Func(*_basicBlock.llvm()->getParent()->getParent()), {a, b}); + p = m_builder.CreateURem(p, m); + p = m_builder.CreateTrunc(p, Type::Word); + p = m_builder.CreateSelect(divByZero, Constant::get(0), p); + stack.push(p); break; } @@ -417,48 +474,29 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti case Instruction::BYTE: { - const auto byteNum = stack.pop(); - auto value = stack.pop(); + const auto idx = stack.pop(); + auto value = Endianness::toBE(m_builder, stack.pop()); - value = Endianness::toBE(m_builder, value); + auto idxValid = m_builder.CreateICmpULT(idx, Constant::get(32), "idxValid"); auto bytes = m_builder.CreateBitCast(value, llvm::VectorType::get(Type::Byte, 32), "bytes"); - auto safeByteNum = m_builder.CreateZExt(m_builder.CreateTrunc(byteNum, m_builder.getIntNTy(5)), Type::lowPrecision); // Trim index, large values can crash - auto byte = m_builder.CreateExtractElement(bytes, safeByteNum, "byte"); + // TODO: Workaround for LLVM bug. Using big value of index causes invalid memory access. + auto safeIdx = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5)); + // TODO: Workaround for LLVM bug. DAG Builder used sext on index instead of zext + safeIdx = m_builder.CreateZExt(safeIdx, Type::Size); + auto byte = m_builder.CreateExtractElement(bytes, safeIdx, "byte"); value = m_builder.CreateZExt(byte, Type::Word); - - auto byteNumValid = m_builder.CreateICmpULT(byteNum, Constant::get(32)); - value = m_builder.CreateSelect(byteNumValid, value, Constant::get(0)); + value = m_builder.CreateSelect(idxValid, value, Constant::get(0)); stack.push(value); break; } - case Instruction::ADDMOD: - { - auto lhs = stack.pop(); - auto rhs = stack.pop(); - auto mod = stack.pop(); - auto res = _arith.addmod(lhs, rhs, mod); - stack.push(res); - break; - } - - case Instruction::MULMOD: - { - auto lhs = stack.pop(); - auto rhs = stack.pop(); - auto mod = stack.pop(); - auto res = _arith.mulmod(lhs, rhs, mod); - stack.push(res); - break; - } - case Instruction::SIGNEXTEND: { auto idx = stack.pop(); auto word = stack.pop(); auto k32_ = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5), "k_32"); - auto k32 = m_builder.CreateZExt(k32_, Type::lowPrecision); + auto k32 = m_builder.CreateZExt(k32_, Type::Size); auto k32x8 = m_builder.CreateMul(k32, m_builder.getInt64(8), "kx8"); // test for word >> (k * 8 + 7) @@ -495,11 +533,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti case Instruction::POP: { - auto val = stack.pop(); - static_cast(val); - // Generate a dummy use of val to make sure that a get(0) will be emitted at this point, - // so that StackUnderflow will be thrown - // m_builder.CreateICmpEQ(val, val, "dummy"); + stack.pop(); break; } @@ -656,7 +690,6 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti } case Instruction::CODESIZE: - // TODO: Use constant stack.push(_runtimeManager.getCodeSize()); break; @@ -729,8 +762,8 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti case Instruction::CALLDATALOAD: { - auto index = stack.pop(); - auto value = _ext.calldataload(index); + auto idx = stack.pop(); + auto value = _ext.calldataload(idx); stack.push(value); break; } @@ -797,7 +830,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti case Instruction::STOP: { - m_builder.CreateRet(Constant::get(ReturnCode::Stop)); + m_builder.CreateBr(m_stopBB); break; } @@ -824,7 +857,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti } default: // Invalid instruction - abort - m_builder.CreateRet(Constant::get(ReturnCode::BadInstruction)); + m_builder.CreateBr(m_abortBB); it = _basicBlock.end() - 1; // finish block compilation } } @@ -942,4 +975,3 @@ void Compiler::dump() } } } - diff --git a/evmjit/libevmjit/Compiler.h b/evmjit/libevmjit/Compiler.h index 4469389bb..0b31ae0f2 100644 --- a/evmjit/libevmjit/Compiler.h +++ b/evmjit/libevmjit/Compiler.h @@ -1,6 +1,5 @@ #pragma once -#include "Common.h" #include "BasicBlock.h" namespace dev @@ -65,6 +64,9 @@ private: /// Stop basic block - terminates execution with STOP code (0) llvm::BasicBlock* m_stopBB = nullptr; + /// Abort basic block - terminates execution with OOG-like state + llvm::BasicBlock* m_abortBB = nullptr; + /// Block with a jump table. std::unique_ptr m_jumpTableBlock; diff --git a/evmjit/libevmjit/CompilerHelper.h b/evmjit/libevmjit/CompilerHelper.h index cd6d09a58..5eeae9a6e 100644 --- a/evmjit/libevmjit/CompilerHelper.h +++ b/evmjit/libevmjit/CompilerHelper.h @@ -37,7 +37,6 @@ protected: friend class RuntimeHelper; }; - /// Compiler helper that depends on runtime data class RuntimeHelper : public CompilerHelper { @@ -50,29 +49,7 @@ private: RuntimeManager& m_runtimeManager; }; - -/// Saves the insert point of the IR builder and restores it when destructed -struct InsertPointGuard -{ - InsertPointGuard(llvm::IRBuilder<>& _builder) : - m_builder(_builder), - m_insertBB(m_builder.GetInsertBlock()), - m_insertPt(m_builder.GetInsertPoint()) - {} - - InsertPointGuard(const InsertPointGuard&) = delete; - void operator=(InsertPointGuard) = delete; - - ~InsertPointGuard() - { - m_builder.SetInsertPoint(m_insertBB, m_insertPt); - } - -private: - llvm::IRBuilder<>& m_builder; - llvm::BasicBlock* m_insertBB; - llvm::BasicBlock::iterator m_insertPt; -}; +using InsertPointGuard = llvm::IRBuilderBase::InsertPointGuard; } } diff --git a/evmjit/libevmjit/ExecStats.cpp b/evmjit/libevmjit/ExecStats.cpp index ff8c05307..c7f6ef0cd 100644 --- a/evmjit/libevmjit/ExecStats.cpp +++ b/evmjit/libevmjit/ExecStats.cpp @@ -8,9 +8,7 @@ namespace dev { -namespace eth -{ -namespace jit +namespace evmjit { void ExecStats::stateChanged(ExecState _state) @@ -95,4 +93,3 @@ StatsCollector::~StatsCollector() } } -} diff --git a/evmjit/libevmjit/ExecStats.h b/evmjit/libevmjit/ExecStats.h index 0451ccb05..4a5ae00e1 100644 --- a/evmjit/libevmjit/ExecStats.h +++ b/evmjit/libevmjit/ExecStats.h @@ -1,19 +1,43 @@ #pragma once +#include #include #include #include -#include "ExecutionEngine.h" - namespace dev { -namespace eth +namespace evmjit +{ + +enum class ExecState { -namespace jit + Started, + CacheLoad, + CacheWrite, + Compilation, + Optimization, + CodeGen, + Execution, + Return, + Finished +}; + +class JITListener { +public: + JITListener() = default; + JITListener(JITListener const&) = delete; + JITListener& operator=(JITListener) = delete; + virtual ~JITListener() {} + + virtual void executionStarted() {} + virtual void executionEnded() {} -class ExecStats : public ExecutionEngineListener + virtual void stateChanged(ExecState) {} +}; + +class ExecStats : public JITListener { public: using clock = std::chrono::high_resolution_clock; @@ -42,4 +66,3 @@ public: } } -} diff --git a/evmjit/libevmjit/ExecutionEngine.cpp b/evmjit/libevmjit/ExecutionEngine.cpp deleted file mode 100644 index a5b26401f..000000000 --- a/evmjit/libevmjit/ExecutionEngine.cpp +++ /dev/null @@ -1,192 +0,0 @@ -#include "ExecutionEngine.h" - -#include -#include -#include -#include -#include -#include - -#include "preprocessor/llvm_includes_start.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "preprocessor/llvm_includes_end.h" - -#include "evmjit/JIT.h" -#include "Runtime.h" -#include "Compiler.h" -#include "Optimizer.h" -#include "Cache.h" -#include "ExecStats.h" -#include "Utils.h" -#include "BuildInfo.gen.h" - -namespace dev -{ -namespace eth -{ -namespace jit -{ -using evmjit::JIT; - -namespace -{ -using EntryFuncPtr = ReturnCode(*)(Runtime*); - -std::string codeHash(i256 const& _hash) -{ - static const auto size = sizeof(_hash); - static const auto hexChars = "0123456789abcdef"; - std::string str; - str.resize(size * 2); - auto outIt = str.rbegin(); // reverse for BE - auto& arr = *(std::array*)&_hash; - for (auto b : arr) - { - *(outIt++) = hexChars[b & 0xf]; - *(outIt++) = hexChars[b >> 4]; - } - return str; -} - -void printVersion() -{ - std::cout << "Ethereum EVM JIT Compiler (http://github.com/ethereum/evmjit):\n" - << " EVMJIT version " << EVMJIT_VERSION << "\n" -#ifdef NDEBUG - << " Optimized build, " EVMJIT_VERSION_FULL "\n" -#else - << " DEBUG build, " EVMJIT_VERSION_FULL "\n" -#endif - << " Built " << __DATE__ << " (" << __TIME__ << ")\n" - << std::endl; -} - -namespace cl = llvm::cl; -cl::opt g_optimize{"O", cl::desc{"Optimize"}}; -cl::opt g_cache{"cache", cl::desc{"Cache compiled EVM code on disk"}, - cl::values( - clEnumValN(CacheMode::on, "1", "Enabled"), - clEnumValN(CacheMode::off, "0", "Disabled"), - clEnumValN(CacheMode::read, "r", "Read only. No new objects are added to cache."), - clEnumValN(CacheMode::write, "w", "Write only. No objects are loaded from cache."), - clEnumValN(CacheMode::clear, "c", "Clear the cache storage. Cache is disabled."), - clEnumValN(CacheMode::preload, "p", "Preload all cached objects."), - clEnumValEnd)}; -cl::opt g_stats{"st", cl::desc{"Statistics"}}; -cl::opt g_dump{"dump", cl::desc{"Dump LLVM IR module"}}; - -void parseOptions() -{ - static llvm::llvm_shutdown_obj shutdownObj{}; - cl::AddExtraVersionPrinter(printVersion); - cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); -} - -} - - -ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) -{ - static std::once_flag flag; - std::call_once(flag, parseOptions); - - std::unique_ptr listener{new ExecStats}; - listener->stateChanged(ExecState::Started); - - bool preloadCache = g_cache == CacheMode::preload; - if (preloadCache) - g_cache = CacheMode::on; - - // TODO: Do not pseudo-init the cache every time - auto objectCache = (g_cache != CacheMode::off && g_cache != CacheMode::clear) ? Cache::getObjectCache(g_cache, listener.get()) : nullptr; - - static std::unique_ptr ee; - if (!ee) - { - if (g_cache == CacheMode::clear) - Cache::clear(); - - llvm::InitializeNativeTarget(); - llvm::InitializeNativeTargetAsmPrinter(); - - auto module = std::unique_ptr(new llvm::Module({}, llvm::getGlobalContext())); - - // FIXME: LLVM 3.7: test on Windows - auto triple = llvm::Triple(llvm::sys::getProcessTriple()); - if (triple.getOS() == llvm::Triple::OSType::Win32) - triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format - module->setTargetTriple(triple.str()); - - llvm::EngineBuilder builder(std::move(module)); - builder.setEngineKind(llvm::EngineKind::JIT); - builder.setOptLevel(g_optimize ? llvm::CodeGenOpt::Default : llvm::CodeGenOpt::None); - - ee.reset(builder.create()); - if (!CHECK(ee)) - return ReturnCode::LLVMConfigError; - ee->setObjectCache(objectCache); - - // FIXME: Disabled during API changes - //if (preloadCache) - // Cache::preload(*ee, funcCache); - } - - static StatsCollector statsCollector; - - auto mainFuncName = codeHash(_data->codeHash); - m_runtime.init(_data, _env); - - // TODO: Remove cast - auto entryFuncPtr = (EntryFuncPtr) JIT::getCode(_data->codeHash); - if (!entryFuncPtr) - { - auto module = objectCache ? Cache::getObject(mainFuncName) : nullptr; - if (!module) - { - listener->stateChanged(ExecState::Compilation); - assert(_data->code || !_data->codeSize); //TODO: Is it good idea to execute empty code? - module = Compiler{{}}.compile(_data->code, _data->code + _data->codeSize, mainFuncName); - - if (g_optimize) - { - listener->stateChanged(ExecState::Optimization); - optimize(*module); - } - } - if (g_dump) - module->dump(); - - ee->addModule(std::move(module)); - listener->stateChanged(ExecState::CodeGen); - entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName); - if (!CHECK(entryFuncPtr)) - return ReturnCode::LLVMLinkError; - JIT::mapCode(_data->codeHash, (uint64_t)entryFuncPtr); // FIXME: Remove cast - } - - listener->stateChanged(ExecState::Execution); - auto returnCode = entryFuncPtr(&m_runtime); - listener->stateChanged(ExecState::Return); - - if (returnCode == ReturnCode::Return) - returnData = m_runtime.getReturnData(); // Save reference to return data - - listener->stateChanged(ExecState::Finished); - - if (g_stats) - statsCollector.stats.push_back(std::move(listener)); - - return returnCode; -} - -} -} -} diff --git a/evmjit/libevmjit/ExecutionEngine.h b/evmjit/libevmjit/ExecutionEngine.h deleted file mode 100644 index 26da6977c..000000000 --- a/evmjit/libevmjit/ExecutionEngine.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include - -#include "Runtime.h" - -namespace dev -{ -namespace eth -{ -namespace jit -{ - -enum class ExecState -{ - Started, - CacheLoad, - CacheWrite, - Compilation, - Optimization, - CodeGen, - Execution, - Return, - Finished -}; - -class ExecutionEngineListener -{ -public: - ExecutionEngineListener() = default; - ExecutionEngineListener(ExecutionEngineListener const&) = delete; - ExecutionEngineListener& operator=(ExecutionEngineListener) = delete; - virtual ~ExecutionEngineListener() {} - - virtual void executionStarted() {} - virtual void executionEnded() {} - - virtual void stateChanged(ExecState) {} -}; - -class ExecutionEngine -{ -public: - ExecutionEngine() = default; - ExecutionEngine(ExecutionEngine const&) = delete; - ExecutionEngine& operator=(ExecutionEngine) = delete; - - EXPORT ReturnCode run(RuntimeData* _data, Env* _env); - - /// Reference to returned data (RETURN opcode used) - bytes_ref returnData; - -private: - Runtime m_runtime; -}; - -} -} -} diff --git a/evmjit/libevmjit/Ext.cpp b/evmjit/libevmjit/Ext.cpp index d35aebc68..b8b124ff5 100644 --- a/evmjit/libevmjit/Ext.cpp +++ b/evmjit/libevmjit/Ext.cpp @@ -45,7 +45,6 @@ std::array::value> const& getEnvFuncDescs() FuncDesc{"env_log", getFunctionType(Type::Void, {Type::EnvPtr, Type::BytePtr, Type::Size, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr})}, FuncDesc{"env_blockhash", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})}, FuncDesc{"env_extcode", getFunctionType(Type::BytePtr, {Type::EnvPtr, Type::WordPtr, Type::Size->getPointerTo()})}, - FuncDesc{"ext_calldataload", getFunctionType(Type::Void, {Type::RuntimeDataPtr, Type::WordPtr, Type::WordPtr})}, }}; return descs; @@ -101,12 +100,27 @@ void Ext::sstore(llvm::Value* _index, llvm::Value* _value) createCall(EnvFunc::sstore, {getRuntimeManager().getEnvPtr(), byPtr(_index), byPtr(_value)}); // Uses native endianness } -llvm::Value* Ext::calldataload(llvm::Value* _index) +llvm::Value* Ext::calldataload(llvm::Value* _idx) { auto ret = getArgAlloca(); - createCall(EnvFunc::calldataload, {getRuntimeManager().getDataPtr(), byPtr(_index), ret}); - ret = m_builder.CreateLoad(ret); - return Endianness::toNative(m_builder, ret); + auto result = m_builder.CreateBitCast(ret, Type::BytePtr); + + auto callDataSize = getRuntimeManager().getCallDataSize(); + auto callDataSize64 = m_builder.CreateTrunc(callDataSize, Type::Size); + auto idxValid = m_builder.CreateICmpULT(_idx, callDataSize); + auto idx = m_builder.CreateTrunc(m_builder.CreateSelect(idxValid, _idx, callDataSize), Type::Size, "idx"); + + auto end = m_builder.CreateNUWAdd(idx, m_builder.getInt64(32)); + end = m_builder.CreateSelect(m_builder.CreateICmpULE(end, callDataSize64), end, callDataSize64); + auto copySize = m_builder.CreateNUWSub(end, idx); + auto padSize = m_builder.CreateNUWSub(m_builder.getInt64(32), copySize); + auto dataBegin = m_builder.CreateGEP(Type::Byte, getRuntimeManager().getCallData(), idx); + m_builder.CreateMemCpy(result, dataBegin, copySize, 1); + auto pad = m_builder.CreateGEP(Type::Byte, result, copySize); + m_builder.CreateMemSet(pad, m_builder.getInt8(0), padSize, 1); + + m_argCounter = 0; // Release args allocas. TODO: This is a bad design + return Endianness::toNative(m_builder, m_builder.CreateLoad(ret)); } llvm::Value* Ext::balance(llvm::Value* _address) diff --git a/evmjit/libevmjit/Ext.h b/evmjit/libevmjit/Ext.h index b0048d2e9..2af074f4a 100644 --- a/evmjit/libevmjit/Ext.h +++ b/evmjit/libevmjit/Ext.h @@ -35,7 +35,6 @@ enum class EnvFunc log, blockhash, extcode, - calldataload, // Helper function, not client Env interface _size }; @@ -63,7 +62,6 @@ private: Memory& m_memoryMan; llvm::Value* m_size; - llvm::Value* m_data = nullptr; std::array::value> m_funcs; std::array m_argAllocas; diff --git a/evmjit/libevmjit/GasMeter.h b/evmjit/libevmjit/GasMeter.h index aecc07315..93a6cc24c 100644 --- a/evmjit/libevmjit/GasMeter.h +++ b/evmjit/libevmjit/GasMeter.h @@ -10,6 +10,7 @@ namespace eth namespace jit { class RuntimeManager; +using namespace evmjit; class GasMeter : public CompilerHelper // TODO: Use RuntimeHelper { diff --git a/evmjit/libevmjit/Instruction.cpp b/evmjit/libevmjit/Instruction.cpp index f70b020f8..c2e267cdb 100644 --- a/evmjit/libevmjit/Instruction.cpp +++ b/evmjit/libevmjit/Instruction.cpp @@ -6,9 +6,7 @@ namespace dev { -namespace eth -{ -namespace jit +namespace evmjit { llvm::APInt readPushData(code_iterator& _curr, code_iterator _end) @@ -39,4 +37,3 @@ void skipPushData(code_iterator& _curr, code_iterator _end) } } -} diff --git a/evmjit/libevmjit/Instruction.h b/evmjit/libevmjit/Instruction.h index 6785213d6..89add0958 100644 --- a/evmjit/libevmjit/Instruction.h +++ b/evmjit/libevmjit/Instruction.h @@ -9,9 +9,7 @@ namespace llvm namespace dev { -namespace eth -{ -namespace jit +namespace evmjit { /// Virtual machine bytecode instruction. @@ -236,4 +234,3 @@ void skipPushData(code_iterator& _curr, code_iterator _end); } } -} diff --git a/evmjit/libevmjit/JIT.cpp b/evmjit/libevmjit/JIT.cpp index 8617fab6d..53c36dcb2 100644 --- a/evmjit/libevmjit/JIT.cpp +++ b/evmjit/libevmjit/JIT.cpp @@ -1,45 +1,251 @@ #include "evmjit/JIT.h" -#include +#include +#include + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include +#include +#include +#include +#include +#include "preprocessor/llvm_includes_end.h" + +#include "Compiler.h" +#include "Optimizer.h" +#include "Cache.h" +#include "ExecStats.h" +#include "Utils.h" +#include "BuildInfo.gen.h" namespace dev { namespace evmjit { +using namespace eth::jit; + namespace { +using ExecFunc = ReturnCode(*)(ExecutionContext*); -class JITImpl: JIT +std::string hash2str(i256 const& _hash) { -public: - std::unordered_map codeMap; + static const auto size = sizeof(_hash); + static const auto hexChars = "0123456789abcdef"; + std::string str; + str.resize(size * 2); + auto outIt = str.rbegin(); // reverse for BE + auto& arr = *(std::array*)&_hash; + for (auto b : arr) + { + *(outIt++) = hexChars[b & 0xf]; + *(outIt++) = hexChars[b >> 4]; + } + return str; +} +void printVersion() +{ + std::cout << "Ethereum EVM JIT Compiler (http://github.com/ethereum/evmjit):\n" + << " EVMJIT version " << EVMJIT_VERSION << "\n" +#ifdef NDEBUG + << " Optimized build, " EVMJIT_VERSION_FULL "\n" +#else + << " DEBUG build, " EVMJIT_VERSION_FULL "\n" +#endif + << " Built " << __DATE__ << " (" << __TIME__ << ")\n" + << std::endl; +} + +namespace cl = llvm::cl; +cl::opt g_optimize{"O", cl::desc{"Optimize"}}; +cl::opt g_cache{"cache", cl::desc{"Cache compiled EVM code on disk"}, + cl::values( + clEnumValN(CacheMode::on, "1", "Enabled"), + clEnumValN(CacheMode::off, "0", "Disabled"), + clEnumValN(CacheMode::read, "r", "Read only. No new objects are added to cache."), + clEnumValN(CacheMode::write, "w", "Write only. No objects are loaded from cache."), + clEnumValN(CacheMode::clear, "c", "Clear the cache storage. Cache is disabled."), + clEnumValN(CacheMode::preload, "p", "Preload all cached objects."), + clEnumValEnd)}; +cl::opt g_stats{"st", cl::desc{"Statistics"}}; +cl::opt g_dump{"dump", cl::desc{"Dump LLVM IR module"}}; + +void parseOptions() +{ + static llvm::llvm_shutdown_obj shutdownObj{}; + cl::AddExtraVersionPrinter(printVersion); + cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); +} + +class JITImpl +{ + std::unique_ptr m_engine; + mutable std::mutex x_codeMap; + std::unordered_map m_codeMap; + +public: static JITImpl& instance() { static JITImpl s_instance; return s_instance; } + + JITImpl(); + + llvm::ExecutionEngine& engine() { return *m_engine; } + + ExecFunc getExecFunc(h256 const& _codeHash) const; + void mapExecFunc(h256 _codeHash, ExecFunc _funcAddr); + + ExecFunc compile(byte const* _code, uint64_t _codeSize, h256 const& _codeHash); }; +JITImpl::JITImpl() +{ + parseOptions(); + + bool preloadCache = g_cache == CacheMode::preload; + if (preloadCache) + g_cache = CacheMode::on; + + llvm::InitializeNativeTarget(); + llvm::InitializeNativeTargetAsmPrinter(); + + auto module = std::unique_ptr(new llvm::Module({}, llvm::getGlobalContext())); + + // FIXME: LLVM 3.7: test on Windows + auto triple = llvm::Triple(llvm::sys::getProcessTriple()); + if (triple.getOS() == llvm::Triple::OSType::Win32) + triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format + module->setTargetTriple(triple.str()); + + llvm::EngineBuilder builder(std::move(module)); + builder.setEngineKind(llvm::EngineKind::JIT); + builder.setOptLevel(g_optimize ? llvm::CodeGenOpt::Default : llvm::CodeGenOpt::None); + + m_engine.reset(builder.create()); + + // TODO: Update cache listener + m_engine->setObjectCache(Cache::init(g_cache, nullptr)); + + // FIXME: Disabled during API changes + //if (preloadCache) + // Cache::preload(*m_engine, funcCache); +} + +ExecFunc JITImpl::getExecFunc(h256 const& _codeHash) const +{ + std::lock_guard lock{x_codeMap}; + auto it = m_codeMap.find(_codeHash); + if (it != m_codeMap.end()) + return it->second; + return nullptr; +} + +void JITImpl::mapExecFunc(h256 _codeHash, ExecFunc _funcAddr) +{ + std::lock_guard lock{x_codeMap}; + m_codeMap.emplace(std::move(_codeHash), _funcAddr); +} + +ExecFunc JITImpl::compile(byte const* _code, uint64_t _codeSize, h256 const& _codeHash) +{ + auto name = hash2str(_codeHash); + auto module = Cache::getObject(name); + if (!module) + { + // TODO: Listener support must be redesigned. These should be a feature of JITImpl + //listener->stateChanged(ExecState::Compilation); + assert(_code || !_codeSize); //TODO: Is it good idea to execute empty code? + module = Compiler{{}}.compile(_code, _code + _codeSize, name); + + if (g_optimize) + { + //listener->stateChanged(ExecState::Optimization); + optimize(*module); + } + + prepare(*module); + } + if (g_dump) + module->dump(); + + m_engine->addModule(std::move(module)); + //listener->stateChanged(ExecState::CodeGen); + return (ExecFunc)m_engine->getFunctionAddress(name); +} + } // anonymous namespace -bool JIT::isCodeReady(h256 _codeHash) +bool JIT::isCodeReady(h256 const& _codeHash) { - return JITImpl::instance().codeMap.count(_codeHash) != 0; + return JITImpl::instance().getExecFunc(_codeHash) != nullptr; } -uint64_t JIT::getCode(h256 _codeHash) +void JIT::compile(byte const* _code, uint64_t _codeSize, h256 const& _codeHash) { - auto& codeMap = JITImpl::instance().codeMap; - auto it = codeMap.find(_codeHash); - if (it != codeMap.end()) - return it->second; - return 0; + auto& jit = JITImpl::instance(); + auto execFunc = jit.compile(_code, _codeSize, _codeHash); + if (execFunc) // FIXME: What with error? + jit.mapExecFunc(_codeHash, execFunc); } -void JIT::mapCode(h256 _codeHash, uint64_t _funcAddr) +ReturnCode JIT::exec(ExecutionContext& _context) { - JITImpl::instance().codeMap.insert(std::make_pair(_codeHash, _funcAddr)); + //std::unique_ptr listener{new ExecStats}; + //listener->stateChanged(ExecState::Started); + //static StatsCollector statsCollector; + + auto& jit = JITImpl::instance(); + auto codeHash = _context.codeHash(); + auto execFunc = jit.getExecFunc(codeHash); + if (!execFunc) + { + execFunc = jit.compile(_context.code(), _context.codeSize(), codeHash); + if (!execFunc) + return ReturnCode::LLVMError; + jit.mapExecFunc(codeHash, execFunc); + } + + //listener->stateChanged(ExecState::Execution); + auto returnCode = execFunc(&_context); + //listener->stateChanged(ExecState::Return); + + if (returnCode == ReturnCode::Return) + _context.returnData = _context.getReturnData(); // Save reference to return data + + //listener->stateChanged(ExecState::Finished); + // if (g_stats) + // statsCollector.stats.push_back(std::move(listener)); + + return returnCode; +} + + +extern "C" void ext_free(void* _data) noexcept; + +ExecutionContext::~ExecutionContext() +{ + if (m_memData) + ext_free(m_memData); // Use helper free to check memory leaks +} + +bytes_ref ExecutionContext::getReturnData() const +{ + auto data = m_data->callData; + auto size = static_cast(m_data->callDataSize); + + if (data < m_memData || data >= m_memData + m_memSize || size == 0) + { + assert(size == 0); // data can be an invalid pointer only if size is 0 + m_data->callData = nullptr; + return {}; + } + + return bytes_ref{data, size}; } } diff --git a/evmjit/libevmjit/Memory.cpp b/evmjit/libevmjit/Memory.cpp index 79a82a8ae..fdf5a6b98 100644 --- a/evmjit/libevmjit/Memory.cpp +++ b/evmjit/libevmjit/Memory.cpp @@ -5,7 +5,6 @@ #include "preprocessor/llvm_includes_end.h" #include "Type.h" -#include "Runtime.h" #include "GasMeter.h" #include "Endianness.h" #include "RuntimeManager.h" @@ -191,8 +190,7 @@ llvm::Value* Memory::getSize() llvm::Value* Memory::getBytePtr(llvm::Value* _index) { - auto idx = m_builder.CreateTrunc(_index, Type::Size, "idx"); // Never allow memory index be a type bigger than i64 - return m_builder.CreateGEP(getData(), idx, "ptr"); + return m_builder.CreateGEP(getData(), _index, "ptr"); } void Memory::require(llvm::Value* _offset, llvm::Value* _size) @@ -235,7 +233,7 @@ void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* auto bytesToZero = m_builder.CreateNUWSub(reqBytes, bytesToCopy, "bytesToZero"); auto src = m_builder.CreateGEP(_srcPtr, idx64, "src"); - auto dstIdx = m_builder.CreateTrunc(_destMemIdx, Type::Size, "dstIdx"); // Never allow memory index be a type bigger than i64 + auto dstIdx = m_builder.CreateTrunc(_destMemIdx, Type::Size, "dstIdx"); auto padIdx = m_builder.CreateNUWAdd(dstIdx, bytesToCopy, "padIdx"); auto dst = m_memory.getPtr(getRuntimeManager().getMem(), dstIdx); auto pad = m_memory.getPtr(getRuntimeManager().getMem(), padIdx); diff --git a/evmjit/libevmjit/Optimizer.cpp b/evmjit/libevmjit/Optimizer.cpp index df88b4df8..dea3ea2a0 100644 --- a/evmjit/libevmjit/Optimizer.cpp +++ b/evmjit/libevmjit/Optimizer.cpp @@ -1,11 +1,16 @@ #include "Optimizer.h" #include "preprocessor/llvm_includes_start.h" +#include +#include #include #include #include #include "preprocessor/llvm_includes_end.h" +#include "Arith256.h" +#include "Type.h" + namespace dev { namespace eth @@ -16,7 +21,7 @@ namespace jit bool optimize(llvm::Module& _module) { auto pm = llvm::legacy::PassManager{}; - //pm.add(llvm::createFunctionInliningPass(2, 2)); // Problem with APInt value bigger than 64bit + pm.add(llvm::createFunctionInliningPass(2, 2)); pm.add(llvm::createCFGSimplificationPass()); pm.add(llvm::createInstructionCombiningPass()); pm.add(llvm::createAggressiveDCEPass()); @@ -24,6 +29,96 @@ bool optimize(llvm::Module& _module) return pm.run(_module); } +namespace +{ + +class LowerEVMPass: public llvm::BasicBlockPass +{ + static char ID; + +public: + LowerEVMPass(): + llvm::BasicBlockPass(ID) + {} + + virtual bool runOnBasicBlock(llvm::BasicBlock& _bb) override; + + using llvm::BasicBlockPass::doFinalization; + virtual bool doFinalization(llvm::Module& _module) override; +}; + +char LowerEVMPass::ID = 0; + +bool LowerEVMPass::runOnBasicBlock(llvm::BasicBlock& _bb) +{ + auto modified = false; + auto module = _bb.getParent()->getParent(); + auto i512Ty = llvm::IntegerType::get(_bb.getContext(), 512); + for (auto it = _bb.begin(); it != _bb.end(); ) + { + auto& inst = *it++; + llvm::Function* func = nullptr; + if (inst.getType() == Type::Word) + { + switch (inst.getOpcode()) + { + case llvm::Instruction::Mul: + func = Arith256::getMulFunc(*module); + break; + + case llvm::Instruction::UDiv: + func = Arith256::getUDiv256Func(*module); + break; + + case llvm::Instruction::URem: + func = Arith256::getURem256Func(*module); + break; + + case llvm::Instruction::SDiv: + func = Arith256::getSDiv256Func(*module); + break; + + case llvm::Instruction::SRem: + func = Arith256::getSRem256Func(*module); + break; + } + } + else if (inst.getType() == i512Ty) + { + switch (inst.getOpcode()) + { + case llvm::Instruction::URem: + func = Arith256::getURem512Func(*module); + break; + } + } + + if (func) + { + auto call = llvm::CallInst::Create(func, {inst.getOperand(0), inst.getOperand(1)}, "", &inst); + inst.replaceAllUsesWith(call); + inst.eraseFromParent(); + modified = true; + } + } + return modified; +} + +bool LowerEVMPass::doFinalization(llvm::Module&) +{ + return false; +} + +} + +bool prepare(llvm::Module& _module) +{ + auto pm = llvm::legacy::PassManager{}; + pm.add(llvm::createDeadCodeEliminationPass()); + pm.add(new LowerEVMPass{}); + return pm.run(_module); +} + } } } diff --git a/evmjit/libevmjit/Optimizer.h b/evmjit/libevmjit/Optimizer.h index 4a3147a7f..4b7ab7e9a 100644 --- a/evmjit/libevmjit/Optimizer.h +++ b/evmjit/libevmjit/Optimizer.h @@ -14,6 +14,8 @@ namespace jit bool optimize(llvm::Module& _module); +bool prepare(llvm::Module& _module); + } } } diff --git a/evmjit/libevmjit/Runtime.cpp b/evmjit/libevmjit/Runtime.cpp deleted file mode 100644 index 7e9a7d52e..000000000 --- a/evmjit/libevmjit/Runtime.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "Runtime.h" - -#include - -namespace dev -{ -namespace eth -{ -namespace jit -{ - -void Runtime::init(RuntimeData* _data, Env* _env) -{ - m_data = _data; - m_env = _env; -} - -extern "C" void ext_free(void* _data) noexcept; - -Runtime::~Runtime() -{ - if (m_memData) - ext_free(m_memData); // Use helper free to check memory leaks -} - -bytes_ref Runtime::getReturnData() const -{ - auto data = m_data->callData; - auto size = static_cast(m_data->callDataSize); - - if (data < m_memData || data >= m_memData + m_memSize || size == 0) - { - assert(size == 0); // data can be an invalid pointer only if size is 0 - m_data->callData = nullptr; - return {}; - } - - return bytes_ref{data, size}; -} - -} -} -} diff --git a/evmjit/libevmjit/Runtime.h b/evmjit/libevmjit/Runtime.h deleted file mode 100644 index 895128a59..000000000 --- a/evmjit/libevmjit/Runtime.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "RuntimeData.h" - -namespace dev -{ -namespace eth -{ -namespace jit -{ - -class Runtime -{ -public: - void init(RuntimeData* _data, Env* _env); - EXPORT ~Runtime(); - - bytes_ref getReturnData() const; - -private: - RuntimeData* m_data = nullptr; ///< Pointer to data. Expected by compiled contract. - Env* m_env = nullptr; ///< Pointer to environment proxy. Expected by compiled contract. - byte* m_memData = nullptr; - uint64_t m_memSize = 0; - uint64_t m_memCap = 0; -}; - -} -} -} diff --git a/evmjit/libevmjit/RuntimeData.h b/evmjit/libevmjit/RuntimeData.h deleted file mode 100644 index 6a5cd0d14..000000000 --- a/evmjit/libevmjit/RuntimeData.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "evmjit/DataTypes.h" -#include "Common.h" - -namespace dev -{ -namespace eth -{ -namespace jit -{ -using evmjit::i256; -using evmjit::h256; - -struct RuntimeData -{ - enum Index - { - Gas, - GasPrice, - CallData, - CallDataSize, - Address, - Caller, - Origin, - CallValue, - CoinBase, - Difficulty, - GasLimit, - Number, - Timestamp, - Code, - CodeSize, - - SuicideDestAddress = Address, ///< Suicide balance destination address - ReturnData = CallData, ///< Return data pointer (set only in case of RETURN) - ReturnDataSize = CallDataSize, ///< Return data size (set only in case of RETURN) - }; - - int64_t gas = 0; - int64_t gasPrice = 0; - byte const* callData = nullptr; - uint64_t callDataSize = 0; - i256 address; - i256 caller; - i256 origin; - i256 callValue; - i256 coinBase; - i256 difficulty; - i256 gasLimit; - uint64_t number = 0; - int64_t timestamp = 0; - byte const* code = nullptr; - uint64_t codeSize = 0; - h256 codeHash; -}; - -/// VM Environment (ExtVM) opaque type -struct Env; - -} -} -} diff --git a/evmjit/libevmjit/RuntimeManager.cpp b/evmjit/libevmjit/RuntimeManager.cpp index 5c66a5a21..d48b64bb1 100644 --- a/evmjit/libevmjit/RuntimeManager.cpp +++ b/evmjit/libevmjit/RuntimeManager.cpp @@ -64,22 +64,22 @@ llvm::Twine getName(RuntimeData::Index _index) { switch (_index) { - default: return "data"; - case RuntimeData::Address: return "address"; - case RuntimeData::Caller: return "caller"; - case RuntimeData::Origin: return "origin"; - case RuntimeData::CallValue: return "callvalue"; - case RuntimeData::GasPrice: return "gasprice"; - case RuntimeData::CoinBase: return "coinbase"; - case RuntimeData::Difficulty: return "difficulty"; - case RuntimeData::GasLimit: return "gaslimit"; - case RuntimeData::CallData: return "callData"; - case RuntimeData::Code: return "code"; - case RuntimeData::CodeSize: return "code"; - case RuntimeData::CallDataSize: return "callDataSize"; - case RuntimeData::Gas: return "gas"; - case RuntimeData::Number: return "number"; - case RuntimeData::Timestamp: return "timestamp"; + default: return ""; + case RuntimeData::Gas: return "msg.gas"; + case RuntimeData::GasPrice: return "tx.gasprice"; + case RuntimeData::CallData: return "msg.data.ptr"; + case RuntimeData::CallDataSize: return "msg.data.size"; + case RuntimeData::Address: return "this.address"; + case RuntimeData::Caller: return "msg.caller"; + case RuntimeData::Origin: return "tx.origin"; + case RuntimeData::CallValue: return "msg.value"; + case RuntimeData::CoinBase: return "block.coinbase"; + case RuntimeData::Difficulty: return "block.difficulty"; + case RuntimeData::GasLimit: return "block.gaslimit"; + case RuntimeData::Number: return "block.number"; + case RuntimeData::Timestamp: return "block.timestamp"; + case RuntimeData::Code: return "code.ptr"; + case RuntimeData::CodeSize: return "code.size"; } } } @@ -93,10 +93,8 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB // Unpack data auto rtPtr = getRuntimePtr(); - m_dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 0), "data"); + m_dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 0), "dataPtr"); assert(m_dataPtr->getType() == Type::RuntimeDataPtr); - m_gasPtr = m_builder.CreateStructGEP(getRuntimeDataType(), m_dataPtr, 0, "gas"); - assert(m_gasPtr->getType() == Type::Gas->getPointerTo()); m_memPtr = m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 2, "mem"); assert(m_memPtr->getType() == Array::getType()->getPointerTo()); m_envPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 1), "env"); @@ -105,6 +103,13 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB m_stackSize = m_builder.CreateAlloca(Type::Size, nullptr, "stackSize"); m_builder.CreateStore(m_builder.getInt64(0), m_stackSize); + auto data = m_builder.CreateLoad(m_dataPtr, "data"); + for (unsigned i = 0; i < m_dataElts.size(); ++i) + m_dataElts[i] = m_builder.CreateExtractValue(data, i, getName(RuntimeData::Index(i))); + + m_gasPtr = m_builder.CreateAlloca(Type::Gas, nullptr, "gas.ptr"); + m_builder.CreateStore(m_dataElts[RuntimeData::Index::Gas], m_gasPtr); + llvm::Type* checkStackLimitArgs[] = {Type::Size->getPointerTo(), Type::Size, Type::Size, Type::BytePtr}; m_checkStackLimit = llvm::Function::Create(llvm::FunctionType::get(Type::Void, checkStackLimitArgs, false), llvm::Function::PrivateLinkage, "stack.checkSize", getModule()); m_checkStackLimit->setDoesNotThrow(); @@ -180,7 +185,7 @@ llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index) llvm::Value* RuntimeManager::get(RuntimeData::Index _index) { - return getBuilder().CreateLoad(getPtr(_index), getName(_index)); + return m_dataElts[_index]; } void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value) @@ -194,8 +199,7 @@ void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size { auto memPtr = m_builder.CreateBitCast(getMem(), Type::BytePtr->getPointerTo()); auto mem = getBuilder().CreateLoad(memPtr, "memory"); - auto idx = m_builder.CreateTrunc(_offset, Type::Size, "idx"); // Never allow memory index be a type bigger than i64 // TODO: Report bug & fix to LLVM - auto returnDataPtr = getBuilder().CreateGEP(mem, idx); + auto returnDataPtr = getBuilder().CreateGEP(mem, _offset); set(RuntimeData::ReturnData, returnDataPtr); auto size64 = getBuilder().CreateTrunc(_size, Type::Size); @@ -212,6 +216,8 @@ void RuntimeManager::exit(ReturnCode _returnCode) if (m_stack) m_stack->free(); + auto extGasPtr = m_builder.CreateStructGEP(getRuntimeDataType(), getDataPtr(), RuntimeData::Index::Gas, "msg.gas.ptr"); + m_builder.CreateStore(getGas(), extGasPtr); m_builder.CreateRet(Constant::get(_returnCode)); } @@ -265,9 +271,7 @@ llvm::Value* RuntimeManager::getCallDataSize() llvm::Value* RuntimeManager::getGas() { - auto gas = get(RuntimeData::Gas); - assert(gas->getType() == Type::Gas); - return gas; + return getBuilder().CreateLoad(getGasPtr(), "gas"); } llvm::Value* RuntimeManager::getGasPtr() @@ -285,7 +289,7 @@ llvm::Value* RuntimeManager::getMem() void RuntimeManager::setGas(llvm::Value* _gas) { assert(_gas->getType() == Type::Gas); - set(RuntimeData::Gas, _gas); + getBuilder().CreateStore(_gas, getGasPtr()); } } diff --git a/evmjit/libevmjit/RuntimeManager.h b/evmjit/libevmjit/RuntimeManager.h index c430a1098..8c0728aaf 100644 --- a/evmjit/libevmjit/RuntimeManager.h +++ b/evmjit/libevmjit/RuntimeManager.h @@ -1,8 +1,9 @@ #pragma once +#include + #include "CompilerHelper.h" #include "Type.h" -#include "RuntimeData.h" #include "Instruction.h" namespace dev @@ -11,6 +12,7 @@ namespace eth { namespace jit { +using namespace evmjit; class Stack; class RuntimeManager: public CompilerHelper @@ -61,6 +63,8 @@ private: llvm::Value* m_memPtr = nullptr; llvm::Value* m_envPtr = nullptr; + std::array m_dataElts; + llvm::Value* m_stackSize = nullptr; llvm::Function* m_checkStackLimit = nullptr; diff --git a/evmjit/libevmjit/Stack.cpp b/evmjit/libevmjit/Stack.cpp index 3a686c766..b7b8f25b1 100644 --- a/evmjit/libevmjit/Stack.cpp +++ b/evmjit/libevmjit/Stack.cpp @@ -5,7 +5,6 @@ #include "preprocessor/llvm_includes_end.h" #include "RuntimeManager.h" -#include "Runtime.h" #include "Utils.h" #include // DEBUG only @@ -23,96 +22,6 @@ Stack::Stack(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager): m_stack(_builder, "stack") {} -llvm::Function* Stack::getPushFunc() -{ - auto& func = m_push; - if (!func) - { - llvm::Type* argTypes[] = {Type::RuntimePtr, Type::Word}; - func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::ExternalLinkage, "stack.push", getModule()); - llvm::Type* extArgTypes[] = {Type::RuntimePtr, Type::WordPtr}; - auto extPushFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, extArgTypes, false), llvm::Function::ExternalLinkage, "stack_push", getModule()); - - auto rt = &func->getArgumentList().front(); - rt->setName("rt"); - auto value = rt->getNextNode(); - value->setName("value"); - - InsertPointGuard guard{m_builder}; - auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), {}, func); - m_builder.SetInsertPoint(entryBB); - auto a = m_builder.CreateAlloca(Type::Word); - m_builder.CreateStore(value, a); - createCall(extPushFunc, {rt, a}); - m_builder.CreateRetVoid(); - } - return func; -} - -llvm::Function* Stack::getSetFunc() -{ - auto& func = m_set; - if (!func) - { - llvm::Type* argTypes[] = {Type::RuntimePtr, Type::Size, Type::Word}; - func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::ExternalLinkage, "stack.set", getModule()); - llvm::Type* extArgTypes[] = {Type::RuntimePtr, Type::Size, Type::WordPtr}; - auto extSetFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, extArgTypes, false), llvm::Function::ExternalLinkage, "stack_set", getModule()); - - auto rt = &func->getArgumentList().front(); - rt->setName("rt"); - auto index = rt->getNextNode(); - index->setName("index"); - auto value = index->getNextNode(); - value->setName("value"); - - InsertPointGuard guard{m_builder}; - auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), {}, func); - m_builder.SetInsertPoint(entryBB); - auto a = m_builder.CreateAlloca(Type::Word); - m_builder.CreateStore(value, a); - createCall(extSetFunc, {rt, index, a}); - m_builder.CreateRetVoid(); - } - return func; -} - -llvm::Function* Stack::getPopFunc() -{ - auto& func = m_pop; - if (!func) - { - llvm::Type* argTypes[] = {Type::RuntimePtr, Type::Size, Type::BytePtr}; - func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::ExternalLinkage, "stack.pop", getModule()); - llvm::Type* extArgTypes[] = {Type::RuntimePtr, Type::Size}; - auto extPopFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Bool, extArgTypes, false), llvm::Function::ExternalLinkage, "stack_pop", getModule()); - - auto rt = &func->getArgumentList().front(); - rt->setName("rt"); - auto index = rt->getNextNode(); - index->setName("index"); - auto jmpBuf = index->getNextNode(); - jmpBuf->setName("jmpBuf"); - - InsertPointGuard guard{m_builder}; - auto entryBB = llvm::BasicBlock::Create(m_builder.getContext(), {}, func); - auto underflowBB = llvm::BasicBlock::Create(m_builder.getContext(), "Underflow", func); - auto returnBB = llvm::BasicBlock::Create(m_builder.getContext(), "Return", func); - - m_builder.SetInsertPoint(entryBB); - auto ok = createCall(extPopFunc, {rt, index}); - m_builder.CreateCondBr(ok, returnBB, underflowBB); //TODO: Add branch weight - - m_builder.SetInsertPoint(underflowBB); - m_runtimeManager.abort(jmpBuf); - m_builder.CreateUnreachable(); - - m_builder.SetInsertPoint(returnBB); - m_builder.CreateRetVoid(); - } - return func; -} - llvm::Function* Stack::getGetFunc() { auto& func = m_get; @@ -175,32 +84,3 @@ void Stack::push(llvm::Value* _value) } } } - -extern "C" -{ - using namespace dev::eth::jit; - - EXPORT void ext_calldataload(RuntimeData* _rtData, i256* _index, byte* o_value) - { - // It asumes all indexes are less than 2^64 - - auto index = _index->a; - if (_index->b || _index->c || _index->d) // if bigger that 2^64 - index = std::numeric_limits::max(); // set max to fill with 0 leter - - auto data = _rtData->callData; - auto size = _rtData->callDataSize; - for (auto i = 0; i < 32; ++i) - { - if (index < size) - { - o_value[i] = data[index]; - ++index; // increment only if in range - } - else - o_value[i] = 0; - } - } - -} // extern "C" - diff --git a/evmjit/libevmjit/Stack.h b/evmjit/libevmjit/Stack.h index 3c526f0d3..ad10dae12 100644 --- a/evmjit/libevmjit/Stack.h +++ b/evmjit/libevmjit/Stack.h @@ -24,18 +24,10 @@ public: void free() { m_stack.free(); } private: - llvm::Function* getPopFunc(); - llvm::Function* getPushFunc(); llvm::Function* getGetFunc(); - llvm::Function* getSetFunc(); RuntimeManager& m_runtimeManager; - - llvm::Function* m_pop = nullptr; - llvm::Function* m_push = nullptr; llvm::Function* m_get = nullptr; - llvm::Function* m_set = nullptr; - Array m_stack; }; diff --git a/evmjit/libevmjit/Type.cpp b/evmjit/libevmjit/Type.cpp index 00a143dea..6ac9a6467 100644 --- a/evmjit/libevmjit/Type.cpp +++ b/evmjit/libevmjit/Type.cpp @@ -13,7 +13,6 @@ namespace jit llvm::IntegerType* Type::Word; llvm::PointerType* Type::WordPtr; -llvm::IntegerType* Type::lowPrecision; llvm::IntegerType* Type::Bool; llvm::IntegerType* Type::Size; llvm::IntegerType* Type::Gas; @@ -34,8 +33,6 @@ void Type::init(llvm::LLVMContext& _context) { Word = llvm::Type::getIntNTy(_context, 256); WordPtr = Word->getPointerTo(); - lowPrecision = llvm::Type::getInt64Ty(_context); - // TODO: Size should be architecture-dependent Bool = llvm::Type::getInt1Ty(_context); Size = llvm::Type::getInt64Ty(_context); Gas = Size; diff --git a/evmjit/libevmjit/Type.h b/evmjit/libevmjit/Type.h index fcca98d74..5e5b9dde5 100644 --- a/evmjit/libevmjit/Type.h +++ b/evmjit/libevmjit/Type.h @@ -4,9 +4,9 @@ #include #include #include -#include "preprocessor/llvm_includes_end.h" // FIXME: LLVM 3.7: check if needed +#include "preprocessor/llvm_includes_end.h" -#include "Common.h" +#include "evmjit/JIT.h" // ReturnCode namespace dev { @@ -14,16 +14,13 @@ namespace eth { namespace jit { +using namespace evmjit; struct Type { static llvm::IntegerType* Word; static llvm::PointerType* WordPtr; - /// Type for doing low precision arithmetics where 256-bit precision is not supported by native target - /// @TODO: Use 64-bit for now. In 128-bit compiler-rt library functions are required - static llvm::IntegerType* lowPrecision; - static llvm::IntegerType* Bool; static llvm::IntegerType* Size; static llvm::IntegerType* Gas; diff --git a/evmjit/libevmjit/interface.cpp b/evmjit/libevmjit/interface.cpp index 01f743a2e..7136f6798 100644 --- a/evmjit/libevmjit/interface.cpp +++ b/evmjit/libevmjit/interface.cpp @@ -1,29 +1,28 @@ -#include "ExecutionEngine.h" +#include "evmjit/JIT.h" extern "C" { +using namespace dev::evmjit; -using namespace dev::eth::jit; - -EXPORT void* evmjit_create() noexcept +EXPORT void* evmjit_create(RuntimeData* _data, Env* _env) noexcept { - // TODO: Make sure ExecutionEngine constructor does not throw - return new(std::nothrow) ExecutionEngine; + if (!_data) + return nullptr; + + // TODO: Make sure ExecutionEngine constructor does not throw + make JIT/ExecutionEngine interface all nothrow + return new(std::nothrow) ExecutionContext{*_data, _env}; } -EXPORT void evmjit_destroy(ExecutionEngine* _engine) noexcept +EXPORT void evmjit_destroy(ExecutionContext* _context) noexcept { - delete _engine; + delete _context; } -EXPORT int evmjit_run(ExecutionEngine* _engine, RuntimeData* _data, Env* _env) noexcept +EXPORT int evmjit_run(ExecutionContext* _context) noexcept { - if (!_engine || !_data) - return static_cast(ReturnCode::UnexpectedException); - try { - auto returnCode = _engine->run(_data, _env); + auto returnCode = JIT::exec(*_context); return static_cast(returnCode); } catch(...) diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index 823425598..e6360317f 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -6,6 +6,9 @@ aux_source_directory(. SRC_LIST) include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(BEFORE ..) include_directories(${DB_INCLUDE_DIRS}) +if (ETHASHCL) + include_directories(${OpenCL_INCLUDE_DIRS}) +endif () set(EXECUTABLE exp) @@ -27,11 +30,6 @@ target_link_libraries(${EXECUTABLE} p2p) if (ETHASHCL) target_link_libraries(${EXECUTABLE} ethash-cl) target_link_libraries(${EXECUTABLE} ethash) - target_link_libraries(${EXECUTABLE} OpenCL) + target_link_libraries(${EXECUTABLE} ${OpenCL_LIBRARIES}) endif() -install( TARGETS ${EXECUTABLE} DESTINATION bin) - - - - - +install( TARGETS ${EXECUTABLE} DESTINATION bin) diff --git a/exp/main.cpp b/exp/main.cpp index 1db9b4267..88608f8cf 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -135,7 +135,7 @@ int main() DownloadSub s0(man); DownloadSub s1(man); DownloadSub s2(man); - man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)})); + man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}), 0); assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8})); assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6})); assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4})); diff --git a/extdep/getstuff.bat b/extdep/getstuff.bat index 3b41f9e96..3c0b42f95 100644 --- a/extdep/getstuff.bat +++ b/extdep/getstuff.bat @@ -14,6 +14,7 @@ call :download leveldb 1.2 call :download microhttpd 0.9.2 call :download qt 5.4.1 call :download miniupnpc 1.9 +call :download v8 3.15.9 goto :EOF diff --git a/libdevcore/Base64.cpp b/libdevcore/Base64.cpp index f97c82156..8ee2b29f7 100644 --- a/libdevcore/Base64.cpp +++ b/libdevcore/Base64.cpp @@ -27,6 +27,8 @@ /// Originally by René Nyffenegger, modified by some other guy and then devified by Gav Wood. #include "Base64.h" + +using namespace std; using namespace dev; static inline bool is_base64(byte c) @@ -44,14 +46,14 @@ static inline byte find_base64_char_index(byte c) else return 1 + find_base64_char_index('/'); } -std::string dev::toBase64(bytesConstRef _in) +string dev::toBase64(bytesConstRef _in) { static const char base64_chars[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; - std::string ret; + string ret; int i = 0; int j = 0; byte char_array_3[3]; @@ -60,15 +62,17 @@ std::string dev::toBase64(bytesConstRef _in) auto buf = _in.data(); auto bufLen = _in.size(); - while (bufLen--) { + while (bufLen--) + { char_array_3[i++] = *(buf++); - if (i == 3) { + if (i == 3) + { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; - for(i = 0; (i <4) ; i++) + for (i = 0; i < 4; i++) ret += base64_chars[char_array_4[i]]; i = 0; } @@ -76,7 +80,7 @@ std::string dev::toBase64(bytesConstRef _in) if (i) { - for(j = i; j < 3; j++) + for (j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; @@ -84,28 +88,31 @@ std::string dev::toBase64(bytesConstRef _in) char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); char_array_4[3] = char_array_3[2] & 0x3f; - for (j = 0; (j < i + 1); j++) + for (j = 0; j < i + 1; j++) ret += base64_chars[char_array_4[j]]; - while((i++ < 3)) + while (i++ < 3) ret += '='; } return ret; } -bytes dev::fromBase64(std::string const& encoded_string) +bytes dev::fromBase64(string const& encoded_string) { auto in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; - byte char_array_4[4], char_array_3[3]; + byte char_array_3[3]; + byte char_array_4[4]; bytes ret; - while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { + while (in_len-- && encoded_string[in_] != '=' && is_base64(encoded_string[in_])) + { char_array_4[i++] = encoded_string[in_]; in_++; - if (i == 4) { + if (i == 4) + { for (i = 0; i < 4; i++) char_array_4[i] = find_base64_char_index(char_array_4[i]); @@ -119,7 +126,8 @@ bytes dev::fromBase64(std::string const& encoded_string) } } - if (i) { + if (i) + { for (j = i; j < 4; j++) char_array_4[j] = 0; @@ -130,7 +138,8 @@ bytes dev::fromBase64(std::string const& encoded_string) char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; - for (j = 0; (j < i - 1); j++) ret.push_back(char_array_3[j]); + for (j = 0; j < i - 1; j++) + ret.push_back(char_array_3[j]); } return ret; diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index e33936102..6ba933556 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -28,14 +28,17 @@ using namespace dev; namespace dev { -char const* Version = "0.9.27"; +char const* Version = "0.9.29"; const u256 UndefinedU256 = ~(u256)0; -void HasInvariants::checkInvariants() const +void InvariantChecker::checkInvariants() const { - if (!invariants()) - BOOST_THROW_EXCEPTION(FailedInvariant()); + if (!m_this->invariants()) + { + cwarn << "Invariant failed in" << m_function << "at" << m_file << ":" << m_line; + ::boost::exception_detail::throw_exception_(FailedInvariant(), m_function, m_file, m_line); + } } struct TimerChannel: public LogChannel { static const char* name(); static const int verbosity = 0; }; diff --git a/libdevcore/Common.h b/libdevcore/Common.h index f1d35bbc7..303512e57 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -41,6 +41,7 @@ #include #include #include +#include #include #pragma warning(push) #pragma GCC diagnostic push @@ -63,6 +64,8 @@ using byte = uint8_t; #define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} +#define DEV_IF_NO_ELSE(X) if(!(X)){}else + namespace dev { @@ -163,10 +166,6 @@ private: class HasInvariants { public: - /// Check invariants are met, throw if not. - void checkInvariants() const; - -protected: /// Reimplement to specify the invariants. virtual bool invariants() const = 0; }; @@ -175,16 +174,22 @@ protected: class InvariantChecker { public: - InvariantChecker(HasInvariants* _this): m_this(_this) { m_this->checkInvariants(); } - ~InvariantChecker() { m_this->checkInvariants(); } + InvariantChecker(HasInvariants* _this, char const* _fn, char const* _file, int _line): m_this(_this), m_function(_fn), m_file(_file), m_line(_line) { checkInvariants(); } + ~InvariantChecker() { checkInvariants(); } private: + /// Check invariants are met, throw if not. + void checkInvariants() const; + HasInvariants const* m_this; + char const* m_function; + char const* m_file; + int m_line; }; /// Scope guard for invariant check in a class derived from HasInvariants. #if ETH_DEBUG -#define DEV_INVARIANT_CHECK { ::dev::InvariantChecker __dev_invariantCheck(this); } +#define DEV_INVARIANT_CHECK ::dev::InvariantChecker __dev_invariantCheck(this, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__) #else #define DEV_INVARIANT_CHECK (void)0; #endif @@ -235,6 +240,7 @@ enum class WithExisting: int { Trust = 0, Verify, + Rescue, Kill }; diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index ed09e60ee..0faba8e8e 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -50,8 +50,8 @@ enum class HexPrefix /// Convert a series of bytes to the corresponding string of hex duplets. /// @param _w specifies the width of the first of the elements. Defaults to two - enough to represent a byte. /// @example toHex("A\x69") == "4169" -template -std::string toHex(_T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd) +template +std::string toHex(T const& _data, int _w = 2, HexPrefix _prefix = HexPrefix::DontAdd) { std::ostringstream ret; unsigned ii = 0; @@ -99,27 +99,27 @@ bytes asNibbles(bytesConstRef const& _s); /// Converts a templated integer value to the big-endian byte-stream represented on a templated collection. /// The size of the collection object will be unchanged. If it is too small, it will not represent the /// value properly, if too big then the additional elements will be zeroed out. -/// @a _Out will typically be either std::string or bytes. -/// @a _T will typically by unsigned, u160, u256 or bigint. -template -inline void toBigEndian(_T _val, _Out& o_out) +/// @a Out will typically be either std::string or bytes. +/// @a T will typically by unsigned, u160, u256 or bigint. +template +inline void toBigEndian(T _val, Out& o_out) { for (auto i = o_out.size(); i != 0; _val >>= 8, i--) { - _T v = _val & (_T)0xff; - o_out[i - 1] = (typename _Out::value_type)(uint8_t)v; + T v = _val & (T)0xff; + o_out[i - 1] = (typename Out::value_type)(uint8_t)v; } } /// Converts a big-endian byte-stream represented on a templated collection to a templated integer value. /// @a _In will typically be either std::string or bytes. -/// @a _T will typically by unsigned, u160, u256 or bigint. -template -inline _T fromBigEndian(_In const& _bytes) +/// @a T will typically by unsigned, u160, u256 or bigint. +template +inline T fromBigEndian(_In const& _bytes) { - _T ret = (_T)0; + T ret = (T)0; for (auto i: _bytes) - ret = (_T)((ret << 8) | (byte)(typename std::make_unsigned::type)i); + ret = (T)((ret << 8) | (byte)(typename std::make_unsigned::type)i); return ret; } @@ -131,11 +131,11 @@ inline bytes toBigEndian(u160 _val) { bytes ret(20); toBigEndian(_val, ret); ret /// Convenience function for toBigEndian. /// @returns a byte array just big enough to represent @a _val. -template -inline bytes toCompactBigEndian(_T _val, unsigned _min = 0) +template +inline bytes toCompactBigEndian(T _val, unsigned _min = 0) { int i = 0; - for (_T v = _val; v; ++i, v >>= 8) {} + for (T v = _val; v; ++i, v >>= 8) {} bytes ret(std::max(_min, i), 0); toBigEndian(_val, ret); return ret; @@ -147,11 +147,11 @@ inline bytes toCompactBigEndian(byte _val, unsigned _min = 0) /// Convenience function for toBigEndian. /// @returns a string just big enough to represent @a _val. -template -inline std::string toCompactBigEndianString(_T _val, unsigned _min = 0) +template +inline std::string toCompactBigEndianString(T _val, unsigned _min = 0) { int i = 0; - for (_T v = _val; v; ++i, v >>= 8) {} + for (T v = _val; v; ++i, v >>= 8) {} std::string ret(std::max(_min, i), '\0'); toBigEndian(_val, ret); return ret; @@ -179,8 +179,8 @@ std::string escaped(std::string const& _s, bool _all = true); /// Determines the length of the common prefix of the two collections given. /// @returns the number of elements both @a _t and @a _u share, in order, at the beginning. /// @example commonPrefix("Hello world!", "Hello, world!") == 5 -template -unsigned commonPrefix(_T const& _t, _U const& _u) +template +unsigned commonPrefix(T const& _t, _U const& _u) { unsigned s = std::min(_t.size(), _u.size()); for (unsigned i = 0;; ++i) @@ -196,8 +196,8 @@ std::string randomWord(); // General datatype convenience functions. /// Determine bytes required to encode the given integer value. @returns 0 if @a _i is zero. -template -inline unsigned bytesRequired(_T _i) +template +inline unsigned bytesRequired(T _i) { unsigned i = 0; for (; _i != 0; ++i, _i >>= 8) {} @@ -206,39 +206,39 @@ inline unsigned bytesRequired(_T _i) /// Trims a given number of elements from the front of a collection. /// Only works for POD element types. -template -void trimFront(_T& _t, unsigned _elements) +template +void trimFront(T& _t, unsigned _elements) { - static_assert(std::is_pod::value, ""); + static_assert(std::is_pod::value, ""); memmove(_t.data(), _t.data() + _elements, (_t.size() - _elements) * sizeof(_t[0])); _t.resize(_t.size() - _elements); } /// Pushes an element on to the front of a collection. /// Only works for POD element types. -template -void pushFront(_T& _t, _U _e) +template +void pushFront(T& _t, _U _e) { - static_assert(std::is_pod::value, ""); + static_assert(std::is_pod::value, ""); _t.push_back(_e); memmove(_t.data() + 1, _t.data(), (_t.size() - 1) * sizeof(_e)); _t[0] = _e; } /// Concatenate two vectors of elements of POD types. -template -inline std::vector<_T>& operator+=(std::vector::value, _T>::type>& _a, std::vector<_T> const& _b) +template +inline std::vector& operator+=(std::vector::value, T>::type>& _a, std::vector const& _b) { auto s = _a.size(); _a.resize(_a.size() + _b.size()); - memcpy(_a.data() + s, _b.data(), _b.size() * sizeof(_T)); + memcpy(_a.data() + s, _b.data(), _b.size() * sizeof(T)); return _a; } /// Concatenate two vectors of elements. -template -inline std::vector<_T>& operator+=(std::vector::value, _T>::type>& _a, std::vector<_T> const& _b) +template +inline std::vector& operator+=(std::vector::value, T>::type>& _a, std::vector const& _b) { _a.reserve(_a.size() + _b.size()); for (auto& i: _b) @@ -289,16 +289,16 @@ template std::vector operator+(std::vector _a, U const& } /// Concatenate two vectors of elements. -template -inline std::vector<_T> operator+(std::vector<_T> const& _a, std::vector<_T> const& _b) +template +inline std::vector operator+(std::vector const& _a, std::vector const& _b) { - std::vector<_T> ret(_a); + std::vector ret(_a); return ret += _b; } /// Merge two sets of elements. -template -inline std::set<_T>& operator+=(std::set<_T>& _a, std::set<_T> const& _b) +template +inline std::set& operator+=(std::set& _a, std::set const& _b) { for (auto& i: _b) _a.insert(i); @@ -306,13 +306,28 @@ inline std::set<_T>& operator+=(std::set<_T>& _a, std::set<_T> const& _b) } /// Merge two sets of elements. -template -inline std::set<_T> operator+(std::set<_T> const& _a, std::set<_T> const& _b) +template +inline std::set operator+(std::set const& _a, std::set const& _b) { - std::set<_T> ret(_a); + std::set ret(_a); return ret += _b; } +template +std::unordered_map& operator+=(std::unordered_map& _x, std::unordered_map const& _y) +{ + for (auto const& i: _y) + _x.insert(i); + return _x; +} + +template +std::unordered_map operator+(std::unordered_map const& _x, std::unordered_map const& _y) +{ + std::unordered_map ret(_x); + return ret += _y; +} + /// Make normal string from fixed-length string. std::string toString(string32 const& _s); diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index c7c551c2b..3127b349a 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -24,6 +24,7 @@ #pragma once #include +#include #include #include #include "CommonData.h" @@ -31,6 +32,10 @@ namespace dev { +/// Compile-time calculation of Log2 of constant values. +template struct StaticLog2 { enum { result = 1 + StaticLog2::result }; }; +template <> struct StaticLog2<1> { enum { result = 0 }; }; + extern std::random_device s_fixedHashEngine; /// Fixed-size raw-byte array container type, with an API optimised for storing hashes. @@ -77,7 +82,7 @@ public: explicit FixedHash(byte const* _bs, ConstructFromPointerType) { memcpy(m_data.data(), _bs, N); } /// Explicitly construct, copying from a string. - explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s) : dev::asBytes(_s), _ht) {} + explicit FixedHash(std::string const& _s, ConstructFromStringType _t = FromHex, ConstructFromHashType _ht = FailIfDifferent): FixedHash(_t == FromHex ? fromHex(_s, WhenError::Throw) : dev::asBytes(_s), _ht) {} /// Convert to arithmetic type. operator Arith() const { return fromBigEndian(m_data); } @@ -102,7 +107,10 @@ public: FixedHash operator&(FixedHash const& _c) const { return FixedHash(*this) &= _c; } FixedHash operator~() const { FixedHash ret; for (unsigned i = 0; i < N; ++i) ret[i] = ~m_data[i]; return ret; } - /// @returns true if all bytes in @a _c are set in this object. + // Big-endian increment. + FixedHash& operator++() { for (unsigned i = size; i > 0 && !++m_data[--i]; ) {} return *this; } + + /// @returns true if all one-bits in @a _c are set in this object. bool contains(FixedHash const& _c) const { return (*this & _c) == _c; } /// @returns a particular byte from the hash. @@ -146,7 +154,7 @@ public: { FixedHash ret; for (auto& i: ret.m_data) - i = std::uniform_int_distribution(0, 255)(_eng); + i = (uint8_t)std::uniform_int_distribution(0, 255)(_eng); return ret; } @@ -171,18 +179,21 @@ public: template inline FixedHash bloomPart() const { - static_assert((M & (M - 1)) == 0, "M must be power-of-two"); - static const unsigned c_bloomBits = M * 8; - unsigned mask = c_bloomBits - 1; - unsigned bloomBytes = (dev::toLog2(c_bloomBits) + 7) / 8; + unsigned const c_bloomBits = M * 8; + unsigned const c_mask = c_bloomBits - 1; + unsigned const c_bloomBytes = (StaticLog2::result + 7) / 8; + + static_assert((M & (M - 1)) == 0, "M must be power-of-two"); + static_assert(P * c_bloomBytes <= N, "out of range"); + FixedHash ret; byte const* p = data(); for (unsigned i = 0; i < P; ++i) { unsigned index = 0; - for (unsigned j = 0; j < bloomBytes; ++j, ++p) + for (unsigned j = 0; j < c_bloomBytes; ++j, ++p) index = (index << 8) | *p; - index &= mask; + index &= c_mask; ret[M - 1 - index / 8] |= (1 << (index % 8)); } return ret; diff --git a/libdevcore/Guards.h b/libdevcore/Guards.h index 2d3eced32..44d5969e4 100644 --- a/libdevcore/Guards.h +++ b/libdevcore/Guards.h @@ -95,7 +95,7 @@ using SpinGuard = std::lock_guard; * Mutex m; * int d; * ... - * ETH_(m) + * ETH_GUARDED(m) * { * for (auto d = 50; d > 25; --d) * foo(d); diff --git a/libdevcore/RLP.cpp b/libdevcore/RLP.cpp index 330893c76..7e419e42b 100644 --- a/libdevcore/RLP.cpp +++ b/libdevcore/RLP.cpp @@ -49,12 +49,12 @@ RLP::iterator& RLP::iterator::operator++() { if (m_remaining) { - m_lastItem.retarget(m_lastItem.next().data(), m_remaining); - m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem, ThrowOnFail | FailIfTooSmall).actualSize()); - m_remaining -= std::min(m_remaining, m_lastItem.size()); + m_currentItem.retarget(m_currentItem.next().data(), m_remaining); + m_currentItem = m_currentItem.cropped(0, sizeAsEncoded(m_currentItem)); + m_remaining -= std::min(m_remaining, m_currentItem.size()); } else - m_lastItem.retarget(m_lastItem.next().data(), 0); + m_currentItem.retarget(m_currentItem.next().data(), 0); return *this; } @@ -63,28 +63,28 @@ RLP::iterator::iterator(RLP const& _parent, bool _begin) if (_begin && _parent.isList()) { auto pl = _parent.payload(); - m_lastItem = pl.cropped(0, RLP(pl, ThrowOnFail | FailIfTooSmall).actualSize()); - m_remaining = pl.size() - m_lastItem.size(); + m_currentItem = pl.cropped(0, sizeAsEncoded(pl)); + m_remaining = pl.size() - m_currentItem.size(); } else { - m_lastItem = _parent.data().cropped(_parent.data().size()); + m_currentItem = _parent.data().cropped(_parent.data().size()); m_remaining = 0; } } -RLP RLP::operator[](unsigned _i) const +RLP RLP::operator[](size_t _i) const { if (_i < m_lastIndex) { - m_lastEnd = RLP(payload(), ThrowOnFail | FailIfTooSmall).actualSize(); + m_lastEnd = sizeAsEncoded(payload()); m_lastItem = payload().cropped(0, m_lastEnd); m_lastIndex = 0; } for (; m_lastIndex < _i && m_lastItem.size(); ++m_lastIndex) { m_lastItem = payload().cropped(m_lastEnd); - m_lastItem = m_lastItem.cropped(0, RLP(m_lastItem, ThrowOnFail | FailIfTooSmall).actualSize()); + m_lastItem = m_lastItem.cropped(0, sizeAsEncoded(m_lastItem)); m_lastEnd += m_lastItem.size(); } return RLP(m_lastItem, ThrowOnFail | FailIfTooSmall); @@ -100,7 +100,7 @@ RLPs RLP::toList() const return ret; } -unsigned RLP::actualSize() const +size_t RLP::actualSize() const { if (isNull()) return 0; @@ -142,7 +142,7 @@ bool RLP::isInt() const } else if (n < c_rlpListStart) { - if ((int)m_data.size() <= 1 + n - c_rlpDataIndLenZero) + if (m_data.size() <= size_t(1 + n - c_rlpDataIndLenZero)) BOOST_THROW_EXCEPTION(BadRLP()); return m_data[1 + n - c_rlpDataIndLenZero] != 0; } @@ -151,63 +151,75 @@ bool RLP::isInt() const return false; } -unsigned RLP::length() const +size_t RLP::length() const { if (isNull()) return 0; requireGood(); - unsigned ret = 0; - byte n = m_data[0]; + size_t ret = 0; + byte const n = m_data[0]; if (n < c_rlpDataImmLenStart) return 1; else if (n <= c_rlpDataIndLenZero) return n - c_rlpDataImmLenStart; else if (n < c_rlpListStart) { - if ((int)m_data.size() <= n - c_rlpDataIndLenZero) + if (m_data.size() <= size_t(n - c_rlpDataIndLenZero)) BOOST_THROW_EXCEPTION(BadRLP()); - if ((int)m_data.size() > 1) + if (m_data.size() > 1) if (m_data[1] == 0) BOOST_THROW_EXCEPTION(BadRLP()); - for (int i = 0; i < n - c_rlpDataIndLenZero; ++i) + unsigned lengthSize = n - c_rlpDataIndLenZero; + if (lengthSize > sizeof(ret)) + // We did not check, but would most probably not fit in our memory. + BOOST_THROW_EXCEPTION(UndersizeRLP()); + for (unsigned i = 0; i < lengthSize; ++i) ret = (ret << 8) | m_data[i + 1]; } else if (n <= c_rlpListIndLenZero) return n - c_rlpListStart; else { - if ((int)m_data.size() <= n - c_rlpListIndLenZero) + unsigned lengthSize = n - c_rlpListIndLenZero; + if (m_data.size() <= lengthSize) BOOST_THROW_EXCEPTION(BadRLP()); - if ((int)m_data.size() > 1) + if (m_data.size() > 1) if (m_data[1] == 0) BOOST_THROW_EXCEPTION(BadRLP()); - for (int i = 0; i < n - c_rlpListIndLenZero; ++i) + if (lengthSize > sizeof(ret)) + // We did not check, but would most probably not fit in our memory. + BOOST_THROW_EXCEPTION(UndersizeRLP()); + for (unsigned i = 0; i < lengthSize; ++i) ret = (ret << 8) | m_data[i + 1]; } + // We have to be able to add payloadOffset to length without overflow. + // This rejects roughly 4GB-sized RLPs on some platforms. + if (ret >= std::numeric_limits::max() - 0x100) + BOOST_THROW_EXCEPTION(UndersizeRLP()); return ret; } -unsigned RLP::items() const +size_t RLP::items() const { if (isList()) { bytesConstRef d = payload().cropped(0, length()); - unsigned i = 0; + size_t i = 0; for (; d.size(); ++i) - d = d.cropped(RLP(d, ThrowOnFail | FailIfTooSmall).actualSize()); + d = d.cropped(sizeAsEncoded(d)); return i; } return 0; } -RLPStream& RLPStream::appendRaw(bytesConstRef _s, unsigned _itemCount) +RLPStream& RLPStream::appendRaw(bytesConstRef _s, size_t _itemCount) { m_out.insert(m_out.end(), _s.begin(), _s.end()); noteAppended(_itemCount); return *this; } -void RLPStream::noteAppended(unsigned _itemCount) +void RLPStream::noteAppended(size_t _itemCount) { if (!_itemCount) return; @@ -223,7 +235,7 @@ void RLPStream::noteAppended(unsigned _itemCount) { auto p = m_listStack.back().second; m_listStack.pop_back(); - unsigned s = m_out.size() - p; // list size + size_t s = m_out.size() - p; // list size auto brs = bytesRequired(s); unsigned encodeSize = s < c_rlpListImmLenCount ? 1 : (1 + brs); // cdebug << "s: " << s << ", p: " << p << ", m_out.size(): " << m_out.size() << ", encodeSize: " << encodeSize << " (br: " << brs << ")"; @@ -232,19 +244,21 @@ void RLPStream::noteAppended(unsigned _itemCount) memmove(m_out.data() + p + encodeSize, m_out.data() + p, os - p); if (s < c_rlpListImmLenCount) m_out[p] = (byte)(c_rlpListStart + s); - else + else if (c_rlpListIndLenZero + brs <= 0xff) { m_out[p] = (byte)(c_rlpListIndLenZero + brs); byte* b = &(m_out[p + brs]); for (; s; s >>= 8) *(b--) = (byte)s; } + else + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("itemCount too large for RLP")); } _itemCount = 1; // for all following iterations, we've effectively appended a single item only since we completed a list. } } -RLPStream& RLPStream::appendList(unsigned _items) +RLPStream& RLPStream::appendList(size_t _items) { // cdebug << "appendList(" << _items << ")"; if (_items) @@ -266,10 +280,10 @@ RLPStream& RLPStream::appendList(bytesConstRef _rlp) RLPStream& RLPStream::append(bytesConstRef _s, bool _compact) { - unsigned s = _s.size(); + size_t s = _s.size(); byte const* d = _s.data(); if (_compact) - for (unsigned i = 0; i < _s.size() && !*d; ++i, --s, ++d) {} + for (size_t i = 0; i < _s.size() && !*d; ++i, --s, ++d) {} if (s == 1 && *d < c_rlpDataImmLenStart) m_out.push_back(*d); @@ -299,6 +313,8 @@ RLPStream& RLPStream::append(bigint _i) else { auto brbr = bytesRequired(br); + if (c_rlpDataIndLenZero + brbr > 0xff) + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("Number too large for RLP")); m_out.push_back((byte)(c_rlpDataIndLenZero + brbr)); pushInt(br, brbr); } @@ -308,9 +324,11 @@ RLPStream& RLPStream::append(bigint _i) return *this; } -void RLPStream::pushCount(unsigned _count, byte _base) +void RLPStream::pushCount(size_t _count, byte _base) { auto br = bytesRequired(_count); + if (int(br) + _base > 0xff) + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("Count too large for RLP")); m_out.push_back((byte)(br + _base)); // max 8 bytes. pushInt(_count, br); } @@ -320,7 +338,7 @@ std::ostream& dev::operator<<(std::ostream& _out, RLP const& _d) if (_d.isNull()) _out << "null"; else if (_d.isInt()) - _out << std::showbase << std::hex << std::nouppercase << _d.toInt(RLP::LaisezFaire) << dec; + _out << std::showbase << std::hex << std::nouppercase << _d.toInt(RLP::LaissezFaire) << dec; else if (_d.isData()) _out << escaped(_d.toString(), false); else if (_d.isList()) diff --git a/libdevcore/RLP.h b/libdevcore/RLP.h index dee438be4..0a4d1b88b 100644 --- a/libdevcore/RLP.h +++ b/libdevcore/RLP.h @@ -71,7 +71,7 @@ public: FailIfTooSmall = 16, Strict = ThrowOnFail | FailIfTooBig, VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall, - LaisezFaire = AllowNonCanon + LaissezFaire = AllowNonCanon }; using Strictness = int; @@ -113,12 +113,12 @@ public: bool isInt() const; /// @returns the number of items in the list, or zero if it isn't a list. - unsigned itemCount() const { return isList() ? items() : 0; } - unsigned itemCountStrict() const { if (!isList()) BOOST_THROW_EXCEPTION(BadCast()); return items(); } + size_t itemCount() const { return isList() ? items() : 0; } + size_t itemCountStrict() const { if (!isList()) BOOST_THROW_EXCEPTION(BadCast()); return items(); } /// @returns the number of bytes in the data, or zero if it isn't data. - unsigned size() const { return isData() ? length() : 0; } - unsigned sizeStrict() const { if (!isData()) BOOST_THROW_EXCEPTION(BadCast()); return length(); } + size_t size() const { return isData() ? length() : 0; } + size_t sizeStrict() const { if (!isData()) BOOST_THROW_EXCEPTION(BadCast()); return length(); } /// Equality operators; does best-effort conversion and checks for equality. bool operator==(char const* _s) const { return isData() && toString() == _s; } @@ -137,7 +137,7 @@ public: /// Subscript operator. /// @returns the list item @a _i if isList() and @a _i < listItems(), or RLP() otherwise. /// @note if used to access items in ascending order, this is efficient. - RLP operator[](unsigned _i) const; + RLP operator[](size_t _i) const; using element_type = RLP; @@ -152,16 +152,16 @@ public: iterator& operator++(); iterator operator++(int) { auto ret = *this; operator++(); return ret; } - RLP operator*() const { return RLP(m_lastItem); } - bool operator==(iterator const& _cmp) const { return m_lastItem == _cmp.m_lastItem; } + RLP operator*() const { return RLP(m_currentItem); } + bool operator==(iterator const& _cmp) const { return m_currentItem == _cmp.m_currentItem; } bool operator!=(iterator const& _cmp) const { return !operator==(_cmp); } private: iterator() {} iterator(RLP const& _parent, bool _begin); - unsigned m_remaining = 0; - bytesConstRef m_lastItem; + size_t m_remaining = 0; + bytesConstRef m_currentItem; }; /// @brief Iterator into beginning of sub-item list (valid only if we are a list). @@ -247,7 +247,7 @@ public: if (itemCount() != N || !isList()) BOOST_THROW_EXCEPTION(BadCast()); std::array ret; - for (unsigned i = 0; i < N; ++i) + for (size_t i = 0; i < N; ++i) { ret[i] = (T)operator[](i); } @@ -259,19 +259,21 @@ public: { requireGood(); if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull()) + { if (_flags & ThrowOnFail) BOOST_THROW_EXCEPTION(BadCast()); else return 0; - else {} + } auto p = payload(); if (p.size() > intTraits<_T>::maxSize && (_flags & FailIfTooBig)) + { if (_flags & ThrowOnFail) BOOST_THROW_EXCEPTION(BadCast()); else return 0; - else {} + } return fromBigEndian<_T>(p); } @@ -280,14 +282,15 @@ public: { requireGood(); if (!isData() || (length() > _N::size && (_flags & FailIfTooBig)) || (length() < _N::size && (_flags & FailIfTooSmall))) + { if (_flags & ThrowOnFail) BOOST_THROW_EXCEPTION(BadCast()); else return _N(); - else{} + } _N ret; - size_t s = std::min((size_t)_N::size, (size_t)length()); + size_t s = std::min(_N::size, length()); memcpy(ret.data() + _N::size - s, payload().data(), s); return ret; } @@ -298,9 +301,9 @@ public: /// @returns the data payload. Valid for all types. bytesConstRef payload() const { auto l = length(); if (l > m_data.size()) BOOST_THROW_EXCEPTION(BadRLP()); return m_data.cropped(payloadOffset(), l); } - /// @returns the theoretical size of this item. + /// @returns the theoretical size of this item as encoded in the data. /// @note Under normal circumstances, is equivalent to m_data.size() - use that unless you know it won't work. - unsigned actualSize() const; + size_t actualSize() const; private: /// Disable construction from rvalue @@ -316,20 +319,23 @@ private: unsigned lengthSize() const { if (isData() && m_data[0] > c_rlpDataIndLenZero) return m_data[0] - c_rlpDataIndLenZero; if (isList() && m_data[0] > c_rlpListIndLenZero) return m_data[0] - c_rlpListIndLenZero; return 0; } /// @returns the size in bytes of the payload, as given by the RLP as opposed to as inferred from m_data. - unsigned length() const; + size_t length() const; /// @returns the number of bytes into the data that the payload starts. - unsigned payloadOffset() const { return isSingleByte() ? 0 : (1 + lengthSize()); } + size_t payloadOffset() const { return isSingleByte() ? 0 : (1 + lengthSize()); } /// @returns the number of data items. - unsigned items() const; + size_t items() const; + + /// @returns the size encoded into the RLP in @a _data and throws if _data is too short. + static size_t sizeAsEncoded(bytesConstRef _data) { return RLP(_data, ThrowOnFail | FailIfTooSmall).actualSize(); } /// Our byte data. bytesConstRef m_data; /// The list-indexing cache. - mutable unsigned m_lastIndex = (unsigned)-1; - mutable unsigned m_lastEnd = 0; + mutable size_t m_lastIndex = (size_t)-1; + mutable size_t m_lastEnd = 0; mutable bytesConstRef m_lastItem; }; @@ -343,7 +349,7 @@ public: RLPStream() {} /// Initializes the RLPStream as a list of @a _listItems items. - explicit RLPStream(unsigned _listItems) { appendList(_listItems); } + explicit RLPStream(size_t _listItems) { appendList(_listItems); } ~RLPStream() {} @@ -359,7 +365,7 @@ public: template RLPStream& append(FixedHash _s, bool _compact = false, bool _allOrNothing = false) { return _allOrNothing && !_s ? append(bytesConstRef()) : append(_s.ref(), _compact); } /// Appends an arbitrary RLP fragment - this *must* be a single item unless @a _itemCount is given. - RLPStream& append(RLP const& _rlp, unsigned _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); } + RLPStream& append(RLP const& _rlp, size_t _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); } /// Appends a sequence of data to the stream as a list. template RLPStream& append(std::vector<_T> const& _s) { return appendVector(_s); } @@ -370,14 +376,14 @@ public: template RLPStream& append(std::pair const& _s) { appendList(2); append(_s.first); append(_s.second); return *this; } /// Appends a list. - RLPStream& appendList(unsigned _items); + RLPStream& appendList(size_t _items); RLPStream& appendList(bytesConstRef _rlp); RLPStream& appendList(bytes const& _rlp) { return appendList(&_rlp); } RLPStream& appendList(RLPStream const& _s) { return appendList(&_s.out()); } /// Appends raw (pre-serialised) RLP data. Use with caution. - RLPStream& appendRaw(bytesConstRef _rlp, unsigned _itemCount = 1); - RLPStream& appendRaw(bytes const& _rlp, unsigned _itemCount = 1) { return appendRaw(&_rlp, _itemCount); } + RLPStream& appendRaw(bytesConstRef _rlp, size_t _itemCount = 1); + RLPStream& appendRaw(bytes const& _rlp, size_t _itemCount = 1) { return appendRaw(&_rlp, _itemCount); } /// Shift operators for appending data items. template RLPStream& operator<<(T _data) { return append(_data); } @@ -392,14 +398,14 @@ public: void swapOut(bytes& _dest) { if(!m_listStack.empty()) BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("listStack is not empty")); swap(m_out, _dest); } private: - void noteAppended(unsigned _itemCount = 1); + void noteAppended(size_t _itemCount = 1); /// Push the node-type byte (using @a _base) along with the item count @a _count. /// @arg _count is number of characters for strings, data-bytes for ints, or items for lists. - void pushCount(unsigned _count, byte _offset); + void pushCount(size_t _count, byte _offset); /// Push an integer as a raw big-endian byte-stream. - template void pushInt(_T _i, unsigned _br) + template void pushInt(_T _i, size_t _br) { m_out.resize(m_out.size() + _br); byte* b = &m_out.back(); @@ -410,7 +416,7 @@ private: /// Our output byte stream. bytes m_out; - std::vector> m_listStack; + std::vector> m_listStack; }; template void rlpListAux(RLPStream& _out, _T _t) { _out << _t; } diff --git a/libdevcore/RangeMask.h b/libdevcore/RangeMask.h index 7c402fc98..6c32517f5 100644 --- a/libdevcore/RangeMask.h +++ b/libdevcore/RangeMask.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,12 @@ class RLPStream; using UnsignedRange = std::pair; using UnsignedRanges = std::vector; +/** + * Set of elements of a certain "ground range" representable by unions of ranges inside this + * ground range. + * Ranges are given as pairs (begin, end), denoting the interval [begin, end), i.e. end is excluded. + * Supports set-theoretic operators, size and iteration. + */ template class RangeMask { @@ -44,14 +51,19 @@ public: using Range = std::pair; using Ranges = std::vector; + /// Constructs an empty range mask with empty ground range. RangeMask(): m_all(0, 0) {} + /// Constructs an empty range mask with ground range [_begin, _end). RangeMask(T _begin, T _end): m_all(_begin, _end) {} + /// Constructs an empty range mask with ground range _c. RangeMask(Range const& _c): m_all(_c) {} + /// @returns the union with the range mask _m, taking also the union of the ground ranges. RangeMask unionedWith(RangeMask const& _m) const { return operator+(_m); } RangeMask operator+(RangeMask const& _m) const { return RangeMask(*this) += _m; } - RangeMask lowest(T _items) const + /// @returns a new range mask containing the smallest _items elements (not ranges). + RangeMask lowest(decltype(T{} - T{}) _items) const { RangeMask ret(m_all); for (auto i = m_ranges.begin(); i != m_ranges.end() && _items; ++i) @@ -59,8 +71,10 @@ public: return ret; } + /// @returns the complement of the range mask relative to the ground range. RangeMask operator~() const { return inverted(); } + /// @returns a copy of this range mask representing the complement relative to the ground range. RangeMask inverted() const { RangeMask ret(m_all); @@ -76,6 +90,8 @@ public: return ret; } + /// Changes the range mask to its complement relative to the ground range and returns a + /// reference to itself. RangeMask& invert() { return *this = inverted(); } template RangeMask operator-(S const& _m) const { auto ret = *this; return ret -= _m; } @@ -92,61 +108,13 @@ public: return *this; } RangeMask& operator+=(Range const& _m) { return unionWith(_m); } - RangeMask& unionWith(Range const& _m) - { - for (auto i = _m.first; i < _m.second;) - { - assert(i >= m_all.first); - assert(i < m_all.second); - // for each number, we find the element equal or next lower. this, if any, must contain the value. - auto uit = m_ranges.upper_bound(i); - auto it = uit == m_ranges.begin() ? m_ranges.end() : std::prev(uit); - if (it == m_ranges.end() || it->second < i) - // lower range is too low to merge. - // if the next higher range is too high. - if (uit == m_ranges.end() || uit->first > _m.second) - { - // just create a new range - m_ranges[i] = _m.second; - break; - } - else - { - if (uit->first == i) - // move i to end of range - i = uit->second; - else - { - // merge with the next higher range - // move i to end of range - i = m_ranges[i] = uit->second; - i = uit->second; - m_ranges.erase(uit); - } - } - else if (it->second == i) - { - // if the next higher range is too high. - if (uit == m_ranges.end() || uit->first > _m.second) - { - // merge with the next lower range - m_ranges[it->first] = _m.second; - break; - } - else - { - // merge with both next lower & next higher. - i = m_ranges[it->first] = uit->second; - m_ranges.erase(uit); - } - } - else - i = it->second; - } - return *this; - } + /// Modifies this range mask to also include the range _m, which has to be a subset of + /// the ground range. + RangeMask& unionWith(Range const& _m); + /// Adds the single element _i to the range mask. RangeMask& operator+=(T _m) { return unionWith(_m); } + /// Adds the single element _i to the range mask. RangeMask& unionWith(T _i) { return operator+=(Range(_i, _i + 1)); @@ -181,10 +149,12 @@ public: m_all = std::make_pair(0, 0); } + /// @returns the ground range. std::pair const& all() const { return m_all; } + /// Extends the ground range to include _i. void extendAll(T _i) { m_all = std::make_pair(std::min(m_all.first, _i), std::max(m_all.second, _i + 1)); } - class const_iterator + class const_iterator: public std::iterator { friend class RangeMask; @@ -208,6 +178,8 @@ public: const_iterator begin() const { return const_iterator(*this, false); } const_iterator end() const { return const_iterator(*this, true); } + /// @returns the smallest element in the range mask that is larger than _t or the end of the + /// base range if such an element does not exist. T next(T _t) const { _t++; @@ -219,6 +191,7 @@ public: return uit == m_ranges.end() ? m_all.second : uit->first; } + /// @returns the number of elements (not ranges) in the range mask. size_t size() const { size_t c = 0; @@ -227,8 +200,24 @@ public: return c; } + size_t firstOut() const + { + if (m_ranges.empty() || !m_ranges.count(m_all.first)) + return m_all.first; + return m_ranges.at(m_all.first); + } + + size_t lastIn() const + { + if (m_ranges.empty()) + return m_all.first; + return m_ranges.rbegin()->second - 1; + } + private: + /// The ground range. UnsignedRange m_all; + /// Mapping begin -> end containing the ranges. std::map m_ranges; }; @@ -241,4 +230,65 @@ template inline std::ostream& operator<<(std::ostream& _out, RangeMask return _out; } +template +RangeMask& RangeMask::unionWith(typename RangeMask::Range const& _m) +{ + for (auto i = _m.first; i < _m.second;) + { + assert(i >= m_all.first); + assert(i < m_all.second); + // For each number, we find the element equal or next lower. this, if any, must contain the value. + // First range that starts after i. + auto rangeAfter = m_ranges.upper_bound(i); + // Range before rangeAfter or "end" if the rangeAfter is the first ever... + auto it = rangeAfter == m_ranges.begin() ? m_ranges.end() : std::prev(rangeAfter); + if (it == m_ranges.end() || it->second < i) + { + // i is either before the first range or between two ranges (with some distance + // so that we cannot merge it onto "it"). + // lower range is too low to merge. + // if the next higher range is too high. + if (rangeAfter == m_ranges.end() || rangeAfter->first > _m.second) + { + // just create a new range + m_ranges[i] = _m.second; + break; + } + else + { + if (rangeAfter->first == i) + // move i to end of range + i = rangeAfter->second; + else + { + // merge with the next higher range + // move i to end of range + i = m_ranges[i] = rangeAfter->second; + m_ranges.erase(rangeAfter); + } + } + } + else if (it->second == i) + { + // The range before i ends with i. + // if the next higher range is too high. + if (rangeAfter == m_ranges.end() || rangeAfter->first > _m.second) + { + // merge with the next lower range + m_ranges[it->first] = _m.second; + break; + } + else + { + // merge with both next lower & next higher. + i = m_ranges[it->first] = rangeAfter->second; + m_ranges.erase(rangeAfter); + } + } + else + i = it->second; + } + return *this; +} + } diff --git a/libdevcore/TrieCommon.h b/libdevcore/TrieCommon.h index 8d6be8ebd..822cc66e4 100644 --- a/libdevcore/TrieCommon.h +++ b/libdevcore/TrieCommon.h @@ -32,26 +32,38 @@ inline byte nibble(bytesConstRef _data, unsigned _i) return (_i & 1) ? (_data[_i / 2] & 15) : (_data[_i / 2] >> 4); } -inline unsigned sharedNibbles(bytesConstRef _a, unsigned _ab, unsigned _ae, bytesConstRef _b, unsigned _bb, unsigned _be) +/// Interprets @a _first and @a _second as vectors of nibbles and returns the length of the longest common +/// prefix of _first[_beginFirst..._endFirst] and _second[_beginSecond..._endSecond]. +inline unsigned sharedNibbles(bytesConstRef _first, unsigned _beginFirst, unsigned _endFirst, bytesConstRef _second, unsigned _beginSecond, unsigned _endSecond) { unsigned ret = 0; - for (unsigned ai = _ab, bi = _bb; ai < _ae && bi < _be && nibble(_a, ai) == nibble(_b, bi); ++ai, ++bi, ++ret) {} + while (_beginFirst < _endFirst && _beginSecond < _endSecond && nibble(_first, _beginFirst) == nibble(_second, _beginSecond)) + { + ++_beginFirst; + ++_beginSecond; + ++ret; + } return ret; } +/** + * Nibble-based view on a bytesConstRef. + */ struct NibbleSlice { bytesConstRef data; unsigned offset; - NibbleSlice(bytesConstRef _d = bytesConstRef(), unsigned _o = 0): data(_d), offset(_o) {} + NibbleSlice(bytesConstRef _data = bytesConstRef(), unsigned _offset = 0): data(_data), offset(_offset) {} byte operator[](unsigned _index) const { return nibble(data, offset + _index); } unsigned size() const { return data.size() * 2 - offset; } bool empty() const { return !size(); } NibbleSlice mid(unsigned _index) const { return NibbleSlice(data, offset + _index); } void clear() { data.reset(); offset = 0; } + /// @returns true iff _k is a prefix of this. bool contains(NibbleSlice _k) const { return shared(_k) == _k.size(); } + /// @returns the number of shared nibbles at the beginning of this and _k. unsigned shared(NibbleSlice _k) const { return sharedNibbles(data, offset, offset + size(), _k.data, _k.offset, _k.offset + _k.size()); } /** * @brief Determine if we, a full key, are situated prior to a particular key-prefix. @@ -60,8 +72,8 @@ struct NibbleSlice */ bool isEarlierThan(NibbleSlice _k) const { - unsigned i; - for (i = 0; i < _k.size() && i < size(); ++i) + unsigned i = 0; + for (; i < _k.size() && i < size(); ++i) if (operator[](i) < _k[i]) // Byte is lower - we're earlier.. return true; else if (operator[](i) > _k[i]) // Byte is higher - we're not earlier. diff --git a/libdevcore/TrieDB.h b/libdevcore/TrieDB.h index f35cf893c..55ca81023 100644 --- a/libdevcore/TrieDB.h +++ b/libdevcore/TrieDB.h @@ -66,7 +66,7 @@ class GenericTrieDB public: using DB = _DB; - GenericTrieDB(DB* _db = nullptr): m_db(_db) {} + explicit GenericTrieDB(DB* _db = nullptr): m_db(_db) {} GenericTrieDB(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { open(_db, _root, _v); } ~GenericTrieDB() {} @@ -96,11 +96,72 @@ public: /// True if the trie is initialised but empty (i.e. that the DB contains the root node which is empty). bool isEmpty() const { return m_root == c_shaNull && node(m_root).size(); } - h256 const& root() const { if (!node(m_root).size()) BOOST_THROW_EXCEPTION(BadRoot()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly. + h256 const& root() const { if (node(m_root).empty()) BOOST_THROW_EXCEPTION(BadRoot()); /*std::cout << "Returning root as " << ret << " (really " << m_root << ")" << std::endl;*/ return m_root; } // patch the root in the case of the empty trie. TODO: handle this properly. + + std::string at(bytes const& _key) const { return at(&_key); } + std::string at(bytesConstRef _key) const; + void insert(bytes const& _key, bytes const& _value) { insert(&_key, &_value); } + void insert(bytesConstRef _key, bytes const& _value) { insert(_key, &_value); } + void insert(bytes const& _key, bytesConstRef _value) { insert(&_key, _value); } + void insert(bytesConstRef _key, bytesConstRef _value); + void remove(bytes const& _key) { remove(&_key); } + void remove(bytesConstRef _key); + bool contains(bytes const& _key) { return contains(&_key); } + bool contains(bytesConstRef _key) { return !at(_key).empty(); } + + class iterator + { + public: + using value_type = std::pair; + + iterator() {} + explicit iterator(GenericTrieDB const* _db); + iterator(GenericTrieDB const* _db, bytesConstRef _key); + + iterator& operator++() { next(); return *this; } + + value_type operator*() const { return at(); } + value_type operator->() const { return at(); } + + bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; } + bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; } + + value_type at() const; + + private: + void next(); + void next(NibbleSlice _key); + + struct Node + { + std::string rlp; + std::string key; // as hexPrefixEncoding. + byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children. + + // 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17 + + void setChild(unsigned _i) { child = _i; } + void setFirstChild() { child = 16; } + void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); } + + bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; } + bool operator!=(Node const& _c) const { return !operator==(_c); } + }; + + protected: + std::vector m_trail; + GenericTrieDB const* m_that; + }; + + iterator begin() const { return iterator(this); } + iterator end() const { return iterator(); } + + iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); } void debugPrint() {} - void descendKey(h256 _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const + /// Used for debugging, scans the whole trie. + void descendKey(h256 const& _k, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent = 0) const { _keyMask.erase(_k); if (_k == m_root && _k == c_shaNull) // root allowed to be empty @@ -108,6 +169,7 @@ public: descendList(RLP(node(_k)), _keyMask, _wasExt, _out, _indent); // if not, it must be a list } + /// Used for debugging, scans the whole trie. void descendEntry(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const { if (_r.isData() && _r.size() == 32) @@ -118,6 +180,7 @@ public: BOOST_THROW_EXCEPTION(InvalidTrie()); } + /// Used for debugging, scans the whole trie. void descendList(RLP const& _r, h256Hash& _keyMask, bool _wasExt, std::ostream* _out, int _indent) const { if (_r.isList() && _r.itemCount() == 2 && (!_wasExt || _out)) @@ -139,6 +202,7 @@ public: BOOST_THROW_EXCEPTION(InvalidTrie()); } + /// Used for debugging, scans the whole trie. h256Hash leftOvers(std::ostream* _out = nullptr) const { h256Hash k = m_db->keys(); @@ -146,11 +210,14 @@ public: return k; } + /// Used for debugging, scans the whole trie. void debugStructure(std::ostream& _out) const { leftOvers(&_out); } + /// Used for debugging, scans the whole trie. + /// @param _requireNoLeftOvers if true, requires that all keys are reachable. bool check(bool _requireNoLeftOvers) const { try @@ -164,66 +231,6 @@ public: } } - std::string at(bytes const& _key) const { return at(&_key); } - std::string at(bytesConstRef _key) const; - void insert(bytes const& _key, bytes const& _value) { insert(&_key, &_value); } - void insert(bytesConstRef _key, bytes const& _value) { insert(_key, &_value); } - void insert(bytes const& _key, bytesConstRef _value) { insert(&_key, _value); } - void insert(bytesConstRef _key, bytesConstRef _value); - void remove(bytes const& _key) { remove(&_key); } - void remove(bytesConstRef _key); - bool contains(bytes const& _key) { return contains(&_key); } - bool contains(bytesConstRef _key) { return !at(_key).empty(); } - - class iterator - { - public: - using value_type = std::pair; - - iterator() {} - iterator(GenericTrieDB const* _db); - iterator(GenericTrieDB const* _db, bytesConstRef _key); - - iterator& operator++() { next(); return *this; } - - value_type operator*() const { return at(); } - value_type operator->() const { return at(); } - - bool operator==(iterator const& _c) const { return _c.m_trail == m_trail; } - bool operator!=(iterator const& _c) const { return _c.m_trail != m_trail; } - - value_type at() const; - - private: - void next(); - void next(NibbleSlice _key); - - struct Node - { - std::string rlp; - std::string key; // as hexPrefixEncoding. - byte child; // 255 -> entering, 16 -> actually at the node, 17 -> exiting, 0-15 -> actual children. - - // 255 -> 16 -> 0 -> 1 -> ... -> 15 -> 17 - - void setChild(unsigned _i) { child = _i; } - void setFirstChild() { child = 16; } - void incrementChild() { child = child == 16 ? 0 : child == 15 ? 17 : (child + 1); } - - bool operator==(Node const& _c) const { return rlp == _c.rlp && key == _c.key && child == _c.child; } - bool operator!=(Node const& _c) const { return !operator==(_c); } - }; - - protected: - std::vector m_trail; - GenericTrieDB const* m_that; - }; - - iterator begin() const { return this; } - iterator end() const { return iterator(); } - - iterator lower_bound(bytesConstRef _key) const { return iterator(this, _key); } - protected: DB* db() const { return m_db; } @@ -279,12 +286,12 @@ private: bool isTwoItemNode(RLP const& _n) const; std::string deref(RLP const& _n) const; - std::string node(h256 _h) const { return m_db->lookup(_h); } + std::string node(h256 const& _h) const { return m_db->lookup(_h); } // 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); } + void forceInsertNode(h256 const& _h, bytesConstRef _v) { m_db->insert(_h, _v); } + void forceKillNode(h256 const& _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 @@ -305,6 +312,9 @@ std::ostream& operator<<(std::ostream& _out, GenericTrieDB const& _db) return _out; } +/** + * Different view on a GenericTrieDB that can use different key types. + */ template class SpecificTrieDB: public Generic { @@ -753,14 +763,14 @@ template void GenericTrieDB::insert(bytesConstRef _key, bytesCons tdebug << "Insert" << toHex(_key.cropped(0, 4)) << "=>" << toHex(_value); #endif - std::string rv = node(m_root); - assert(rv.size()); - bytes b = mergeAt(RLP(rv), m_root, NibbleSlice(_key), _value); + std::string rootValue = node(m_root); + assert(rootValue.size()); + bytes b = mergeAt(RLP(rootValue), 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) + if (rootValue.size() < 32) forceKillNode(m_root); m_root = forceInsertNode(&b); } @@ -1066,11 +1076,11 @@ template bytes GenericTrieDB::place(RLP const& _orig, NibbleSlice killNode(_orig); if (_orig.isEmpty()) - return (RLPStream(2) << hexPrefixEncode(_k, true) << _s).out(); + return rlpList(hexPrefixEncode(_k, true), _s); assert(_orig.isList() && (_orig.itemCount() == 2 || _orig.itemCount() == 17)); if (_orig.itemCount() == 2) - return (RLPStream(2) << _orig[0] << _s).out(); + return rlpList(_orig[0], _s); auto s = RLPStream(17); for (unsigned i = 0; i < 16; ++i) @@ -1152,7 +1162,7 @@ template bytes GenericTrieDB::graft(RLP const& _orig) } assert(n.itemCount() == 2); - return (RLPStream(2) << hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)) << n[1]).out(); + return rlpList(hexPrefixEncode(keyOf(_orig), keyOf(n), isLeaf(n)), n[1]); // auto ret = // std::cout << keyOf(_orig) << " ++ " << keyOf(n) << " == " << keyOf(RLP(ret)) << std::endl; // return ret; @@ -1201,11 +1211,7 @@ template bytes GenericTrieDB::branch(RLP const& _orig) for (unsigned i = 0; i < 16; ++i) if (i == b) if (isLeaf(_orig) || k.size() > 1) - { - RLPStream bottom(2); - bottom << hexPrefixEncode(k.mid(1), isLeaf(_orig)) << _orig[1]; - streamNode(r, bottom.out()); - } + streamNode(r, rlpList(hexPrefixEncode(k.mid(1), isLeaf(_orig)), _orig[1])); else r << _orig[1]; else diff --git a/libdevcrypto/Common.cpp b/libdevcrypto/Common.cpp index de1eb645a..186c6ce06 100644 --- a/libdevcrypto/Common.cpp +++ b/libdevcrypto/Common.cpp @@ -22,6 +22,7 @@ #include "Common.h" #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #if ETH_HAVE_SECP256K1 #include #endif @@ -46,7 +48,6 @@ struct Secp256k1Context ~Secp256k1Context() { secp256k1_stop(); } }; static Secp256k1Context s_secp256k1; -void dev::crypto::secp256k1Init() { (void)s_secp256k1; } #endif static Secp256k1PP s_secp256k1pp; @@ -91,6 +92,11 @@ Address dev::toAddress(Secret const& _secret) return toAddress(p); } +Address dev::toAddress(Address const& _from, u256 const& _nonce) +{ + return right160(sha3(rlpList(_from, _nonce))); +} + void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher) { bytes io = _plain.toBytes(); @@ -184,17 +190,40 @@ bytes dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _ci Public dev::recover(Signature const& _sig, h256 const& _message) { +#ifdef ETH_HAVE_SECP256K1 + bytes o(65); + int pubkeylen; + if (!secp256k1_ecdsa_recover_compact(_message.data(), h256::size, _sig.data(), o.data(), &pubkeylen, false, _sig[64])) + return Public(); + return FixedHash<64>(o.data()+1, Public::ConstructFromPointer); +#else return s_secp256k1pp.recover(_sig, _message.ref()); +#endif } Signature dev::sign(Secret const& _k, h256 const& _hash) { +#ifdef ETH_HAVE_SECP256K1 + Signature s; + int v; + if (!secp256k1_ecdsa_sign_compact(_hash.data(), h256::size, s.data(), _k.data(), Nonce::get().data(), &v)) + return Signature(); + s[64] = v; + return s; +#else return s_secp256k1pp.sign(_k, _hash); +#endif } bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash) { + if (!_p) + return false; +#ifdef ETH_HAVE_SECP256K1 + return _p == recover(_s, _hash); +#else return s_secp256k1pp.verify(_p, _s, _hash.ref(), true); +#endif } bytes dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen) @@ -234,16 +263,9 @@ bytes dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uin KeyPair KeyPair::create() { - static boost::thread_specific_ptr s_eng; - static unsigned s_id = 0; - if (!s_eng.get()) - s_eng.reset(new mt19937_64(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count() + ++s_id)); - - uniform_int_distribution d(0, 255); - for (int i = 0; i < 100; ++i) { - KeyPair ret(FixedHash<32>::random(*s_eng.get())); + KeyPair ret(FixedHash<32>::random()); if (ret.address()) return ret; } @@ -325,7 +347,7 @@ void Nonce::initialiseIfNeeded() std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count()); std::uniform_int_distribution d(0, 255); for (unsigned i = 0; i < 32; ++i) - m_value[i] = byte(d(s_eng)); + m_value[i] = (uint8_t)d(s_eng); } if (!m_value) BOOST_THROW_EXCEPTION(InvalidState()); diff --git a/libdevcrypto/Common.h b/libdevcrypto/Common.h index 7bb46c3ea..c45e060b2 100644 --- a/libdevcrypto/Common.h +++ b/libdevcrypto/Common.h @@ -85,6 +85,9 @@ Address toAddress(Public const& _public); /// @returns 0 if it's not a valid secret key. Address toAddress(Secret const& _secret); +// Convert transaction from and nonce to address. +Address toAddress(Address const& _from, u256 const& _nonce); + /// Encrypts plain text using Public key. void encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher); @@ -177,8 +180,6 @@ namespace crypto { struct InvalidState: public dev::Exception {}; -void secp256k1Init(); - /// Key derivation h256 kdf(Secret const& _priv, h256 const& _hash); diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index 270367de5..5ca93af4d 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -103,7 +103,7 @@ bool Secp256k1PP::decryptECIES(Secret const& _k, bytes& io_text) // interop w/go ecies implementation // io_cipher[0] must be 2, 3, or 4, else invalidpublickey - if (io_text[0] < 2 || io_text[0] > 4) + if (io_text.empty() || io_text[0] < 2 || io_text[0] > 4) // invalid message: publickey return false; diff --git a/libethash-cl/CMakeLists.txt b/libethash-cl/CMakeLists.txt index 6da254cfb..9dc45fcf5 100644 --- a/libethash-cl/CMakeLists.txt +++ b/libethash-cl/CMakeLists.txt @@ -20,6 +20,7 @@ file(GLOB OUR_HEADERS "*.h") set(HEADERS ${OUR_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/ethash_cl_miner_kernel.h) include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories(${Boost_INCLUDE_DIRS}) include_directories(${OpenCL_INCLUDE_DIRS}) include_directories(..) add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp index 3a72810fa..942819ba8 100644 --- a/libethash-cl/ethash_cl_miner.cpp +++ b/libethash-cl/ethash_cl_miner.cpp @@ -50,6 +50,10 @@ using namespace std; +unsigned const ethash_cl_miner::c_defaultLocalWorkSize = 64; +unsigned const ethash_cl_miner::c_defaultGlobalWorkSizeMultiplier = 4096; // * CL_DEFAULT_LOCAL_WORK_SIZE +unsigned const ethash_cl_miner::c_defaultMSPerBatch = 0; + // TODO: If at any point we can use libdevcore in here then we should switch to using a LogChannel #define ETHCL_LOG(_contents) cout << "[OPENCL]:" << _contents << endl // Types of OpenCL devices we are interested in @@ -140,15 +144,21 @@ unsigned ethash_cl_miner::getNumDevices(unsigned _platformId) bool ethash_cl_miner::configureGPU( unsigned _platformId, + unsigned _localWorkSize, + unsigned _globalWorkSize, + unsigned _msPerBatch, bool _allowCPU, unsigned _extraGPUMemory, - boost::optional _currentBlock + uint64_t _currentBlock ) { + s_workgroupSize = _localWorkSize; + s_initialGlobalWorkSize = _globalWorkSize; + s_msPerBatch = _msPerBatch; s_allowCPU = _allowCPU; s_extraRequiredGPUMem = _extraGPUMemory; // by default let's only consider the DAG of the first epoch - uint64_t dagSize = _currentBlock ? ethash_get_datasize(*_currentBlock) : 1073739904U; + uint64_t dagSize = ethash_get_datasize(_currentBlock); uint64_t requiredSize = dagSize + _extraGPUMemory; return searchForAllDevices(_platformId, [&requiredSize](cl::Device const _device) -> bool { @@ -175,6 +185,9 @@ bool ethash_cl_miner::configureGPU( bool ethash_cl_miner::s_allowCPU = false; unsigned ethash_cl_miner::s_extraRequiredGPUMem; +unsigned ethash_cl_miner::s_msPerBatch = ethash_cl_miner::c_defaultMSPerBatch; +unsigned ethash_cl_miner::s_workgroupSize = ethash_cl_miner::c_defaultLocalWorkSize; +unsigned ethash_cl_miner::s_initialGlobalWorkSize = ethash_cl_miner::c_defaultGlobalWorkSizeMultiplier * ethash_cl_miner::c_defaultLocalWorkSize; bool ethash_cl_miner::searchForAllDevices(function _callback) { @@ -254,7 +267,6 @@ void ethash_cl_miner::finish() bool ethash_cl_miner::init( uint8_t const* _dag, uint64_t _dagSize, - unsigned _workgroupSize, unsigned _platformId, unsigned _deviceId ) @@ -299,14 +311,18 @@ bool ethash_cl_miner::init( m_context = cl::Context(vector(&device, &device + 1)); m_queue = cl::CommandQueue(m_context, device); - // use requested workgroup size, but we require multiple of 8 - m_workgroupSize = ((_workgroupSize + 7) / 8) * 8; + // make sure that global work size is evenly divisible by the local workgroup size + m_globalWorkSize = s_initialGlobalWorkSize; + if (m_globalWorkSize % s_workgroupSize != 0) + m_globalWorkSize = ((m_globalWorkSize / s_workgroupSize) + 1) * s_workgroupSize; + // remember the device's address bits + m_deviceBits = device.getInfo(); // patch source code // note: ETHASH_CL_MINER_KERNEL is simply ethash_cl_miner_kernel.cl compiled // into a byte array by bin2h.cmake. There is no need to load the file by hand in runtime string code(ETHASH_CL_MINER_KERNEL, ETHASH_CL_MINER_KERNEL + ETHASH_CL_MINER_KERNEL_SIZE); - addDefinition(code, "GROUP_SIZE", m_workgroupSize); + addDefinition(code, "GROUP_SIZE", s_workgroupSize); addDefinition(code, "DAG_SIZE", (unsigned)(_dagSize / ETHASH_MIX_BYTES)); addDefinition(code, "ACCESSES", ETHASH_ACCESSES); addDefinition(code, "MAX_OUTPUTS", c_maxSearchResults); @@ -323,7 +339,7 @@ bool ethash_cl_miner::init( ETHCL_LOG("Printing program log"); ETHCL_LOG(program.getBuildInfo(device).c_str()); } - catch (cl::Error const& err) + catch (cl::Error const&) { ETHCL_LOG(program.getBuildInfo(device).c_str()); return false; @@ -415,9 +431,8 @@ bool ethash_cl_miner::init( return true; } -void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook& hook, unsigned _msPerBatch) +void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook& hook) { - (void)_msPerBatch; try { struct pending_batch @@ -454,10 +469,9 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook unsigned buf = 0; random_device engine; uint64_t start_nonce = uniform_int_distribution()(engine); - for (;; start_nonce += m_batchSize) + for (;; start_nonce += m_globalWorkSize) { -// chrono::high_resolution_clock::time_point t = chrono::high_resolution_clock::now(); - + auto t = chrono::high_resolution_clock::now(); // supply output buffer to kernel m_searchKernel.setArg(0, m_searchBuffer[buf]); if (m_dagChunksCount == 1) @@ -466,7 +480,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook m_searchKernel.setArg(6, start_nonce); // execute it! - m_queue.enqueueNDRangeKernel(m_searchKernel, cl::NullRange, m_batchSize, m_workgroupSize); + m_queue.enqueueNDRangeKernel(m_searchKernel, cl::NullRange, m_globalWorkSize, s_workgroupSize); pending.push({ start_nonce, buf }); buf = (buf + 1) % c_bufferCount; @@ -486,7 +500,7 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook m_queue.enqueueUnmapMemObject(m_searchBuffer[batch.buf], results); bool exit = num_found && hook.found(nonces, num_found); - exit |= hook.searched(batch.start_nonce, m_batchSize); // always report searched before exit + exit |= hook.searched(batch.start_nonce, m_globalWorkSize); // always report searched before exit if (exit) break; @@ -497,19 +511,31 @@ void ethash_cl_miner::search(uint8_t const* header, uint64_t target, search_hook pending.pop(); } -/* chrono::high_resolution_clock::duration d = chrono::high_resolution_clock::now() - t; - if (d > chrono::milliseconds(_msPerBatch * 10 / 9)) + // adjust global work size depending on last search time + if (s_msPerBatch) { - cerr << "Batch of" << m_batchSize << "took" << chrono::duration_cast(d).count() << "ms, >>" << _msPerBatch << "ms."; - m_batchSize = max(128, m_batchSize * 9 / 10); - cerr << "New batch size" << m_batchSize; + // Global work size must be: + // - less than or equal to 2 ^ DEVICE_BITS - 1 + // - divisible by lobal work size (workgroup size) + auto d = chrono::duration_cast(chrono::high_resolution_clock::now() - t); + if (d != chrono::milliseconds(0)) // if duration is zero, we did not get in the actual searh/or search not finished + { + if (d > chrono::milliseconds(s_msPerBatch * 10 / 9)) + { + // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, >> " << _msPerBatch << " ms." << endl; + m_globalWorkSize = max(128, m_globalWorkSize + s_workgroupSize); + // cerr << "New global work size" << m_globalWorkSize << endl; + } + else if (d < chrono::milliseconds(s_msPerBatch * 9 / 10)) + { + // cerr << "Batch of " << m_globalWorkSize << " took " << chrono::duration_cast(d).count() << " ms, << " << _msPerBatch << " ms." << endl; + m_globalWorkSize = min(pow(2, m_deviceBits) - 1, m_globalWorkSize - s_workgroupSize); + // Global work size should never be less than the workgroup size + m_globalWorkSize = max(s_workgroupSize, m_globalWorkSize); + // cerr << "New global work size" << m_globalWorkSize << endl; + } + } } - else if (d < chrono::milliseconds(_msPerBatch * 9 / 10)) - { - cerr << "Batch of" << m_batchSize << "took" << chrono::duration_cast(d).count() << "ms, <<" << _msPerBatch << "ms."; - m_batchSize = m_batchSize * 10 / 9; - cerr << "New batch size" << m_batchSize; - }*/ } // not safe to return until this is ready diff --git a/libethash-cl/ethash_cl_miner.h b/libethash-cl/ethash_cl_miner.h index 73bf7e94a..fb28dc04b 100644 --- a/libethash-cl/ethash_cl_miner.h +++ b/libethash-cl/ethash_cl_miner.h @@ -1,6 +1,6 @@ #pragma once -#define __CL_ENABLE_EXCEPTIONS +#define __CL_ENABLE_EXCEPTIONS #define CL_USE_DEPRECATED_OPENCL_2_0_APIS #if defined(__clang__) @@ -12,7 +12,6 @@ #include "cl.hpp" #endif -#include #include #include #include @@ -20,7 +19,7 @@ class ethash_cl_miner { private: - enum { c_maxSearchResults = 63, c_bufferCount = 2, c_hashBatchSize = 1024, c_searchBatchSize = 1024 * 16 }; + enum { c_maxSearchResults = 63, c_bufferCount = 2, c_hashBatchSize = 1024 }; public: struct search_hook @@ -45,24 +44,34 @@ public: static void listDevices(); static bool configureGPU( unsigned _platformId, + unsigned _localWorkSize, + unsigned _globalWorkSize, + unsigned _msPerBatch, bool _allowCPU, unsigned _extraGPUMemory, - boost::optional _currentBlock + uint64_t _currentBlock ); bool init( uint8_t const* _dag, uint64_t _dagSize, - unsigned _workgroupSize = 64, unsigned _platformId = 0, unsigned _deviceId = 0 ); void finish(); - void search(uint8_t const* _header, uint64_t _target, search_hook& _hook, unsigned _msPerBatch = 100); + void search(uint8_t const* _header, uint64_t _target, search_hook& _hook); void hash_chunk(uint8_t* _ret, uint8_t const* _header, uint64_t _nonce, unsigned _count); void search_chunk(uint8_t const*_header, uint64_t _target, search_hook& _hook); + /* -- default values -- */ + /// Default value of the local work size. Also known as workgroup size. + static unsigned const c_defaultLocalWorkSize; + /// Default value of the global work size as a multiplier of the local work size + static unsigned const c_defaultGlobalWorkSizeMultiplier; + /// Default value of the milliseconds per global work size (per batch) + static unsigned const c_defaultMSPerBatch; + private: static std::vector getDevices(std::vector const& _platforms, unsigned _platformId); @@ -76,10 +85,16 @@ private: cl::Buffer m_header; cl::Buffer m_hashBuffer[c_bufferCount]; cl::Buffer m_searchBuffer[c_bufferCount]; - unsigned m_workgroupSize; - unsigned m_batchSize = c_searchBatchSize; + unsigned m_globalWorkSize; bool m_openclOnePointOne; + unsigned m_deviceBits; + /// The local work size for the search + static unsigned s_workgroupSize; + /// The initial global work size for the searches + static unsigned s_initialGlobalWorkSize; + /// The target milliseconds per batch for the search. If 0, then no adjustment will happen + static unsigned s_msPerBatch; /// Allow CPU to appear as an OpenCL device or not. Default is false static bool s_allowCPU; /// GPU memory required for other things, like window rendering e.t.c. diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index a527ad1f4..4dd626642 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.h b/libethcore/Common.h index 732d09981..296f0d01d 100644 --- a/libethcore/Common.h +++ b/libethcore/Common.h @@ -97,10 +97,13 @@ enum class RelativeBlock: BlockNumber Pending = PendingBlock }; +class Transaction; + struct ImportRoute { h256s deadBlocks; h256s liveBlocks; + std::vector goodTranactions; }; enum class ImportResult @@ -129,10 +132,10 @@ struct ImportRequirements }; /// Super-duper signal mechanism. TODO: replace with somthing a bit heavier weight. -class Signal +template class Signal { public: - using Callback = std::function; + using Callback = std::function; class HandlerAux { @@ -141,7 +144,7 @@ public: public: ~HandlerAux() { if (m_s) m_s->m_fire.erase(m_i); m_s = nullptr; } void reset() { m_s = nullptr; } - void fire() { m_h(); } + void fire(Args&&... _args) { m_h(std::forward(_args)...); } private: HandlerAux(unsigned _i, Signal* _s, Callback const& _h): m_i(_i), m_s(_s), m_h(_h) {} @@ -154,7 +157,8 @@ public: ~Signal() { for (auto const& h : m_fire) - h.second->reset(); + if (auto l = h.second.lock()) + l->reset(); } std::shared_ptr add(Callback const& _h) @@ -165,13 +169,18 @@ public: return h; } - void operator()() { for (auto const& f: m_fire) f.second->fire(); } + void operator()(Args&... _args) + { + for (auto const& f: m_fire) + if (auto h = f.second.lock()) + h->fire(std::forward(_args)...); + } private: - std::map> m_fire; + std::map> m_fire; }; -using Handler = std::shared_ptr; +template using Handler = std::shared_ptr::HandlerAux>; struct TransactionSkeleton { @@ -182,6 +191,7 @@ struct TransactionSkeleton bytes data; u256 gas = UndefinedU256; u256 gasPrice = UndefinedU256; + u256 nonce = UndefinedU256; }; void badBlock(bytesConstRef _header, std::string const& _err); diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp index 46d19d164..9be76926d 100644 --- a/libethcore/Ethash.cpp +++ b/libethcore/Ethash.cpp @@ -373,7 +373,7 @@ void Ethash::GPUMiner::workLoop() this_thread::sleep_for(chrono::milliseconds(500)); } bytesConstRef dagData = dag->data(); - m_miner->init(dagData.data(), dagData.size(), 32, s_platformId, device); + m_miner->init(dagData.data(), dagData.size(), s_platformId, device); } uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192); @@ -409,16 +409,39 @@ void Ethash::GPUMiner::listDevices() } bool Ethash::GPUMiner::configureGPU( + unsigned _localWorkSize, + unsigned _globalWorkSizeMultiplier, + unsigned _msPerBatch, unsigned _platformId, unsigned _deviceId, bool _allowCPU, unsigned _extraGPUMemory, - boost::optional _currentBlock + uint64_t _currentBlock ) { s_platformId = _platformId; s_deviceId = _deviceId; - return ethash_cl_miner::configureGPU(_platformId, _allowCPU, _extraGPUMemory, _currentBlock); + + if (_localWorkSize != 32 && _localWorkSize != 64 && _localWorkSize != 128) + { + cout << "Given localWorkSize of " << toString(_localWorkSize) << "is invalid. Must be either 32,64, or 128" << endl; + return false; + } + + if (!ethash_cl_miner::configureGPU( + _platformId, + _localWorkSize, + _globalWorkSizeMultiplier * _localWorkSize, + _msPerBatch, + _allowCPU, + _extraGPUMemory, + _currentBlock) + ) + { + cout << "No GPU device with sufficient memory was found. Can't GPU mine. Remove the -G argument" << endl; + return false; + } + return true; } #endif diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h index 11e012df5..7ffd887d0 100644 --- a/libethcore/Ethash.h +++ b/libethcore/Ethash.h @@ -88,7 +88,7 @@ public: static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); } static std::string platformInfo(); static void listDevices() {} - static bool configureGPU(unsigned, unsigned, bool, unsigned, boost::optional) { return false; } + static bool configureGPU(unsigned, unsigned, unsigned, unsigned, unsigned, bool, unsigned, uint64_t) { return false; } static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, std::thread::hardware_concurrency()); } protected: void kickOff() override @@ -118,11 +118,14 @@ public: static unsigned getNumDevices(); static void listDevices(); static bool configureGPU( + unsigned _localWorkSize, + unsigned _globalWorkSizeMultiplier, + unsigned _msPerBatch, unsigned _platformId, unsigned _deviceId, bool _allowCPU, unsigned _extraGPUMemory, - boost::optional _currentBlock + uint64_t _currentBlock ); static void setNumInstances(unsigned _instances) { s_numInstances = std::min(_instances, getNumDevices()); } diff --git a/libethcore/Transaction.cpp b/libethcore/Transaction.cpp new file mode 100644 index 000000000..302579aa2 --- /dev/null +++ b/libethcore/Transaction.cpp @@ -0,0 +1,132 @@ +/* + 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 TransactionBase.cpp + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include +#include +#include +#include "Transaction.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +TransactionBase::TransactionBase(TransactionSkeleton const& _ts, Secret const& _s): + m_type(_ts.creation ? ContractCreation : MessageCall), + m_nonce(_ts.nonce), + m_value(_ts.value), + m_receiveAddress(_ts.to), + m_gasPrice(_ts.gasPrice), + m_gas(_ts.gas), + m_data(_ts.data), + m_sender(_ts.from) +{ + if (_s) + sign(_s); +} + +TransactionBase::TransactionBase(bytesConstRef _rlpData, CheckTransaction _checkSig) +{ + int field = 0; + RLP rlp(_rlpData); + try + { + if (!rlp.isList()) + BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction RLP must be a list")); + + m_nonce = rlp[field = 0].toInt(); + m_gasPrice = rlp[field = 1].toInt(); + m_gas = rlp[field = 2].toInt(); + m_type = rlp[field = 3].isEmpty() ? ContractCreation : MessageCall; + m_receiveAddress = rlp[field = 3].isEmpty() ? Address() : rlp[field = 3].toHash
(RLP::VeryStrict); + m_value = rlp[field = 4].toInt(); + + if (!rlp[field = 5].isData()) + BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction data RLP must be an array")); + + m_data = rlp[field = 5].toBytes(); + byte v = rlp[field = 6].toInt() - 27; + h256 r = rlp[field = 7].toInt(); + h256 s = rlp[field = 8].toInt(); + + if (rlp.itemCount() > 9) + BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("to many fields in the transaction RLP")); + + m_vrs = SignatureStruct{ r, s, v }; + if (_checkSig >= CheckTransaction::Cheap && !m_vrs.isValid()) + BOOST_THROW_EXCEPTION(InvalidSignature()); + if (_checkSig == CheckTransaction::Everything) + m_sender = sender(); + } + catch (Exception& _e) + { + _e << errinfo_name("invalid transaction format") << BadFieldError(field, toHex(rlp[field].data().toBytes())); + throw; + } +} + +Address const& TransactionBase::safeSender() const noexcept +{ + try + { + return sender(); + } + catch (...) + { + cwarn << "safeSender() did throw an exception: " << boost::current_exception_diagnostic_information(); + return ZeroAddress; + } +} + +Address const& TransactionBase::sender() const +{ + if (!m_sender) + { + auto p = recover(m_vrs, sha3(WithoutSignature)); + if (!p) + BOOST_THROW_EXCEPTION(InvalidSignature()); + m_sender = right160(dev::sha3(bytesConstRef(p.data(), sizeof(p)))); + } + return m_sender; +} + +void TransactionBase::sign(Secret const& _priv) +{ + auto sig = dev::sign(_priv, sha3(WithoutSignature)); + SignatureStruct sigStruct = *(SignatureStruct const*)&sig; + if (sigStruct.isValid()) + m_vrs = sigStruct; +} + +void TransactionBase::streamRLP(RLPStream& _s, IncludeSignature _sig) const +{ + if (m_type == NullTransaction) + return; + _s.appendList((_sig ? 3 : 0) + 6); + _s << m_nonce << m_gasPrice << m_gas; + if (m_type == MessageCall) + _s << m_receiveAddress; + else + _s << ""; + _s << m_value << m_data; + if (_sig) + _s << (m_vrs.v + 27) << (u256)m_vrs.r << (u256)m_vrs.s; +} diff --git a/libethcore/Transaction.h b/libethcore/Transaction.h new file mode 100644 index 000000000..de611fa5a --- /dev/null +++ b/libethcore/Transaction.h @@ -0,0 +1,179 @@ +/* + 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 TransactionBase.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +/// Named-boolean type to encode whether a signature be included in the serialisation process. +enum IncludeSignature +{ + WithoutSignature = 0, ///< Do not include a signature. + WithSignature = 1, ///< Do include a signature. +}; + +enum class CheckTransaction +{ + None, + Cheap, + Everything +}; + +/// Encodes a transaction, ready to be exported to or freshly imported from RLP. +class TransactionBase +{ +public: + /// Constructs a null transaction. + TransactionBase() {} + + /// Constructs a transaction from a transaction skeleton & optional secret. + TransactionBase(TransactionSkeleton const& _ts, Secret const& _s = Secret()); + + /// Constructs a signed message-call transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } + + /// Constructs a signed contract-creation transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } + + /// Constructs an unsigned message-call transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce = 0): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} + + /// Constructs an unsigned contract-creation transaction. + TransactionBase(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce = 0): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} + + /// Constructs a transaction from the given RLP. + explicit TransactionBase(bytesConstRef _rlp, CheckTransaction _checkSig); + + /// Constructs a transaction from the given RLP. + explicit TransactionBase(bytes const& _rlp, CheckTransaction _checkSig): TransactionBase(&_rlp, _checkSig) {} + + /// Checks equality of transactions. + bool operator==(TransactionBase const& _c) const { return m_type == _c.m_type && (m_type == ContractCreation || m_receiveAddress == _c.m_receiveAddress) && m_value == _c.m_value && m_data == _c.m_data; } + /// Checks inequality of transactions. + bool operator!=(TransactionBase const& _c) const { return !operator==(_c); } + + /// @returns sender of the transaction from the signature (and hash). + Address const& sender() const; + /// Like sender() but will never throw. @returns a null Address if the signature is invalid. + Address const& safeSender() const noexcept; + /// Force the sender to a particular value. This will result in an invalid transaction RLP. + void forceSender(Address const& _a) { m_sender = _a; } + + /// @returns true if transaction is non-null. + explicit operator bool() const { return m_type != NullTransaction; } + + /// @returns true if transaction is contract-creation. + bool isCreation() const { return m_type == ContractCreation; } + + /// @returns true if transaction is message-call. + bool isMessageCall() const { return m_type == MessageCall; } + + /// Serialises this transaction to an RLPStream. + void streamRLP(RLPStream& _s, IncludeSignature _sig = WithSignature) const; + + /// @returns the RLP serialisation of this transaction. + bytes rlp(IncludeSignature _sig = WithSignature) const { RLPStream s; streamRLP(s, _sig); return s.out(); } + + /// @returns the SHA3 hash of the RLP serialisation of this transaction. + h256 sha3(IncludeSignature _sig = WithSignature) const { if (_sig == WithSignature && m_hashWith) return m_hashWith; RLPStream s; streamRLP(s, _sig); auto ret = dev::sha3(s.out()); if (_sig == WithSignature) m_hashWith = ret; return ret; } + + /// @returns the amount of ETH to be transferred by this (message-call) transaction, in Wei. Synonym for endowment(). + u256 value() const { return m_value; } + /// @returns the amount of ETH to be endowed by this (contract-creation) transaction, in Wei. Synonym for value(). + u256 endowment() const { return m_value; } + + /// @returns the base fee and thus the implied exchange rate of ETH to GAS. + u256 gasPrice() const { return m_gasPrice; } + + /// @returns the total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. + u256 gas() const { return m_gas; } + + /// @returns the receiving address of the message-call transaction (undefined for contract-creation transactions). + Address receiveAddress() const { return m_receiveAddress; } + + /// Synonym for receiveAddress(). + Address to() const { return m_receiveAddress; } + + /// Synonym for safeSender(). + Address from() const { return safeSender(); } + + /// @returns the data associated with this (message-call) transaction. Synonym for initCode(). + bytes const& data() const { return m_data; } + /// @returns the initialisation code associated with this (contract-creation) transaction. Synonym for data(). + bytes const& initCode() const { return m_data; } + + /// @returns the transaction-count of the sender. + u256 nonce() const { return m_nonce; } + + /// @returns the signature of the transaction. Encodes the sender. + SignatureStruct const& signature() const { return m_vrs; } + + void sign(Secret const& _priv); ///< Sign the transaction. + +protected: + /// Type of transaction. + enum Type + { + NullTransaction, ///< Null transaction. + ContractCreation, ///< Transaction to create contracts - receiveAddress() is ignored. + MessageCall ///< Transaction to invoke a message call - receiveAddress() is used. + }; + + Type m_type = NullTransaction; ///< Is this a contract-creation transaction or a message-call transaction? + u256 m_nonce; ///< The transaction-count of the sender. + u256 m_value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions. + Address m_receiveAddress; ///< The receiving address of the transaction. + u256 m_gasPrice; ///< The base fee and thus the implied exchange rate of ETH to GAS. + u256 m_gas; ///< The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. + bytes m_data; ///< The data associated with the transaction, or the initialiser if it's a creation transaction. + SignatureStruct m_vrs; ///< The signature of the transaction. Encodes the sender. + + mutable h256 m_hashWith; ///< Cached hash of transaction with signature. + mutable Address m_sender; ///< Cached sender, determined from signature. + mutable bigint m_gasRequired = 0; ///< Memoised amount required for the transaction to run. +}; + +/// Nice name for vector of Transaction. +using TransactionBases = std::vector; + +/// Simple human-readable stream-shift operator. +inline std::ostream& operator<<(std::ostream& _out, TransactionBase const& _t) +{ + _out << _t.sha3().abridged() << "{"; + if (_t.receiveAddress()) + _out << _t.receiveAddress().abridged(); + else + _out << "[CREATE]"; + + _out << "/" << _t.data().size() << "$" << _t.value() << "+" << _t.gas() << "@" << _t.gasPrice(); + _out << "<-" << _t.safeSender().abridged() << " #" << _t.nonce() << "}"; + return _out; +} + +} +} diff --git a/libethereum/Account.h b/libethereum/Account.h index 87fc82b6c..4ab98e3ab 100644 --- a/libethereum/Account.h +++ b/libethereum/Account.h @@ -152,8 +152,7 @@ public: h256 codeHash() const { assert(!isFreshCode()); return m_codeHash; } /// Sets the code of the account. Must only be called when isFreshCode() returns true. - void setCode(bytes&& _code) { assert(isFreshCode()); m_codeCache = _code; changed(); } - void setCode(bytes const& _code) { assert(isFreshCode()); m_codeCache = _code; changed(); } + void setCode(bytes&& _code) { assert(isFreshCode()); m_codeCache = std::move(_code); changed(); } /// @returns true if the account's code is available through code(). bool codeCacheValid() const { return m_codeHash == EmptySHA3 || m_codeHash == c_contractConceptionCodeHash || m_codeCache.size(); } @@ -206,4 +205,3 @@ private: } } - diff --git a/libethereum/BasicGasPricer.cpp b/libethereum/BasicGasPricer.cpp new file mode 100644 index 000000000..145d23594 --- /dev/null +++ b/libethereum/BasicGasPricer.cpp @@ -0,0 +1,95 @@ +/* + 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 BasicGasPricer.cpp + * @author Gav Wood + * @date 2015 + */ + +#include +#include "BasicGasPricer.h" +#include "BlockChain.h" +using namespace std; +using namespace dev; +using namespace dev::eth; + +void BasicGasPricer::update(BlockChain const& _bc) +{ + unsigned c = 0; + h256 p = _bc.currentHash(); + m_gasPerBlock = _bc.info(p).gasLimit; + + map dist; + u256 total = 0; + + // make gasPrice versus gasUsed distribution for the last 1000 blocks + while (c < 1000 && p) + { + BlockInfo bi = _bc.info(p); + if (bi.transactionsRoot != EmptyTrie) + { + auto bb = _bc.block(p); + RLP r(bb); + BlockReceipts brs(_bc.receipts(bi.hash())); + size_t i = 0; + for (auto const& tr: r[1]) + { + Transaction tx(tr.data(), CheckTransaction::None); + u256 gu = brs.receipts[i].gasUsed(); + dist[tx.gasPrice()] += gu; + total += gu; + i++; + } + } + p = bi.parentHash; + ++c; + } + + // fill m_octiles with weighted gasPrices + if (total > 0) + { + m_octiles[0] = dist.begin()->first; + + // calc mean + u256 mean = 0; + for (auto const& i: dist) + mean += i.first * i.second; + mean /= total; + + // calc standard deviation + u256 sdSquared = 0; + for (auto const& i: dist) + sdSquared += i.second * (i.first - mean) * (i.first - mean); + sdSquared /= total; + + if (sdSquared) + { + long double sd = sqrt(sdSquared.convert_to()); + long double normalizedSd = sd / mean.convert_to(); + + // calc octiles normalized to gaussian distribution + boost::math::normal gauss(1.0, (normalizedSd > 0.01) ? normalizedSd : 0.01); + for (size_t i = 1; i < 8; i++) + m_octiles[i] = u256(mean.convert_to() * boost::math::quantile(gauss, i / 8.0)); + m_octiles[8] = dist.rbegin()->first; + } + else + { + for (size_t i = 0; i < 9; i++) + m_octiles[i] = (i + 1) * mean / 5; + } + } +} diff --git a/libethereum/BasicGasPricer.h b/libethereum/BasicGasPricer.h new file mode 100644 index 000000000..77d4547c5 --- /dev/null +++ b/libethereum/BasicGasPricer.h @@ -0,0 +1,53 @@ +/* + 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 BasicGasPricer.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include +#include "GasPricer.h" + +namespace dev +{ +namespace eth +{ + +class BasicGasPricer: public GasPricer +{ +public: + explicit BasicGasPricer(u256 _weiPerRef, u256 _refsPerBlock): m_weiPerRef(_weiPerRef), m_refsPerBlock(_refsPerBlock) {} + + void setRefPrice(u256 _weiPerRef) { if ((bigint)m_refsPerBlock * _weiPerRef > std::numeric_limits::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_weiPerRef = _weiPerRef; } + void setRefBlockFees(u256 _refsPerBlock) { if ((bigint)m_weiPerRef * _refsPerBlock > std::numeric_limits::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_refsPerBlock = _refsPerBlock; } + + u256 ask(State const&) const override { return m_weiPerRef * m_refsPerBlock / m_gasPerBlock; } + u256 bid(TransactionPriority _p = TransactionPriority::Medium) const override { return m_octiles[(int)_p] > 0 ? m_octiles[(int)_p] : (m_weiPerRef * m_refsPerBlock / m_gasPerBlock); } + + void update(BlockChain const& _bc) override; + +private: + u256 m_weiPerRef; + u256 m_refsPerBlock; + u256 m_gasPerBlock = 3141592; + std::array m_octiles; +}; + +} +} diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index 4d05ea7db..d9a54a1ee 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -127,7 +127,7 @@ static const unsigned c_minCacheSize = 1024 * 1024 * 32; #endif -BlockChain::BlockChain(bytes const& _genesisBlock, std::string _path, WithExisting _we, ProgressCallback const& _p) +BlockChain::BlockChain(bytes const& _genesisBlock, std::string const& _path, WithExisting _we, ProgressCallback const& _p) { // initialise deathrow. m_cacheUsage.resize(c_collectionQueueSize); @@ -137,8 +137,7 @@ BlockChain::BlockChain(bytes const& _genesisBlock, std::string _path, WithExisti m_genesisBlock = _genesisBlock; m_genesisHash = sha3(RLP(m_genesisBlock)[0].data()); - open(_path, _we); - if (_we == WithExisting::Verify) + if (open(_path, _we) != c_minorProtocolVersion) rebuild(_path, _p); } @@ -147,24 +146,41 @@ BlockChain::~BlockChain() close(); } -void BlockChain::open(std::string const& _path, WithExisting _we) +unsigned BlockChain::open(std::string const& _path, WithExisting _we) { - std::string path = _path.empty() ? Defaults::get()->m_dbPath : _path; - boost::filesystem::create_directories(path); + string path = _path.empty() ? Defaults::get()->m_dbPath : _path; + string chainPath = path + "/" + toHex(m_genesisHash.ref().cropped(0, 4)); + string extrasPath = chainPath + "/" + toString(c_databaseVersion); + + boost::filesystem::create_directories(extrasPath); + + bytes status = contents(extrasPath + "/minor"); + unsigned lastMinor = c_minorProtocolVersion; + DEV_IGNORE_EXCEPTIONS(lastMinor = (unsigned)RLP(status)); + if (c_minorProtocolVersion != lastMinor) + { + cnote << "Killing extras database (DB minor version:" << lastMinor << " != our miner version: " << c_minorProtocolVersion << ")."; + DEV_IGNORE_EXCEPTIONS(boost::filesystem::remove_all(extrasPath + "/details.old")); + boost::filesystem::rename(extrasPath + "/extras", extrasPath + "/extras.old"); + boost::filesystem::remove_all(extrasPath + "/state"); + writeFile(extrasPath + "/minor", rlp(c_minorProtocolVersion)); + lastMinor = (unsigned)RLP(status); + } if (_we == WithExisting::Kill) { - boost::filesystem::remove_all(path + "/blocks"); - boost::filesystem::remove_all(path + "/details"); + cnote << "Killing blockchain & extras database (WithExisting::Kill)."; + boost::filesystem::remove_all(chainPath + "/blocks"); + boost::filesystem::remove_all(extrasPath + "/extras"); } ldb::Options o; o.create_if_missing = true; o.max_open_files = 256; - ldb::DB::Open(o, path + "/blocks", &m_blocksDB); - ldb::DB::Open(o, path + "/details", &m_extrasDB); + ldb::DB::Open(o, chainPath + "/blocks", &m_blocksDB); + ldb::DB::Open(o, extrasPath + "/extras", &m_extrasDB); if (!m_blocksDB || !m_extrasDB) { - if (boost::filesystem::space(path + "/blocks").available < 1024) + if (boost::filesystem::space(chainPath + "/blocks").available < 1024) { cwarn << "Not enough available space found on hard drive. Please free some up and then re-run. Bailing."; BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace()); @@ -176,6 +192,8 @@ void BlockChain::open(std::string const& _path, WithExisting _we) } } + m_writeOptions.sync = true; + if (_we != WithExisting::Verify && !details(m_genesisHash)) { // Insert details of genesis block. @@ -194,7 +212,8 @@ void BlockChain::open(std::string const& _path, WithExisting _we) m_lastBlockHash = l.empty() ? m_genesisHash : *(h256*)l.data(); m_lastBlockNumber = number(m_lastBlockHash); - cnote << "Opened blockchain DB. Latest: " << currentHash(); + cnote << "Opened blockchain DB. Latest: " << currentHash() << (lastMinor == c_minorProtocolVersion ? "(rebuild not needed)" : "*** REBUILD NEEDED ***"); + return lastMinor; } void BlockChain::close() @@ -208,11 +227,11 @@ void BlockChain::close() m_blocks.clear(); } -#define IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} - void BlockChain::rebuild(std::string const& _path, std::function const& _progress, bool _prepPoW) { - std::string path = _path.empty() ? Defaults::get()->m_dbPath : _path; + string path = _path.empty() ? Defaults::get()->m_dbPath : _path; + string chainPath = path + "/" + toHex(m_genesisHash.ref().cropped(0, 4)); + string extrasPath = chainPath + "/" + toString(c_databaseVersion); #if ETH_PROFILING_GPERF ProfilerStart("BlockChain_rebuild.log"); @@ -220,16 +239,21 @@ void BlockChain::rebuild(std::string const& _path, std::function BlockChain::sync(BlockQueue& _bq, OverlayDB c h256s fresh; h256s dead; h256s badBlocks; + Transactions goodTransactions; unsigned count = 0; for (VerifiedBlock const& block: blocks) if (!badBlocks.empty()) @@ -325,10 +350,11 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB c { // Nonce & uncle nonces already verified in verification thread at this point. ImportRoute r; - DEV_TIMED_ABOVE("Block import", 500) + DEV_TIMED_ABOVE("Block import " + toString(block.verified.info.number), 500) r = import(block.verified, _stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce & ~ImportRequirements::CheckUncles); fresh += r.liveBlocks; dead += r.deadBlocks; + goodTransactions += r.goodTranactions; ++count; } catch (dev::eth::UnknownParent) @@ -355,7 +381,7 @@ tuple BlockChain::sync(BlockQueue& _bq, OverlayDB c badBlocks.push_back(block.verified.info.hash()); } } - return make_tuple(ImportRoute{dead, fresh}, _bq.doneDrain(badBlocks), count); + return make_tuple(ImportRoute{dead, fresh, goodTransactions}, _bq.doneDrain(badBlocks), count); } pair BlockChain::attemptImport(bytes const& _block, OverlayDB const& _stateDB, ImportRequirements::value _ir) noexcept @@ -475,6 +501,7 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& BlockReceipts br; u256 td; + Transactions goodTransactions; #if ETH_CATCH try #endif @@ -488,6 +515,7 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& { blb.blooms.push_back(s.receipt(i).bloom()); br.receipts.push_back(s.receipt(i)); + goodTransactions.push_back(s.pending()[i]); } s.cleanup(true); @@ -728,7 +756,7 @@ ImportRoute BlockChain::import(VerifiedBlockRef const& _block, OverlayDB const& dead.push_back(h); else fresh.push_back(h); - return ImportRoute{dead, fresh}; + return ImportRoute{dead, fresh, move(goodTransactions)}; } void BlockChain::clearBlockBlooms(unsigned _begin, unsigned _end) @@ -773,6 +801,75 @@ void BlockChain::clearBlockBlooms(unsigned _begin, unsigned _end) } } +void BlockChain::rescue(OverlayDB& _db) +{ + cout << "Rescuing database..." << endl; + + unsigned u = 1; + while (true) + { + try { + if (isKnown(numberHash(u))) + u *= 2; + else + break; + } + catch (...) + { + break; + } + } + unsigned l = u / 2; + cout << "Finding last likely block number..." << endl; + while (u - l > 1) + { + unsigned m = (u + l) / 2; + cout << " " << m << flush; + if (isKnown(numberHash(m))) + l = m; + else + u = m; + } + cout << " lowest is " << l << endl; + for (;; --l) + { + h256 h = numberHash(l); + cout << "Checking validity of " << l << " (" << h << ")..." << flush; + try + { + cout << "block..." << flush; + BlockInfo bi = info(h); + cout << "details..." << flush; + BlockDetails bd = details(h); + cout << "state..." << flush; + if (_db.exists(bi.stateRoot)) + break; + } + catch (...) {} + } + cout << "OK." << endl; + rewind(l); +} + +void BlockChain::rewind(unsigned _newHead) +{ + DEV_WRITE_GUARDED(x_lastBlockHash) + { + if (_newHead >= m_lastBlockNumber) + return; + m_lastBlockHash = numberHash(_newHead); + m_lastBlockNumber = _newHead; + auto o = m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&m_lastBlockHash, 32)); + if (!o.ok()) + { + cwarn << "Error writing to extras database: " << o.ToString(); + cout << "Put" << toHex(bytesConstRef(ldb::Slice("best"))) << "=>" << toHex(bytesConstRef(ldb::Slice((char const*)&m_lastBlockHash, 32))); + cwarn << "Fail writing to extras database. Bombing out."; + exit(-1); + } + } +} + tuple BlockChain::treeRoute(h256 const& _from, h256 const& _to, bool _common, bool _pre, bool _post) const { // cdebug << "treeRoute" << _from << "..." << _to; @@ -845,33 +942,21 @@ template static unsigned getHashSize(unordered_map const& _ma void BlockChain::updateStats() const { - { - ReadGuard l(x_blocks); - m_lastStats.memBlocks = 0; + m_lastStats.memBlocks = 0; + DEV_READ_GUARDED(x_blocks) for (auto const& i: m_blocks) m_lastStats.memBlocks += i.second.size() + 64; - } - { - ReadGuard l(x_details); + DEV_READ_GUARDED(x_details) m_lastStats.memDetails = getHashSize(m_details); - } - { - ReadGuard l1(x_logBlooms); - ReadGuard l2(x_blocksBlooms); - m_lastStats.memLogBlooms = getHashSize(m_logBlooms) + getHashSize(m_blocksBlooms); - } - { - ReadGuard l(x_receipts); + DEV_READ_GUARDED(x_logBlooms) + DEV_READ_GUARDED(x_blocksBlooms) + m_lastStats.memLogBlooms = getHashSize(m_logBlooms) + getHashSize(m_blocksBlooms); + DEV_READ_GUARDED(x_receipts) m_lastStats.memReceipts = getHashSize(m_receipts); - } - { - ReadGuard l(x_blockHashes); + DEV_READ_GUARDED(x_blockHashes) m_lastStats.memBlockHashes = getHashSize(m_blockHashes); - } - { - ReadGuard l(x_transactionAddresses); + DEV_READ_GUARDED(x_transactionAddresses) m_lastStats.memTransactionAddresses = getHashSize(m_transactionAddresses); - } } void BlockChain::garbageCollect(bool _force) @@ -928,10 +1013,8 @@ void BlockChain::garbageCollect(bool _force) void BlockChain::checkConsistency() { - { - WriteGuard l(x_details); + DEV_WRITE_GUARDED(x_details) m_details.clear(); - } ldb::Iterator* it = m_blocksDB->NewIterator(m_readOptions); for (it->SeekToFirst(); it->Valid(); it->Next()) if (it->key().size() == 32) @@ -943,13 +1026,9 @@ void BlockChain::checkConsistency() { auto dp = details(p); if (asserts(contains(dp.children, h))) - { cnote << "Apparently the database is corrupt. Not much we can do at this stage..."; - } if (assertsEqual(dp.number, dh.number - 1)) - { cnote << "Apparently the database is corrupt. Not much we can do at this stage..."; - } } } delete it; @@ -1062,7 +1141,8 @@ bool BlockChain::isKnown(h256 const& _hash) const if (d.empty()) return false; } - return true; +// return true; + return details(_hash).number <= m_lastBlockNumber; // to allow rewind functionality. } bytes BlockChain::block(h256 const& _hash) const diff --git a/libethereum/BlockChain.h b/libethereum/BlockChain.h index 906608d35..638c9c3af 100644 --- a/libethereum/BlockChain.h +++ b/libethereum/BlockChain.h @@ -94,7 +94,7 @@ using ProgressCallback = std::function; class BlockChain { public: - BlockChain(bytes const& _genesisBlock, std::string _path, WithExisting _we, ProgressCallback const& _p = ProgressCallback()); + BlockChain(bytes const& _genesisBlock, std::string const& _path, WithExisting _we = WithExisting::Trust, ProgressCallback const& _p = ProgressCallback()); ~BlockChain(); /// Attempt a database re-open. @@ -142,6 +142,9 @@ public: BlockReceipts receipts(h256 const& _hash) const { return queryExtras(_hash, m_receipts, x_receipts, NullBlockReceipts); } BlockReceipts receipts() const { return receipts(currentHash()); } + /// Get the transaction receipt by transaction hash. Thread-safe. + TransactionReceipt transactionReceipt(h256 const& _transactionHash) const {TransactionAddress ta = queryExtras(_transactionHash, m_transactionAddresses, x_transactionAddresses, NullTransactionAddress); if (!ta) return bytesConstRef(); return receipts(ta.blockHash).receipts[ta.index]; } + /// Get a list of transaction hashes for a given block. Thread-safe. TransactionHashes transactionHashes(h256 const& _hash) const { auto b = block(_hash); RLP rlp(b); h256s ret; for (auto t: rlp[1]) ret.push_back(sha3(t.data())); return ret; } TransactionHashes transactionHashes() const { return transactionHashes(currentHash()); } @@ -212,6 +215,12 @@ public: /// 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(), bool _prepPoW = false); + /// Alter the head of the chain to some prior block along it. + void rewind(unsigned _newHead); + + /// Rescue the database. + void rescue(OverlayDB& _db); + /** @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 * blocks that are parent-to-child, then two sibling blocks, then a number of blocks that are child-to-parent; @@ -264,7 +273,7 @@ public: private: static h256 chunkId(unsigned _level, unsigned _index) { return h256(_index * 0xff + _level); } - void open(std::string const& _path, WithExisting _we = WithExisting::Trust); + unsigned open(std::string const& _path, WithExisting _we = WithExisting::Trust); void close(); template T queryExtras(h256 const& _h, std::unordered_map& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const diff --git a/libethereum/BlockChainSync.cpp b/libethereum/BlockChainSync.cpp index 63ac620ce..6aede0c16 100644 --- a/libethereum/BlockChainSync.cpp +++ b/libethereum/BlockChainSync.cpp @@ -38,7 +38,19 @@ using namespace dev; using namespace dev::eth; using namespace p2p; -unsigned const c_chainReorgSize = 30000; +unsigned const c_chainReorgSize = 30000; /// Added to estimated hashes to account for potential chain reorganiation +unsigned const c_hashSubchainSize = 8192; /// PV61 subchain size + +std::ostream& dev::eth::operator<<(std::ostream& _out, SyncStatus const& _sync) +{ + _out << "protocol: " << _sync.protocolVersion << endl; + _out << "state: " << EthereumHost::stateName(_sync.state) << " "; + if (_sync.state == SyncState::Hashes) + _out << _sync.hashesReceived << "/" << (_sync.hashesEstimated ? "~" : "") << _sync.hashesTotal; + if (_sync.state == SyncState::Blocks || _sync.state == SyncState::NewBlocks) + _out << _sync.blocksReceived << "/" << _sync.blocksTotal; + return _out; +} BlockChainSync::BlockChainSync(EthereumHost& _host): m_host(_host) @@ -68,22 +80,25 @@ DownloadMan& BlockChainSync::downloadMan() void BlockChainSync::abortSync() { - downloadMan().resetToChain(h256s()); + downloadMan().reset(); } void BlockChainSync::onPeerStatus(std::shared_ptr _peer) { RecursiveGuard l(x_sync); DEV_INVARIANT_CHECK; + std::shared_ptr session = _peer->session(); + if (!session) + return; // Expired if (_peer->m_genesisHash != host().chain().genesisHash()) _peer->disable("Invalid genesis hash"); else if (_peer->m_protocolVersion != host().protocolVersion() && _peer->m_protocolVersion != EthereumHost::c_oldProtocolVersion) _peer->disable("Invalid protocol version."); else if (_peer->m_networkId != host().networkId()) _peer->disable("Invalid network identifier."); - else if (_peer->session()->info().clientVersion.find("/v0.7.0/") != string::npos) + else if (session->info().clientVersion.find("/v0.7.0/") != string::npos) _peer->disable("Blacklisted client version."); - else if (host().isBanned(_peer->session()->id())) + else if (host().isBanned(session->id())) _peer->disable("Peer banned for previous bad behaviour."); else { @@ -91,7 +106,6 @@ void BlockChainSync::onPeerStatus(std::shared_ptr _peer) _peer->m_expectedHashes = hashes; onNewPeer(_peer); } - DEV_INVARIANT_CHECK; } unsigned BlockChainSync::estimatedHashes() const @@ -114,7 +128,6 @@ void BlockChainSync::requestBlocks(std::shared_ptr _peer) { clog(NetAllDetail) << "Waiting for block queue before downloading blocks"; pauseSync(); - _peer->setIdle(); return; } _peer->requestBlocks(); @@ -137,13 +150,14 @@ void BlockChainSync::logNewBlock(h256 const& _h) void BlockChainSync::onPeerBlocks(std::shared_ptr _peer, RLP const& _r) { RecursiveGuard l(x_sync); - DEV_INVARIANT_CHECK; unsigned itemCount = _r.itemCount(); clog(NetMessageSummary) << "Blocks (" << dec << itemCount << "entries)" << (itemCount ? "" : ": NoMoreBlocks"); - _peer->setIdle(); if (m_state != SyncState::Blocks && m_state != SyncState::NewBlocks && m_state != SyncState::Waiting) - clog(NetWarn) << "Unexpected Blocks received!"; + { + clog(NetMessageSummary) << "Ignoring unexpected blocks"; + return; + } if (m_state == SyncState::Waiting) { clog(NetAllDetail) << "Ignored blocks while waiting"; @@ -184,6 +198,7 @@ void BlockChainSync::onPeerBlocks(std::shared_ptr _peer, RLP const case ImportResult::BadChain: logNewBlock(h); _peer->disable("Malformed block received."); + restartSync(); return; case ImportResult::FutureTimeKnown: @@ -281,17 +296,22 @@ void BlockChainSync::onPeerNewBlock(std::shared_ptr _peer, RLP con case ImportResult::FutureTimeUnknown: case ImportResult::UnknownParent: + { logNewBlock(h); - clog(NetMessageSummary) << "Received block with no known parent. Resyncing..."; - resetSyncFor(_peer, h, _r[1].toInt()); + u256 totalDifficulty = _r[1].toInt(); + if (totalDifficulty > _peer->m_totalDifficulty) + { + clog(NetMessageDetail) << "Received block with no known parent. Resyncing..."; + resetSyncFor(_peer, h, totalDifficulty); + } break; + } default:; } DEV_GUARDED(_peer->x_knownBlocks) _peer->m_knownBlocks.insert(h); } - DEV_INVARIANT_CHECK; } PV60Sync::PV60Sync(EthereumHost& _host): @@ -305,6 +325,7 @@ SyncStatus PV60Sync::status() const RecursiveGuard l(x_sync); SyncStatus res; res.state = m_state; + res.protocolVersion = EthereumHost::c_oldProtocolVersion; if (m_state == SyncState::Hashes) { res.hashesTotal = m_estimatedHashes; @@ -344,26 +365,30 @@ void PV60Sync::restartSync() { resetSync(); host().bq().clear(); - if (isSyncing()) - transition(m_syncer.lock(), SyncState::Idle); + std::shared_ptr syncer = m_syncer.lock(); + if (syncer) + transition(syncer, SyncState::Idle); } void PV60Sync::completeSync() { - if (isSyncing()) - transition(m_syncer.lock(), SyncState::Idle); + std::shared_ptr syncer = m_syncer.lock(); + if (syncer) + transition(syncer, SyncState::Idle); } void PV60Sync::pauseSync() { - if (isSyncing()) - setState(m_syncer.lock(), SyncState::Waiting, true); + std::shared_ptr syncer = m_syncer.lock(); + if (syncer) + transition(syncer, SyncState::Waiting, true); } void PV60Sync::continueSync() { - if (isSyncing()) - transition(m_syncer.lock(), SyncState::Blocks); + std::shared_ptr syncer = m_syncer.lock(); + if (syncer) + transition(syncer, SyncState::Blocks); } void PV60Sync::onNewPeer(std::shared_ptr _peer) @@ -378,29 +403,12 @@ void PV60Sync::transition(std::shared_ptr _peer, SyncState _s, boo if (m_state == SyncState::Idle && _s != SyncState::Idle) _peer->m_requireTransactions = true; - RLPStream s; if (_s == SyncState::Hashes) { - if (m_state == SyncState::Idle) + if (m_state == SyncState::Idle || m_state == SyncState::Hashes) { - if (isSyncing(_peer)) - clog(NetWarn) << "Bad state: not asking for Hashes, yet syncing!"; - - m_syncingLatestHash = _peer->m_latestHash; - m_syncingTotalDifficulty = _peer->m_totalDifficulty; - setState(_peer, _s, true); - _peer->requestHashes(m_syncingLastReceivedHash ? m_syncingLastReceivedHash : m_syncingLatestHash); - DEV_INVARIANT_CHECK; - return; - } - else if (m_state == SyncState::Hashes) - { - if (!isSyncing(_peer)) - clog(NetWarn) << "Bad state: asking for Hashes yet not syncing!"; - - setState(_peer, _s, true); - _peer->requestHashes(m_syncingLastReceivedHash); - DEV_INVARIANT_CHECK; + m_estimatedHashes = _peer->m_expectedHashes - c_chainReorgSize; + syncHashes(_peer); return; } } @@ -462,7 +470,6 @@ void PV60Sync::transition(std::shared_ptr _peer, SyncState _s, boo } else if (_s == SyncState::Idle) { - host().foreachPeer([this](std::shared_ptr _p) { _p->setIdle(); return true; }); if (m_state == SyncState::Blocks || m_state == SyncState::NewBlocks) { clog(NetMessageDetail) << "Finishing blocks fetch..."; @@ -473,7 +480,6 @@ void PV60Sync::transition(std::shared_ptr _peer, SyncState _s, boo // NOTE: need to notify of giving up on chain-hashes, too, altering state as necessary. _peer->m_sub.doneFetch(); - _peer->setIdle(); setState(_peer, SyncState::Idle, false); } else if (m_state == SyncState::Hashes) @@ -502,7 +508,9 @@ void PV60Sync::setNeedsSyncing(std::shared_ptr _peer, h256 const& if (_peer->m_latestHash) noteNeedsSyncing(_peer); - _peer->session()->addNote("sync", string(isSyncing(_peer) ? "ongoing" : "holding") + (needsSyncing(_peer) ? " & needed" : "")); + shared_ptr session = _peer->session(); + if (session) + session->addNote("sync", string(isSyncing(_peer) ? "ongoing" : "holding") + (needsSyncing(_peer) ? " & needed" : "")); } bool PV60Sync::needsSyncing(std::shared_ptr _peer) const @@ -562,7 +570,6 @@ void PV60Sync::attemptSync(std::shared_ptr _peer) else { clog(NetAllDetail) << "Yes. Their chain is better."; - m_estimatedHashes = _peer->m_expectedHashes - c_chainReorgSize; transition(_peer, SyncState::Hashes); } } @@ -573,7 +580,9 @@ void PV60Sync::noteNeedsSyncing(std::shared_ptr _peer) if (isSyncing()) { clog(NetAllDetail) << "Sync in progress: Just set to help out."; - if (m_state == SyncState::Blocks) + if (m_state == SyncState::Hashes && _peer->m_asking == Asking::Nothing) + requestSubchain(_peer); + else if (m_state == SyncState::Blocks) requestBlocks(_peer); } else @@ -649,20 +658,45 @@ void PV60Sync::noteDoneBlocks(std::shared_ptr _peer, bool _clemenc } resetSync(); downloadMan().reset(); + } _peer->m_sub.doneFetch(); +} + +void PV60Sync::syncHashes(std::shared_ptr _peer) +{ + if (m_state == SyncState::Idle) + { + if (isSyncing(_peer)) + clog(NetWarn) << "Bad state: not asking for Hashes, yet syncing!"; + + m_syncingLatestHash = _peer->m_latestHash; + m_syncingTotalDifficulty = _peer->m_totalDifficulty; + setState(_peer, SyncState::Hashes, true); + _peer->requestHashes(m_syncingLastReceivedHash ? m_syncingLastReceivedHash : m_syncingLatestHash); + } + else if (m_state == SyncState::Hashes) + { + if (!isSyncing(_peer)) + clog(NetWarn) << "Bad state: asking for Hashes yet not syncing!"; + + setState(_peer, SyncState::Hashes, true); + _peer->requestHashes(m_syncingLastReceivedHash); } } void PV60Sync::onPeerHashes(std::shared_ptr _peer, h256s const& _hashes) { RecursiveGuard l(x_sync); - DEV_INVARIANT_CHECK; - _peer->setIdle(); if (!isSyncing(_peer)) { clog(NetMessageSummary) << "Ignoring hashes since not syncing"; return; } + if (_peer->m_syncHash != (m_syncingLastReceivedHash ? m_syncingLastReceivedHash : m_syncingLatestHash)) + { + clog(NetMessageSummary) << "Ignoring unexpected hashes"; + return; + } if (_hashes.size() == 0) { transition(_peer, SyncState::Blocks); @@ -684,7 +718,8 @@ void PV60Sync::onPeerHashes(std::shared_ptr _peer, h256s const& _h else if (status == QueueStatus::Bad) { cwarn << "block hash bad!" << h << ". Bailing..."; - transition(_peer, SyncState::Idle); + _peer->disable("Bad blocks"); + restartSync(); return; } else if (status == QueueStatus::Unknown) @@ -711,7 +746,6 @@ void PV60Sync::onPeerHashes(std::shared_ptr _peer, h256s const& _h void PV60Sync::onPeerNewHashes(std::shared_ptr _peer, h256s const& _hashes) { RecursiveGuard l(x_sync); - DEV_INVARIANT_CHECK; if (isSyncing() && (m_state != SyncState::NewBlocks || isSyncing(_peer))) { clog(NetMessageSummary) << "Ignoring since we're already downloading."; @@ -769,8 +803,33 @@ void PV60Sync::onPeerNewHashes(std::shared_ptr _peer, h256s const& void PV60Sync::abortSync() { // Can't check invariants here since the peers is already removed from the list and the state is not updated yet. - host().foreachPeer([this](std::shared_ptr _p) { _p->setIdle(); return true; }); - setState(std::shared_ptr(), SyncState::Idle, false, true); + bool continueSync = false; + if (m_state == SyncState::Blocks) + { + // Main syncer aborted, try to find a replacement + host().foreachPeer([&](std::shared_ptr _p) + { + if (_p->m_asking == Asking::Blocks) + { + setState(_p, SyncState::Blocks, true, true); // will kick off other peers to help if available. + continueSync = true; + return false; + } + if (_p->m_asking == Asking::Nothing && shouldGrabBlocks(_p)) + { + transition(_p, SyncState::Blocks); + clog(NetMessageDetail) << "New sync peer selected"; + continueSync = true; + return false; + } + return true; + }); + } + if (!continueSync) + { + // Just set to idle. Hashchain is keept, Sync will be continued if there are more peers to sync with + setState(std::shared_ptr(), SyncState::Idle, false, true); + } DEV_INVARIANT_CHECK; } @@ -778,45 +837,366 @@ void PV60Sync::onPeerAborting() { RecursiveGuard l(x_sync); // Can't check invariants here since the peers is already removed from the list and the state is not updated yet. - if (m_syncer.expired()) + if (m_syncer.expired() && m_state != SyncState::Idle) + { + clog(NetWarn) << "Syncing peer disconnected, restarting sync"; + m_syncer.reset(); abortSync(); + } DEV_INVARIANT_CHECK; } bool PV60Sync::invariants() const { if (m_state == SyncState::Idle && isSyncing()) - return false; + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Idle while peer syncing")); if (m_state != SyncState::Idle && !isSyncing()) - return false; + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Active while peer not syncing")); if (m_state == SyncState::Hashes) { - bool hashes = false; - host().foreachPeer([&](std::shared_ptr _p) { if (_p->m_asking == Asking::Hashes) hashes = true; return !hashes; }); - if (!hashes) - return false; if (!m_syncingLatestHash) - return false; + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("m_syncingLatestHash is not set while downloading hashes")); if (m_syncingNeededBlocks.empty() != (!m_syncingLastReceivedHash)) - return false; + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Received hashes but the hashes list is empty (or the other way around)")); } if (m_state == SyncState::Blocks || m_state == SyncState::NewBlocks) { - bool blocks = false; - host().foreachPeer([&](std::shared_ptr _p) { if (_p->m_asking == Asking::Blocks) blocks = true; return !blocks; }); - if (!blocks) - return false; if (downloadMan().isComplete()) - return false; + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Block download complete but the state is still Blocks")); + } + if (m_state == SyncState::Waiting && !host().bq().isActive()) + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Waiting while block queue is idle")); + return true; +} + +PV61Sync::PV61Sync(EthereumHost& _host): + PV60Sync(_host) +{ +} + +void PV61Sync::syncHashes(std::shared_ptr _peer) +{ + if (_peer->m_protocolVersion != host().protocolVersion()) + { + m_readyChainMap.clear(); + m_completeChainMap.clear(); + m_downloadingChainMap.clear(); + m_syncingBlockNumber = 0; + m_chainSyncPeers.clear(); + m_knownHashes.clear(); + m_hashScanComplete = false; + PV60Sync::syncHashes(_peer); + return; } if (m_state == SyncState::Idle) { - bool busy = false; - host().foreachPeer([&](std::shared_ptr _p) { if (_p->m_asking != Asking::Nothing && _p->m_asking != Asking::State) busy = true; return !busy; }); - if (busy) - return false; + if (isSyncing(_peer)) + clog(NetWarn) << "Bad state: not asking for Hashes, yet syncing!"; + + if (m_syncingBlockNumber == 0) + m_syncingBlockNumber = host().chain().number() + c_hashSubchainSize; + m_syncingTotalDifficulty = _peer->m_totalDifficulty; + setState(_peer, SyncState::Hashes, true); + _peer->requestHashes(m_syncingBlockNumber, 1); } - if (m_state == SyncState::Waiting && !host().bq().isActive()) - return false; + else if (m_state == SyncState::Hashes) + { + if (!isSyncing(_peer)) + clog(NetWarn) << "Bad state: asking for Hashes yet not syncing!"; + + m_syncingBlockNumber += c_hashSubchainSize; + setState(_peer, SyncState::Hashes, true); + _peer->requestHashes(m_syncingBlockNumber, 1); + } +} + +void PV61Sync::requestSubchain(std::shared_ptr _peer) +{ + auto syncPeer = m_chainSyncPeers.find(_peer); + if (syncPeer != m_chainSyncPeers.end()) + { + // Already downoading, request next batch + h256s& d = m_downloadingChainMap.at(syncPeer->second); + _peer->requestHashes(d.back()); + } + else if (needsSyncing(_peer)) + { + if (!m_readyChainMap.empty()) + { + clog(NetAllDetail) << "Helping with hashchin download"; + h256s& d = m_readyChainMap.begin()->second; + _peer->requestHashes(d.back()); + m_downloadingChainMap[m_readyChainMap.begin()->first] = move(d); + m_chainSyncPeers[_peer] = m_readyChainMap.begin()->first; + m_readyChainMap.erase(m_readyChainMap.begin()); + } + else if (!m_downloadingChainMap.empty() && m_hashScanComplete) + { + // Lead syncer is done, just grab whatever we can + h256s& d = m_downloadingChainMap.begin()->second; + _peer->requestHashes(d.back()); + } + } +} + +void PV61Sync::requestSubchains() +{ + host().foreachPeer([this](std::shared_ptr _p) + { + if (_p->m_asking == Asking::Nothing) + requestSubchain(_p); + return true; + }); +} + +void PV61Sync::completeSubchain(std::shared_ptr _peer, unsigned _n) +{ + m_completeChainMap[_n] = move(m_downloadingChainMap.at(_n)); + m_downloadingChainMap.erase(_n); + for (auto s = m_chainSyncPeers.begin(); s != m_chainSyncPeers.end(); ++s) + if (s->second == _n) //TODO: optimize this + { + m_chainSyncPeers.erase(s); + break; + } + + _peer->m_syncHashNumber = 0; + + auto syncer = m_syncer.lock(); + if (!syncer) + { + restartSync(); + return; + } + + if (m_readyChainMap.empty() && m_downloadingChainMap.empty() && m_hashScanComplete) + { + //Done chain-get + m_syncingNeededBlocks.clear(); + for (auto h = m_completeChainMap.rbegin(); h != m_completeChainMap.rend(); ++h) + m_syncingNeededBlocks.insert(m_syncingNeededBlocks.end(), h->second.begin(), h->second.end()); + m_completeChainMap.clear(); + m_knownHashes.clear(); + m_syncingBlockNumber = 0; + transition(syncer, SyncState::Blocks); + } + else + requestSubchain(_peer); +} + +void PV61Sync::restartSync() +{ + m_completeChainMap.clear(); + m_readyChainMap.clear(); + m_downloadingChainMap.clear(); + m_chainSyncPeers.clear(); + m_syncingBlockNumber = 0; + m_knownHashes.clear(); + m_hashScanComplete = false; + PV60Sync::restartSync(); +} + +void PV61Sync::onPeerHashes(std::shared_ptr _peer, h256s const& _hashes) +{ + RecursiveGuard l(x_sync); + if (m_syncingBlockNumber == 0 || (_peer == m_syncer.lock() && _peer->m_protocolVersion != host().protocolVersion())) + { + // Syncing in pv60 mode + PV60Sync::onPeerHashes(_peer, _hashes); + return; + } + if (_hashes.size() == 0) + { + if (isSyncing(_peer) && _peer->m_syncHashNumber == m_syncingBlockNumber) + { + // End of hash chain, add last chunk to download + m_readyChainMap.insert(make_pair(m_syncingBlockNumber, h256s { _peer->m_latestHash })); + m_hashScanComplete = true; + _peer->m_syncHashNumber = 0; + requestSubchain(_peer); + } + else + { + auto syncPeer = m_chainSyncPeers.find(_peer); + if (syncPeer == m_chainSyncPeers.end()) + clog(NetMessageDetail) << "Hashes response from unexpected peer"; + else + { + // Peer does not have request hashes, move back from downloading to ready + unsigned number = syncPeer->second; + m_chainSyncPeers.erase(_peer); + m_readyChainMap[number] = move(m_downloadingChainMap.at(number)); + m_downloadingChainMap.erase(number); + resetNeedsSyncing(_peer); + requestSubchains(); + } + } + return; + } + if (isSyncing(_peer) && _peer->m_syncHashNumber == m_syncingBlockNumber) + { + // Got new subchain marker + assert(_hashes.size() == 1); + m_knownHashes.insert(_hashes[0]); + m_readyChainMap.insert(make_pair(m_syncingBlockNumber, h256s { _hashes[0] })); + if ((m_readyChainMap.size() + m_downloadingChainMap.size() + m_completeChainMap.size()) * c_hashSubchainSize > _peer->m_expectedHashes) + { + _peer->disable("Too many hashes from lead peer"); + restartSync(); + return; + } + transition(_peer, SyncState::Hashes); + requestSubchains(); + } + else + { + auto syncPeer = m_chainSyncPeers.find(_peer); + unsigned number = 0; + if (syncPeer == m_chainSyncPeers.end()) + { + //check downlading peers + for (auto const& downloader: m_downloadingChainMap) + if (downloader.second.back() == _peer->m_syncHash) + { + number = downloader.first; + break; + } + } + else + number = syncPeer->second; + if (number == 0) + { + clog(NetAllDetail) << "Hashes response from unexpected/expired peer"; + return; + } + + auto downloadingPeer = m_downloadingChainMap.find(number); + if (downloadingPeer == m_downloadingChainMap.end() || downloadingPeer->second.back() != _peer->m_syncHash) + { + // Too late, other peer has already downloaded our hashes + m_chainSyncPeers.erase(_peer); + requestSubchain(_peer); + return; + } + + h256s& hashes = downloadingPeer->second; + unsigned knowns = 0; + unsigned unknowns = 0; + for (unsigned i = 0; i < _hashes.size(); ++i) + { + auto h = _hashes[i]; + auto status = host().bq().blockStatus(h); + if (status == QueueStatus::Importing || status == QueueStatus::Ready || host().chain().isKnown(h) || !!m_knownHashes.count(h)) + { + clog(NetMessageSummary) << "Subchain download complete"; + m_chainSyncPeers.erase(_peer); + completeSubchain(_peer, number); + return; + } + else if (status == QueueStatus::Bad) + { + cwarn << "block hash bad!" << h << ". Bailing..."; + _peer->disable("Bad hashes"); + if (isSyncing(_peer)) + restartSync(); + else + { + //try with other peer + m_readyChainMap[number] = move(m_downloadingChainMap.at(number)); + m_downloadingChainMap.erase(number); + m_chainSyncPeers.erase(_peer); + } + return; + } + else if (status == QueueStatus::Unknown) + { + unknowns++; + hashes.push_back(h); + } + else + knowns++; + } + clog(NetMessageSummary) << knowns << "knowns," << unknowns << "unknowns; now at" << hashes.back(); + if (hashes.size() > c_hashSubchainSize) + { + _peer->disable("Too many subchain hashes"); + restartSync(); + return; + } + requestSubchain(_peer); + } + DEV_INVARIANT_CHECK; +} + +void PV61Sync::onPeerAborting() +{ + RecursiveGuard l(x_sync); + // Can't check invariants here since the peers is already removed from the list and the state is not updated yet. + for (auto s = m_chainSyncPeers.begin(); s != m_chainSyncPeers.end();) + { + if (s->first.expired()) + { + unsigned number = s->second; + m_readyChainMap[number] = move(m_downloadingChainMap.at(number)); + m_downloadingChainMap.erase(number); + m_chainSyncPeers.erase(s++); + } + else + ++s; + } + if (m_syncer.expired()) + { + if (m_state == SyncState::Hashes) + { + // Main syncer aborted, other peers are probably still downloading hashes, just set one of them as syncer + host().foreachPeer([&](std::shared_ptr _p) + { + if (_p->m_asking != Asking::Hashes) + return true; + setState(_p, SyncState::Hashes, true, true); + return false; + }); + } + + if (m_syncer.expired()) + PV60Sync::onPeerAborting(); + } + else if (isPV61Syncing() && m_state == SyncState::Hashes) + requestSubchains(); + DEV_INVARIANT_CHECK; +} + +SyncStatus PV61Sync::status() const +{ + RecursiveGuard l(x_sync); + SyncStatus res = PV60Sync::status(); + res.protocolVersion = 61; + if (m_state == SyncState::Hashes && isPV61Syncing()) + { + res.hashesReceived = 0; + for (auto const& d : m_readyChainMap) + res.hashesReceived += d.second.size(); + for (auto const& d : m_downloadingChainMap) + res.hashesReceived += d.second.size(); + for (auto const& d : m_completeChainMap) + res.hashesReceived += d.second.size(); + } + return res; +} + +bool PV61Sync::isPV61Syncing() const +{ + return m_syncingBlockNumber != 0; +} + +bool PV61Sync::invariants() const +{ + if (m_state == SyncState::Hashes) + { + if (isPV61Syncing() && !m_syncingBlockNumber) + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment("Syncing in PV61 with no block number set")); + } + else if (!PV60Sync::invariants()) + return false; return true; } diff --git a/libethereum/BlockChainSync.h b/libethereum/BlockChainSync.h index 449dd49d1..6be17bc74 100644 --- a/libethereum/BlockChainSync.h +++ b/libethereum/BlockChainSync.h @@ -24,7 +24,6 @@ #include #include -#include #include #include #include "CommonNet.h" @@ -59,6 +58,9 @@ public: /// @returns true is Sync is in progress virtual bool isSyncing() const = 0; + /// Restart sync + virtual void restartSync() = 0; + /// Called by peer to report status virtual void onPeerStatus(std::shared_ptr _peer); @@ -93,9 +95,6 @@ protected: /// Resume downloading after witing state virtual void continueSync() = 0; - /// Restart sync - virtual void restartSync() = 0; - /// Called after all blocks have been donloaded virtual void completeSync() = 0; @@ -115,7 +114,7 @@ protected: void requestBlocks(std::shared_ptr _peer); protected: - Handler m_bqRoomAvailable; ///< Triggered once block queue + Handler<> m_bqRoomAvailable; ///< Triggered once block queue mutable RecursiveMutex x_sync; SyncState m_state = SyncState::Idle; ///< Current sync state unsigned m_estimatedHashes = 0; ///< Number of estimated hashes for the last peer over PV60. Used for status reporting only. @@ -132,8 +131,8 @@ private: /** - * @brief Syncrhonization over PV60. Selects a single peer and tries to downloading hashes from it. After hash downaload is complete - * Syncs to peers and keeps up to date + * @brief Syncrhonization over PV60. Selects a single peer and tries to downloading hashes from it. After hash download is complete + * syncs to peers and keeps up to date */ /** @@ -228,7 +227,7 @@ protected: void pauseSync() override; void resetSyncFor(std::shared_ptr _peer, h256 const& _latestHash, u256 const& _td) override; -private: +protected: /// Transition sync state in a particular direction. @param _peer Peer that is responsible for state tranfer void transition(std::shared_ptr _peer, SyncState _s, bool _force = false, bool _needHelp = true); @@ -262,6 +261,12 @@ private: /// Called when peer done downloading blocks void noteDoneBlocks(std::shared_ptr _who, bool _clemency); + /// Start chainhash sync + virtual void syncHashes(std::shared_ptr _peer); + + /// Request subchain, no-op for pv60 + virtual void requestSubchain(std::shared_ptr /*_peer*/) {} + /// Abort syncing void abortSync(); @@ -276,5 +281,43 @@ private: u256 m_syncingTotalDifficulty; ///< Latest block's total difficulty of the peer we aresyncing to, as of the current sync. std::weak_ptr m_syncer; ///< Peer we are currently syncing with }; + +/** + * @brief Syncrhonization over PV61. Selects a single peer and requests every c_hashSubchainSize hash, splitting the hashchain into subchains and downloading each subchain in parallel. + * Syncs to peers and keeps up to date + */ +class PV61Sync: public PV60Sync +{ +public: + PV61Sync(EthereumHost& _host); + +protected: + void restartSync() override; + void requestSubchain(std::shared_ptr _peer) override; + void syncHashes(std::shared_ptr _peer) override; + void onPeerHashes(std::shared_ptr _peer, h256s const& _hashes) override; + void onPeerAborting() override; + SyncStatus status() const override; + bool invariants() const override; + +private: + /// Called when subchain is complete. Check if if hashchain is fully downloaded and proceed to downloading blocks + void completeSubchain(std::shared_ptr _peer, unsigned _n); + /// Find a subchain for peers to downloading + void requestSubchains(); + /// Check if downloading hashes in parallel + bool isPV61Syncing() const; + + std::map m_completeChainMap; ///< Fully downloaded subchains + std::map m_readyChainMap; ///< Subchains ready for download + std::map m_downloadingChainMap; ///< Subchains currently being downloading. In sync with m_chainSyncPeers + std::map, unsigned, std::owner_less>> m_chainSyncPeers; ///< Peers to m_downloadingSubchain number map + h256Hash m_knownHashes; ///< Subchain start markers. Used to track suchain completion + unsigned m_syncingBlockNumber = 0; ///< Current subchain marker + bool m_hashScanComplete = false; ///< True if leading peer completed hashchain scan and we have a list of subchains ready +}; + +std::ostream& operator<<(std::ostream& _out, SyncStatus const& _sync); + } } diff --git a/libethereum/BlockDetails.h b/libethereum/BlockDetails.h index f1526b5fd..73026834e 100644 --- a/libethereum/BlockDetails.h +++ b/libethereum/BlockDetails.h @@ -59,7 +59,7 @@ struct BlockLogBlooms { BlockLogBlooms() {} BlockLogBlooms(RLP const& _r) { blooms = _r.toVector(); size = _r.data().size(); } - bytes rlp() const { RLPStream s; s << blooms; size = s.out().size(); return s.out(); } + bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; } LogBlooms blooms; mutable unsigned size; @@ -69,7 +69,7 @@ struct BlocksBlooms { BlocksBlooms() {} BlocksBlooms(RLP const& _r) { blooms = _r.toArray(); size = _r.data().size(); } - bytes rlp() const { RLPStream s; s << blooms; size = s.out().size(); return s.out(); } + bytes rlp() const { bytes r = dev::rlp(blooms); size = r.size(); return r; } std::array blooms; mutable unsigned size; diff --git a/libethereum/BlockQueue.cpp b/libethereum/BlockQueue.cpp index 074278d9a..f95a3880e 100644 --- a/libethereum/BlockQueue.cpp +++ b/libethereum/BlockQueue.cpp @@ -21,6 +21,7 @@ #include "BlockQueue.h" #include +#include #include #include #include @@ -114,15 +115,11 @@ void BlockQueue::verifierBody() 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.hash); - m_knownBad.insert(work.hash); - } - + // has to be this order as that's how invariants() assumes. + WriteGuard l2(m_lock); unique_lock l(m_verification); + m_readySet.erase(work.hash); + m_knownBad.insert(work.hash); for (auto it = m_verifying.begin(); it != m_verifying.end(); ++it) if (it->verified.info.mixHash == work.hash) { @@ -131,6 +128,7 @@ void BlockQueue::verifierBody() } cwarn << "BlockQueue missing our job: was there a GM?"; OK1:; + drainVerified_WITH_BOTH_LOCKS(); continue; } @@ -149,17 +147,8 @@ void BlockQueue::verifierBody() } else m_verified.emplace_back(move(res)); - while (m_verifying.size() && !m_verifying.front().blockData.empty()) - { - if (m_knownBad.count(m_verifying.front().verified.info.parentHash)) - { - m_readySet.erase(m_verifying.front().verified.info.hash()); - m_knownBad.insert(res.verified.info.hash()); - } - else - m_verified.emplace_back(move(m_verifying.front())); - m_verifying.pop_front(); - } + + drainVerified_WITH_BOTH_LOCKS(); ready = true; } else @@ -179,8 +168,24 @@ void BlockQueue::verifierBody() } } +void BlockQueue::drainVerified_WITH_BOTH_LOCKS() +{ + while (!m_verifying.empty() && !m_verifying.front().blockData.empty()) + { + if (m_knownBad.count(m_verifying.front().verified.info.parentHash)) + { + m_readySet.erase(m_verifying.front().verified.info.hash()); + m_knownBad.insert(m_verifying.front().verified.info.hash()); + } + else + m_verified.emplace_back(move(m_verifying.front())); + m_verifying.pop_front(); + } +} + ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, bool _isOurs) { + clog(BlockQueueTraceChannel) << std::this_thread::get_id(); // Check if we already know this block. h256 h = BlockInfo::headerHash(_block); @@ -210,8 +215,10 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo return ImportResult::Malformed; } + clog(BlockQueueTraceChannel) << "Block" << h << "is" << bi.number << "parent is" << bi.parentHash; + // Check block doesn't already exist first! - if (_bc.details(h)) + if (_bc.isKnown(h)) { cblockq << "Already known in chain."; return ImportResult::AlreadyInChain; @@ -242,7 +249,7 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo if (m_knownBad.count(bi.parentHash)) { m_knownBad.insert(bi.hash()); - updateBad(bi.hash()); + updateBad_WITH_LOCK(bi.hash()); // bad parent; this is bad too, note it as such return ImportResult::BadChain; } @@ -277,12 +284,12 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo } } -void BlockQueue::updateBad(h256 const& _bad) +void BlockQueue::updateBad_WITH_LOCK(h256 const& _bad) { DEV_INVARIANT_CHECK; DEV_GUARDED(m_verification) { - collectUnknownBad(_bad); + collectUnknownBad_WITH_BOTH_LOCKS(_bad); bool moreBad = true; while (moreBad) { @@ -294,7 +301,7 @@ void BlockQueue::updateBad(h256 const& _bad) { m_knownBad.insert(b.verified.info.hash()); m_readySet.erase(b.verified.info.hash()); - collectUnknownBad(b.verified.info.hash()); + collectUnknownBad_WITH_BOTH_LOCKS(b.verified.info.hash()); moreBad = true; } else @@ -307,7 +314,7 @@ void BlockQueue::updateBad(h256 const& _bad) { m_knownBad.insert(b.hash); m_readySet.erase(b.hash); - collectUnknownBad(b.hash); + collectUnknownBad_WITH_BOTH_LOCKS(b.hash); moreBad = true; } else @@ -321,17 +328,16 @@ void BlockQueue::updateBad(h256 const& _bad) h256 const& h = b.blockData.size() != 0 ? b.verified.info.hash() : b.verified.info.mixHash; m_knownBad.insert(h); m_readySet.erase(h); - collectUnknownBad(h); + collectUnknownBad_WITH_BOTH_LOCKS(h); moreBad = true; } else m_verifying.push_back(std::move(b)); } } - DEV_INVARIANT_CHECK; } -void BlockQueue::collectUnknownBad(h256 const& _bad) +void BlockQueue::collectUnknownBad_WITH_BOTH_LOCKS(h256 const& _bad) { list badQueue(1, _bad); while (!badQueue.empty()) @@ -349,7 +355,6 @@ void BlockQueue::collectUnknownBad(h256 const& _bad) } m_unknown.erase(r.first, r.second); } - } bool BlockQueue::doneDrain(h256s const& _bad) @@ -364,7 +369,7 @@ bool BlockQueue::doneDrain(h256s const& _bad) // at least one of them was bad. m_knownBad += _bad; for (h256 const& b : _bad) - updateBad(b); + updateBad_WITH_LOCK(b); } return !m_readySet.empty(); } @@ -471,7 +476,13 @@ void BlockQueue::drain(VerifiedBlocks& o_out, unsigned _max) bool BlockQueue::invariants() const { Guard l(m_verification); - return m_readySet.size() == m_verified.size() + m_unverified.size() + m_verifying.size(); + if (!(m_readySet.size() == m_verified.size() + m_unverified.size() + m_verifying.size())) + { + std::stringstream s; + s << "Failed BlockQueue invariant: m_readySet: " << m_readySet.size() << " m_verified: " << m_verified.size() << " m_unverified: " << m_unverified.size() << " m_verifying" << m_verifying.size(); + BOOST_THROW_EXCEPTION(FailedInvariant() << errinfo_comment(s.str())); + } + return true; } void BlockQueue::noteReady_WITH_LOCK(h256 const& _good) @@ -501,7 +512,6 @@ void BlockQueue::noteReady_WITH_LOCK(h256 const& _good) } if (notify) m_moreToVerify.notify_all(); - DEV_INVARIANT_CHECK; } void BlockQueue::retryAllUnknown() diff --git a/libethereum/BlockQueue.h b/libethereum/BlockQueue.h index 137048ec4..b9e6f5b3b 100644 --- a/libethereum/BlockQueue.h +++ b/libethereum/BlockQueue.h @@ -111,8 +111,8 @@ public: /// Get some infomration on the given block's status regarding us. QueueStatus blockStatus(h256 const& _h) const; - template Handler onReady(T const& _t) { return m_onReady.add(_t); } - template Handler onRoomAvailable(T const& _t) { return m_onRoomAvailable.add(_t); } + template Handler<> onReady(T const& _t) { return m_onReady.add(_t); } + template Handler<> onRoomAvailable(T const& _t) { return m_onRoomAvailable.add(_t); } template void setOnBad(T const& _t) { m_onBad = _t; } @@ -134,8 +134,9 @@ private: bool invariants() const override; void verifierBody(); - void collectUnknownBad(h256 const& _bad); - void updateBad(h256 const& _bad); + void collectUnknownBad_WITH_BOTH_LOCKS(h256 const& _bad); + void updateBad_WITH_LOCK(h256 const& _bad); + void drainVerified_WITH_BOTH_LOCKS(); mutable boost::shared_mutex m_lock; ///< General lock for the sets, m_future and m_unknown. h256Hash m_drainingSet; ///< All blocks being imported. @@ -144,8 +145,8 @@ private: 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. - Signal m_onRoomAvailable; ///< Called when space for new blocks becomes availabe after a drain. Be nice and exit fast. + Signal<> m_onReady; ///< Called when a subsequent call to import blocks will return a non-empty container. Be nice and exit fast. + Signal<> m_onRoomAvailable; ///< Called when space for new blocks becomes availabe after a drain. 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. diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index bfc825c0a..bddcf8d6c 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #if ETH_JSONRPC || !ETH_TRUE #include #include @@ -38,64 +37,97 @@ #include "Defaults.h" #include "Executive.h" #include "EthereumHost.h" +#include "Utility.h" using namespace std; using namespace dev; using namespace dev::eth; using namespace p2p; -VersionChecker::VersionChecker(string const& _dbPath): - m_path(_dbPath.size() ? _dbPath : Defaults::dbPath()) +std::ostream& dev::eth::operator<<(std::ostream& _out, ActivityReport const& _r) { - bytes statusBytes = contents(m_path + "/status"); - RLP status(statusBytes); - try - { - auto protocolVersion = (unsigned)status[0]; - (void)protocolVersion; - auto minorProtocolVersion = (unsigned)status[1]; - auto databaseVersion = (unsigned)status[2]; - h256 ourGenesisHash = CanonBlockChain::genesis().hash(); - auto genesisHash = status.itemCount() > 3 ? (h256)status[3] : ourGenesisHash; - - m_action = - databaseVersion != c_databaseVersion || genesisHash != ourGenesisHash ? - WithExisting::Kill - : minorProtocolVersion != eth::c_minorProtocolVersion ? - WithExisting::Verify - : - WithExisting::Trust; - } - catch (...) - { - m_action = WithExisting::Kill; - } + _out << "Since " << toString(_r.since) << " (" << std::chrono::duration_cast(std::chrono::system_clock::now() - _r.since).count(); + _out << "): " << _r.ticks << "ticks"; + return _out; +} + +#ifdef _WIN32 +const char* ClientNote::name() { return EthTeal "^" EthBlue " i"; } +const char* ClientChat::name() { return EthTeal "^" EthWhite " o"; } +const char* ClientTrace::name() { return EthTeal "^" EthGray " O"; } +const char* ClientDetail::name() { return EthTeal "^" EthCoal " 0"; } +#else +const char* ClientNote::name() { return EthTeal "⧫" EthBlue " ℹ"; } +const char* ClientChat::name() { return EthTeal "⧫" EthWhite " ◌"; } +const char* ClientTrace::name() { return EthTeal "⧫" EthGray " ◎"; } +const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; } +#endif + +static const Addresses c_canaries = +{ + Address("4bb7e8ae99b645c2b7860b8f3a2328aae28bd80a"), // gav + Address("1baf27b88c48dd02b744999cf3522766929d2b2a"), // vitalik + Address("a8edb1ac2c86d3d9d78f96cd18001f60df29e52c"), // jeff + Address("ace7813896a84d3f5f80223916a5353ab16e46e6") // christoph +}; + +VersionChecker::VersionChecker(string const& _dbPath) +{ + upgradeDatabase(_dbPath); } -void VersionChecker::setOk() +Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): + Client(_extNet, make_shared(), _dbPath, _forceAction, _networkId) { - if (m_action != WithExisting::Trust) - { - try - { - boost::filesystem::create_directory(m_path); - } - catch (...) - { - cwarn << "Unhandled exception! Failed to create directory: " << m_path << "\n" << boost::current_exception_diagnostic_information(); - } - writeFile(m_path + "/status", rlpList(eth::c_protocolVersion, eth::c_minorProtocolVersion, c_databaseVersion, CanonBlockChain::genesis().hash())); - } + startWorking(); +} + +Client::Client(p2p::Host* _extNet, std::shared_ptr _gp, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): + Worker("eth", 0), + m_vc(_dbPath), + m_bc(_dbPath, _forceAction, [](unsigned d, unsigned t){ cerr << "REVISING BLOCKCHAIN: Processed " << d << " of " << t << "...\r"; }), + m_gp(_gp), + m_stateDB(State::openDB(_dbPath, _forceAction)), + m_preMine(m_stateDB, BaseState::CanonGenesis), + m_postMine(m_stateDB) +{ + if (_forceAction == WithExisting::Rescue) + m_bc.rescue(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_bq.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); + m_bc.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); + m_farm.onSolutionFound([=](ProofOfWork::Solution const& s){ return this->submitWork(s); }); + + m_gp->update(m_bc); + + auto host = _extNet->registerCapability(new EthereumHost(m_bc, m_tq, m_bq, _networkId)); + m_host = host; + _extNet->addCapability(host, EthereumHost::staticName(), EthereumHost::c_oldProtocolVersion); //TODO: remove this one v61+ protocol is common + + if (_dbPath.size()) + Defaults::setDBPath(_dbPath); + doWork(); + + startWorking(); +} + +Client::~Client() +{ + stopWorking(); } ImportResult Client::queueBlock(bytes const& _block, bool _isSafe) { - if (m_bq.status().verified + m_bq.status().verifying + m_bq.status().unverified > 30000) + if (m_bq.status().verified + m_bq.status().verifying + m_bq.status().unverified > 10000) this_thread::sleep_for(std::chrono::milliseconds(500)); return m_bq.import(&_block, bc(), _isSafe); } tuple Client::syncQueue(unsigned _max) { + stopWorking(); return m_bc.sync(m_bq, m_stateDB, _max); } @@ -210,144 +242,18 @@ void Client::onBadBlock(Exception& _ex) const #endif } -void BasicGasPricer::update(BlockChain const& _bc) -{ - unsigned c = 0; - h256 p = _bc.currentHash(); - m_gasPerBlock = _bc.info(p).gasLimit; - - map dist; - u256 total = 0; - - // make gasPrice versus gasUsed distribution for the last 1000 blocks - while (c < 1000 && p) - { - BlockInfo bi = _bc.info(p); - if (bi.transactionsRoot != EmptyTrie) - { - auto bb = _bc.block(p); - RLP r(bb); - BlockReceipts brs(_bc.receipts(bi.hash())); - size_t i = 0; - for (auto const& tr: r[1]) - { - Transaction tx(tr.data(), CheckTransaction::None); - u256 gu = brs.receipts[i].gasUsed(); - dist[tx.gasPrice()] += gu; - total += gu; - i++; - } - } - p = bi.parentHash; - ++c; - } - - // fill m_octiles with weighted gasPrices - if (total > 0) - { - m_octiles[0] = dist.begin()->first; - - // calc mean - u256 mean = 0; - for (auto const& i: dist) - mean += i.first * i.second; - mean /= total; - - // calc standard deviation - u256 sdSquared = 0; - for (auto const& i: dist) - sdSquared += i.second * (i.first - mean) * (i.first - mean); - sdSquared /= total; - - if (sdSquared) - { - long double sd = sqrt(sdSquared.convert_to()); - long double normalizedSd = sd / mean.convert_to(); - - // calc octiles normalized to gaussian distribution - boost::math::normal gauss(1.0, (normalizedSd > 0.01) ? normalizedSd : 0.01); - for (size_t i = 1; i < 8; i++) - m_octiles[i] = u256(mean.convert_to() * boost::math::quantile(gauss, i / 8.0)); - m_octiles[8] = dist.rbegin()->first; - } - else - { - for (size_t i = 0; i < 9; i++) - m_octiles[i] = (i + 1) * mean / 5; - } - } -} - -std::ostream& dev::eth::operator<<(std::ostream& _out, ActivityReport const& _r) -{ - _out << "Since " << toString(_r.since) << " (" << std::chrono::duration_cast(std::chrono::system_clock::now() - _r.since).count(); - _out << "): " << _r.ticks << "ticks"; - return _out; -} - -#ifdef _WIN32 -const char* ClientNote::name() { return EthTeal "^" EthBlue " i"; } -const char* ClientChat::name() { return EthTeal "^" EthWhite " o"; } -const char* ClientTrace::name() { return EthTeal "^" EthGray " O"; } -const char* ClientDetail::name() { return EthTeal "^" EthCoal " 0"; } -#else -const char* ClientNote::name() { return EthTeal "⧫" EthBlue " ℹ"; } -const char* ClientChat::name() { return EthTeal "⧫" EthWhite " ◌"; } -const char* ClientTrace::name() { return EthTeal "⧫" EthGray " ◎"; } -const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; } -#endif - -Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): - Client(_extNet, make_shared(), _dbPath, _forceAction, _networkId) -{ - startWorking(); -} - -Client::Client(p2p::Host* _extNet, std::shared_ptr _gp, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId): - 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(_gp), - m_stateDB(State::openDB(_dbPath, max(m_vc.action(), _forceAction))), - 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_bq.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); - m_bc.setOnBad([=](Exception& ex){ this->onBadBlock(ex); }); - m_farm.onSolutionFound([=](ProofOfWork::Solution const& s){ return this->submitWork(s); }); - - m_gp->update(m_bc); - - auto host = _extNet->registerCapability(new EthereumHost(m_bc, m_tq, m_bq, _networkId)); - m_host = host; - _extNet->addCapability(host, EthereumHost::staticName(), EthereumHost::c_oldProtocolVersion); //TODO: remove this one v61+ protocol is common - - if (_dbPath.size()) - Defaults::setDBPath(_dbPath); - m_vc.setOk(); - doWork(); - - startWorking(); -} - -Client::~Client() -{ - stopWorking(); -} - -static const Address c_canary("0x"); - bool Client::isChainBad() const { - return stateAt(c_canary, 0) != 0; + unsigned numberBad = 0; + for (auto const& a: c_canaries) + if (!!stateAt(a, 0)) + numberBad++; + return numberBad >= 2; } bool Client::isUpgradeNeeded() const { - return stateAt(c_canary, 0) == 2; + return stateAt(c_canaries[0], 0) == 2; } void Client::setNetworkId(u256 _n) @@ -701,7 +607,7 @@ void Client::onDeadBlocks(h256s const& _blocks, h256Hash& io_changed) for (auto const& t: m_bc.transactions(h)) { clog(ClientTrace) << "Resubmitting dead-block transaction " << Transaction(t, CheckTransaction::None); - m_tq.import(t, TransactionQueue::ImportCallback(), IfDropped::Retry); + m_tq.import(t, IfDropped::Retry); } } @@ -713,14 +619,7 @@ void Client::onNewBlocks(h256s const& _blocks, h256Hash& io_changed) { // remove transactions from m_tq nicely rather than relying on out of date nonce later on. for (auto const& h: _blocks) - { clog(ClientTrace) << "Live block:" << h; - for (auto const& th: m_bc.transactionHashes(h)) - { - clog(ClientTrace) << "Safely dropping transaction " << th; - m_tq.drop(th); - } - } if (auto h = m_host.lock()) h->noteNewBlocks(); @@ -756,7 +655,7 @@ void Client::restartMining() for (auto const& t: m_postMine.pending()) { clog(ClientTrace) << "Resubmitting post-mine transaction " << t; - auto ir = m_tq.import(t, TransactionQueue::ImportCallback(), IfDropped::Retry); + auto ir = m_tq.import(t, IfDropped::Retry); if (ir != ImportResult::Success) onTransactionQueueReady(); } @@ -776,6 +675,11 @@ void Client::onChainChanged(ImportRoute const& _ir) { h256Hash changeds; onDeadBlocks(_ir.deadBlocks, changeds); + for (auto const& t: _ir.goodTranactions) + { + clog(ClientTrace) << "Safely dropping transaction " << t.sha3(); + m_tq.dropGood(t); + } onNewBlocks(_ir.liveBlocks, changeds); restartMining(); noteChanged(changeds); @@ -805,7 +709,7 @@ void Client::rejigMining() { clog(ClientTrace) << "Rejigging mining..."; DEV_WRITE_GUARDED(x_working) - m_working.commitToMine(m_bc); + m_working.commitToMine(m_bc, m_extraData); DEV_READ_GUARDED(x_working) { DEV_WRITE_GUARDED(x_postMine) diff --git a/libethereum/Client.h b/libethereum/Client.h index aa118054f..3bb9b8a8c 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -64,33 +64,6 @@ class VersionChecker { public: VersionChecker(std::string const& _dbPath); - - void setOk(); - WithExisting action() const { return m_action; } - -private: - WithExisting m_action; - std::string m_path; -}; - -class BasicGasPricer: public GasPricer -{ -public: - explicit BasicGasPricer(u256 _weiPerRef, u256 _refsPerBlock): m_weiPerRef(_weiPerRef), m_refsPerBlock(_refsPerBlock) {} - - void setRefPrice(u256 _weiPerRef) { if ((bigint)m_refsPerBlock * _weiPerRef > std::numeric_limits::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_weiPerRef = _weiPerRef; } - void setRefBlockFees(u256 _refsPerBlock) { if ((bigint)m_weiPerRef * _refsPerBlock > std::numeric_limits::max() ) BOOST_THROW_EXCEPTION(Overflow() << errinfo_comment("ether price * block fees is larger than 2**256-1, choose a smaller number.") ); else m_refsPerBlock = _refsPerBlock; } - - u256 ask(State const&) const override { return m_weiPerRef * m_refsPerBlock / m_gasPerBlock; } - u256 bid(TransactionPriority _p = TransactionPriority::Medium) const override { return m_octiles[(int)_p] > 0 ? m_octiles[(int)_p] : (m_weiPerRef * m_refsPerBlock / m_gasPerBlock); } - - void update(BlockChain const& _bc) override; - -private: - u256 m_weiPerRef; - u256 m_refsPerBlock; - u256 m_gasPerBlock = 3141592; - std::array m_octiles; }; struct ClientNote: public LogChannel { static const char* name(); static const int verbosity = 2; }; @@ -240,6 +213,12 @@ public: ActivityReport activityReport() { ActivityReport ret; std::swap(m_report, ret); return ret; } /// Set a JSONRPC server to which we can report bad blocks. void setSentinel(std::string const& _server) { m_sentinel = _server; } + /// Get the JSONRPC server to which we report bad blocks. + std::string const& sentinel() const { return m_sentinel; } + /// Set the extra data that goes into mined blocks. + void setExtraData(bytes const& _extraData) { m_extraData = _extraData; } + /// Rewind to a prior head. + void rewind(unsigned _n) { m_bc.rewind(_n); } protected: /// InterfaceStub methods @@ -342,10 +321,10 @@ private: GenericFarm m_farm; ///< Our mining farm. - Handler m_tqReady; - Handler m_bqReady; + Handler<> m_tqReady; + Handler<> m_bqReady; - bool m_wouldMine = false; ///< True if we /should/ be mining. + bool m_wouldMine = false; ///< True if we /should/ be mining. bool m_turboMining = false; ///< Don't squander all of our time mining actually just sleeping. bool m_forceMining = false; ///< Mine even when there are no transactions pending? bool m_mineOnBadChain = false; ///< Mine even when the canary says it's a bad chain. @@ -366,6 +345,7 @@ private: std::atomic m_syncBlockQueue = {false}; std::string m_sentinel; + bytes m_extraData; }; } diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 4f50234e6..f9a213881 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -45,48 +45,21 @@ State ClientBase::asOf(BlockNumber _h) const return asOf(bc().numberHash(_h)); } -void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, u256 _nonce) -{ - prepareForTransaction(); - - Transaction t(_value, _gasPrice, _gas, _dest, _data, _nonce, _secret); - m_tq.import(t.rlp()); - - StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged()); - cnote << "New transaction " << t; -} - -Address ClientBase::submitTransaction(Secret _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, u256 _nonce) -{ - prepareForTransaction(); - - Transaction t(_value, _gasPrice, _gas, _data, _nonce, _secret); - m_tq.import(t.rlp()); - - StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged()); - cnote << "New transaction " << t; - - return right160(sha3(rlpList(t.sender(), t.nonce()))); -} - -void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) -{ - auto a = toAddress(_secret); - submitTransaction(_secret, _value, _dest, _data, _gas, _gasPrice, max(postMine().transactionsFrom(a), m_tq.maxNonce(a))); -} - -Address ClientBase::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) +pair ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) { prepareForTransaction(); - u256 n = postMine().transactionsFrom(toAddress(_secret)); - Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); - m_tq.import(t.rlp()); + TransactionSkeleton ts(_t); + ts.from = toAddress(_secret); + if (_t.nonce == UndefinedU256) + ts.nonce = max(postMine().transactionsFrom(ts.from), m_tq.maxNonce(ts.from)); + Transaction t(ts, _secret); + m_tq.import(t.rlp()); StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged()); cnote << "New transaction " << t; - return right160(sha3(rlpList(t.sender(), t.nonce()))); + return make_pair(t.sha3(), toAddress(ts.from, ts.nonce)); } // TODO: remove try/catch, allow exceptions @@ -354,6 +327,11 @@ Transaction ClientBase::transaction(h256 _blockHash, unsigned _i) const return Transaction(); } +TransactionReceipt ClientBase::transactionReceipt(h256 const& _transactionHash) const +{ + return bc().transactionReceipt(_transactionHash); +} + pair ClientBase::transactionLocation(h256 const& _transactionHash) const { return bc().transactionLocation(_transactionHash); @@ -481,7 +459,7 @@ int ClientBase::compareBlockHashes(h256 _h1, h256 _h2) const return -1; } -bool ClientBase::isKnown(h256 _hash) const +bool ClientBase::isKnown(h256 const& _hash) const { return _hash == PendingBlockHash || _hash == LatestBlockHash || @@ -496,7 +474,7 @@ bool ClientBase::isKnown(BlockNumber _block) const bc().numberHash(_block) != h256(); } -bool ClientBase::isKnownTransaction(h256 _transactionHash) const +bool ClientBase::isKnownTransaction(h256 const& _transactionHash) const { return bc().isKnownTransaction(_transactionHash); } diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index aac10ae60..82f03def0 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -75,14 +75,9 @@ public: ClientBase() {} virtual ~ClientBase() {} - /// Submits the given message-call transaction. - virtual void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, u256 _nonce); - virtual void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo) override; - - /// Submits a new contract-creation transaction. - /// @returns the new contract's address (assuming it all goes through). - virtual Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, u256 _nonce); - virtual Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo) override; + /// Submits the given transaction. + /// @returns the new transaction's hash. + virtual std::pair submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override; using Interface::submitTransaction; /// Makes the given call. Nothing is recorded into the state. @@ -124,6 +119,7 @@ public: virtual BlockDetails blockDetails(h256 _hash) const override; virtual Transaction transaction(h256 _transactionHash) const override; virtual Transaction transaction(h256 _blockHash, unsigned _i) const override; + virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const override; virtual std::pair transactionLocation(h256 const& _transactionHash) const override; virtual Transactions transactions(h256 _blockHash) const override; virtual TransactionHashes transactionHashes(h256 _blockHash) const override; @@ -149,9 +145,9 @@ public: /// Get the coinbase address virtual Address address() const override; - virtual bool isKnown(h256 _hash) const override; + virtual bool isKnown(h256 const& _hash) const override; virtual bool isKnown(BlockNumber _block) const override; - virtual bool isKnownTransaction(h256 _transactionHash) const override; + virtual bool isKnownTransaction(h256 const& _transactionHash) const override; /// TODO: consider moving it to a separate interface diff --git a/libethereum/CommonNet.h b/libethereum/CommonNet.h index 35a27ff5e..d03e04d85 100644 --- a/libethereum/CommonNet.h +++ b/libethereum/CommonNet.h @@ -91,6 +91,7 @@ enum class SyncState struct SyncStatus { SyncState state = SyncState::Idle; + unsigned protocolVersion = 0; unsigned hashesTotal = 0; unsigned hashesReceived = 0; bool hashesEstimated = false; diff --git a/libethereum/DownloadMan.cpp b/libethereum/DownloadMan.cpp index 5e68e3c49..a9d353292 100644 --- a/libethereum/DownloadMan.cpp +++ b/libethereum/DownloadMan.cpp @@ -24,6 +24,16 @@ using namespace std; using namespace dev; using namespace dev::eth; +DownloadMan::Overview DownloadMan::overview() const +{ + ReadGuard l(m_lock); + Overview ret; + ret.firstIncomplete = m_blocksGot.firstOut(); + ret.lastComplete = ret.lastStarted = m_blocksGot.lastIn();// TODO: lastStarted properly + ret.total = m_blocksGot.size(); + return ret; +} + DownloadSub::DownloadSub(DownloadMan& _man): m_man(&_man) { WriteGuard l(m_man->x_subs); diff --git a/libethereum/DownloadMan.h b/libethereum/DownloadMan.h index ac99e1d36..b697d87ae 100644 --- a/libethereum/DownloadMan.h +++ b/libethereum/DownloadMan.h @@ -82,6 +82,14 @@ class DownloadMan friend class DownloadSub; public: + struct Overview + { + size_t total; + size_t firstIncomplete; + size_t lastComplete; + size_t lastStarted; + }; + ~DownloadMan() { for (auto i: m_subs) @@ -97,11 +105,9 @@ public: void resetToChain(h256s const& _chain) { - { - ReadGuard l(x_subs); + DEV_READ_GUARDED(x_subs) for (auto i: m_subs) i->resetFetch(); - } WriteGuard l(m_lock); m_chain.clear(); m_chain.reserve(_chain.size()); @@ -112,11 +118,9 @@ public: void reset() { - { - ReadGuard l(x_subs); + DEV_READ_GUARDED(x_subs) for (auto i: m_subs) i->resetFetch(); - } WriteGuard l(m_lock); m_chain.clear(); m_blocksGot.reset(); @@ -127,11 +131,9 @@ public: ReadGuard l(m_lock); auto ret = m_blocksGot; if (!_desperate) - { - ReadGuard l(x_subs); - for (auto i: m_subs) - ret += i->m_asked; - } + DEV_READ_GUARDED(x_subs) + for (auto i: m_subs) + ret += i->m_asked; return ret; } @@ -144,12 +146,15 @@ public: h256s remaining() const { h256s ret; - ReadGuard l(m_lock); - for (auto i: m_blocksGot.inverted()) - ret.push_back(m_chain[i]); + DEV_READ_GUARDED(m_lock) + for (auto i: m_blocksGot.inverted()) + ret.push_back(m_chain[i]); return ret; } + h256 firstBlock() const { return m_chain.empty() ? h256() : m_chain[0]; } + Overview overview() const; + size_t chainSize() const { ReadGuard l(m_lock); return m_chain.size(); } size_t chainEmpty() const { ReadGuard l(m_lock); return m_chain.empty(); } void foreachSub(std::function const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); } diff --git a/libethereum/EthereumHost.cpp b/libethereum/EthereumHost.cpp index 9980f4339..f8ad742f8 100644 --- a/libethereum/EthereumHost.cpp +++ b/libethereum/EthereumHost.cpp @@ -41,9 +41,16 @@ using namespace dev::eth; using namespace p2p; unsigned const EthereumHost::c_oldProtocolVersion = 60; //TODO: remove this once v61+ is common +static unsigned const c_maxSendTransactions = 256; char const* const EthereumHost::s_stateNames[static_cast(SyncState::Size)] = {"Idle", "Waiting", "Hashes", "Blocks", "NewBlocks" }; +#ifdef _WIN32 +const char* EthereumHostTrace::name() { return EthPurple "^" EthGray " "; } +#else +const char* EthereumHostTrace::name() { return EthPurple "⧫" EthGray " "; } +#endif + EthereumHost::EthereumHost(BlockChain const& _ch, TransactionQueue& _tq, BlockQueue& _bq, u256 _networkId): HostCapability(), Worker ("ethsync"), @@ -53,6 +60,7 @@ EthereumHost::EthereumHost(BlockChain const& _ch, TransactionQueue& _tq, BlockQu m_networkId (_networkId) { m_latestBlockSent = _ch.currentHash(); + m_tq.onImport([this](ImportResult _ir, h256 const& _h, h512 const& _nodeId) { onTransactionImported(_ir, _h, _nodeId); }); } EthereumHost::~EthereumHost() @@ -65,10 +73,10 @@ bool EthereumHost::ensureInitialised() { // First time - just initialise. m_latestBlockSent = m_chain.currentHash(); - clog(NetNote) << "Initialising: latest=" << m_latestBlockSent; + clog(EthereumHostTrace) << "Initialising: latest=" << m_latestBlockSent; - for (auto const& i: m_tq.transactions()) - m_transactionsSent.insert(i.first); + Guard l(x_transactions); + m_transactionsSent = m_tq.knownTransactions(); return true; } return false; @@ -80,8 +88,10 @@ void EthereumHost::reset() if (m_sync) m_sync->abortSync(); m_sync.reset(); + m_syncStart = 0; m_latestBlockSent = h256(); + Guard tl(x_transactions); m_transactionsSent.clear(); } @@ -106,6 +116,21 @@ void EthereumHost::doWork() foreachPeer([](std::shared_ptr _p) { _p->tick(); return true; }); + if (m_syncStart) + { + DEV_GUARDED(x_sync) + if (!m_sync) + { + time_t now = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); + if (now - m_syncStart > 10) + { + m_sync.reset(new PV60Sync(*this)); + m_syncStart = 0; + m_sync->restartSync(); + } + } + } + // return netChange; // TODO: Figure out what to do with netChange. (void)netChange; @@ -114,25 +139,29 @@ void EthereumHost::doWork() void EthereumHost::maintainTransactions() { // Send any new transactions. - unordered_map, h256s> peerTransactions; - auto ts = m_tq.transactions(); - for (auto const& i: ts) + unordered_map, std::vector> peerTransactions; + auto ts = m_tq.topTransactions(c_maxSendTransactions); { - bool unsent = !m_transactionsSent.count(i.first); - auto peers = get<1>(randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(i.first)); })); - for (auto const& p: peers) - peerTransactions[p].push_back(i.first); + Guard l(x_transactions); + for (size_t i = 0; i < ts.size(); ++i) + { + auto const& t = ts[i]; + bool unsent = !m_transactionsSent.count(t.sha3()); + auto peers = get<1>(randomSelection(0, [&](EthereumPeer* p) { return p->m_requireTransactions || (unsent && !p->m_knownTransactions.count(t.sha3())); })); + for (auto const& p: peers) + peerTransactions[p].push_back(i); + } + for (auto const& t: ts) + m_transactionsSent.insert(t.sha3()); } - for (auto const& t: ts) - m_transactionsSent.insert(t.first); foreachPeer([&](shared_ptr _p) { bytes b; unsigned n = 0; - for (auto const& h: peerTransactions[_p]) + for (auto const& i: peerTransactions[_p]) { - _p->m_knownTransactions.insert(h); - b += ts[h].rlp(); + _p->m_knownTransactions.insert(ts[i].sha3()); + b += ts[i].rlp(); ++n; } @@ -143,7 +172,7 @@ void EthereumHost::maintainTransactions() RLPStream ts; _p->prep(ts, TransactionsPacket, n).appendRaw(b, n); _p->sealAndSend(ts); - cnote << "Sent" << n << "transactions to " << _p->session()->info().clientVersion; + clog(EthereumHostTrace) << "Sent" << n << "transactions to " << _p->session()->info().clientVersion; } _p->m_requireTransactions = false; return true; @@ -199,11 +228,15 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) if (diff(detailsFrom.number, detailsTo.number) < 20) { // don't be sending more than 20 "new" blocks. if there are any more we were probably waaaay behind. - clog(NetMessageSummary) << "Sending a new block (current is" << _currentHash << ", was" << m_latestBlockSent << ")"; + clog(EthereumHostTrace) << "Sending a new block (current is" << _currentHash << ", was" << m_latestBlockSent << ")"; h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true)); - auto s = randomSelection(25, [&](EthereumPeer* p){ DEV_GUARDED(p->x_knownBlocks) return !p->m_knownBlocks.count(_currentHash); return false; }); + auto s = randomSelection(25, [&](EthereumPeer* p){ + DEV_GUARDED(p->x_knownBlocks) + return !p->m_knownBlocks.count(_currentHash); + return false; + }); for (shared_ptr const& p: get<0>(s)) for (auto const& b: blocks) { @@ -230,10 +263,10 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash) } } -BlockChainSync& EthereumHost::sync() +BlockChainSync* EthereumHost::sync() { if (m_sync) - return *m_sync; // We only chose sync strategy once + return m_sync.get(); // We only chose sync strategy once bool pv61 = false; foreachPeer([&](std::shared_ptr _p) @@ -242,78 +275,76 @@ BlockChainSync& EthereumHost::sync() pv61 = true; return !pv61; }); - m_sync.reset(pv61 ? new PV60Sync(*this) : new PV60Sync(*this)); - return *m_sync; + if (pv61) + { + m_syncStart = 0; + m_sync.reset(new PV61Sync(*this)); + } + else if (!m_syncStart) + m_syncStart = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); + + return m_sync.get(); } void EthereumHost::onPeerStatus(std::shared_ptr _peer) { Guard l(x_sync); - sync().onPeerStatus(_peer); + if (sync()) + sync()->onPeerStatus(_peer); } void EthereumHost::onPeerHashes(std::shared_ptr _peer, h256s const& _hashes) { Guard l(x_sync); - sync().onPeerHashes(_peer, _hashes); + if (sync()) + sync()->onPeerHashes(_peer, _hashes); } void EthereumHost::onPeerBlocks(std::shared_ptr _peer, RLP const& _r) { Guard l(x_sync); - sync().onPeerBlocks(_peer, _r); + if (sync()) + sync()->onPeerBlocks(_peer, _r); } void EthereumHost::onPeerNewHashes(std::shared_ptr _peer, h256s const& _hashes) { Guard l(x_sync); - sync().onPeerNewHashes(_peer, _hashes); + if (sync()) + sync()->onPeerNewHashes(_peer, _hashes); } void EthereumHost::onPeerNewBlock(std::shared_ptr _peer, RLP const& _r) { Guard l(x_sync); - sync().onPeerNewBlock(_peer, _r); + if (sync()) + sync()->onPeerNewBlock(_peer, _r); } void EthereumHost::onPeerTransactions(std::shared_ptr _peer, RLP const& _r) { if (_peer->isCriticalSyncing()) { - clog(NetAllDetail) << "Ignoring transaction from peer we are syncing with"; + clog(EthereumHostTrace) << "Ignoring transaction from peer we are syncing with"; return; } unsigned itemCount = _r.itemCount(); - clog(NetAllDetail) << "Transactions (" << dec << itemCount << "entries)"; - Guard l(_peer->x_knownTransactions); - for (unsigned i = 0; i < min(itemCount, 256); ++i) // process 256 transactions at most. TODO: much better solution. - { - auto h = sha3(_r[i].data()); - _peer->m_knownTransactions.insert(h); - ImportResult ir = m_tq.import(_r[i].data()); - switch (ir) - { - case ImportResult::Malformed: - _peer->addRating(-100); - break; - case ImportResult::AlreadyKnown: - // if we already had the transaction, then don't bother sending it on. - m_transactionsSent.insert(h); - _peer->addRating(0); - break; - case ImportResult::Success: - _peer->addRating(100); - break; - default:; - } - } + clog(EthereumHostTrace) << "Transactions (" << dec << itemCount << "entries)"; + m_tq.enqueue(_r, _peer->session()->id()); } void EthereumHost::onPeerAborting() { Guard l(x_sync); - if (m_sync) - m_sync->onPeerAborting(); + try + { + if (m_sync) + m_sync->onPeerAborting(); + } + catch (Exception&) + { + cwarn << "Exception on peer destruciton: " << boost::current_exception_diagnostic_information(); + } } bool EthereumHost::isSyncing() const @@ -331,3 +362,35 @@ SyncStatus EthereumHost::status() const return SyncStatus(); return m_sync->status(); } + +void EthereumHost::onTransactionImported(ImportResult _ir, h256 const& _h, h512 const& _nodeId) +{ + auto session = host()->peerSession(_nodeId); + if (!session) + return; + + std::shared_ptr peer = session->cap(); + if (!peer) + peer = session->cap(c_oldProtocolVersion); + if (!peer) + return; + + Guard l(peer->x_knownTransactions); + peer->m_knownTransactions.insert(_h); + switch (_ir) + { + case ImportResult::Malformed: + peer->addRating(-100); + break; + case ImportResult::AlreadyKnown: + // if we already had the transaction, then don't bother sending it on. + DEV_GUARDED(x_transactions) + m_transactionsSent.insert(_h); + peer->addRating(0); + break; + case ImportResult::Success: + peer->addRating(100); + break; + default:; + } +} diff --git a/libethereum/EthereumHost.h b/libethereum/EthereumHost.h index 182c3d4cd..9afaa8413 100644 --- a/libethereum/EthereumHost.h +++ b/libethereum/EthereumHost.h @@ -31,7 +31,6 @@ #include #include -#include #include #include #include "CommonNet.h" @@ -50,6 +49,8 @@ class TransactionQueue; class BlockQueue; class BlockChainSync; +struct EthereumHostTrace: public LogChannel { static const char* name(); static const int verbosity = 6; }; + /** * @brief The EthereumHost class * @warning None of this is thread-safe. You have been warned. @@ -106,6 +107,7 @@ private: void maintainTransactions(); void maintainBlocks(h256 const& _currentBlock); + void onTransactionImported(ImportResult _ir, h256 const& _h, h512 const& _nodeId); /// Check to see if the network peer-state initialisation has happened. bool isInitialised() const { return (bool)m_latestBlockSent; } @@ -116,7 +118,7 @@ private: virtual void onStarting() override { startWorking(); } virtual void onStopping() override { stopWorking(); } - BlockChainSync& sync(); + BlockChainSync* sync(); BlockChain const& m_chain; TransactionQueue& m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. @@ -133,8 +135,10 @@ private: bool m_newBlocks = false; mutable Mutex x_sync; + mutable Mutex x_transactions; DownloadMan m_man; std::unique_ptr m_sync; + std::atomic m_syncStart = { 0 }; }; } diff --git a/libethereum/EthereumPeer.cpp b/libethereum/EthereumPeer.cpp index 88878334c..3b7a72b63 100644 --- a/libethereum/EthereumPeer.cpp +++ b/libethereum/EthereumPeer.cpp @@ -86,7 +86,7 @@ unsigned EthereumPeer::askOverride() const if (s->info().clientVersion.substr(0, badGeth.size()) == badGeth) return 1; bytes const& d = repMan().data(*s, name()); - return d.empty() ? c_maxBlocksAsk : RLP(d).toInt(RLP::LaisezFaire); + return d.empty() ? c_maxBlocksAsk : RLP(d).toInt(RLP::LaissezFaire); } void EthereumPeer::setRude() @@ -127,20 +127,19 @@ void EthereumPeer::requestStatus() m_requireTransactions = true; RLPStream s; bool latest = m_peerCapabilityVersion == host()->protocolVersion(); - prep(s, StatusPacket, latest ? 6 : 5) + prep(s, StatusPacket, 5) << (latest ? host()->protocolVersion() : EthereumHost::c_oldProtocolVersion) << host()->networkId() << host()->chain().details().totalDifficulty << host()->chain().currentHash() << host()->chain().genesisHash(); - if (latest) - s << u256(host()->chain().number()); sealAndSend(s); } void EthereumPeer::requestHashes(u256 _number, unsigned _count) { assert(m_asking == Asking::Nothing); + assert(m_protocolVersion == host()->protocolVersion()); m_syncHashNumber = _number; m_syncHash = h256(); setAsking(Asking::Hashes); @@ -198,7 +197,7 @@ void EthereumPeer::requestBlocks() void EthereumPeer::setAsking(Asking _a) { m_asking = _a; - m_lastAsk = chrono::system_clock::now(); + m_lastAsk = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); auto s = session(); if (s) @@ -211,7 +210,8 @@ void EthereumPeer::setAsking(Asking _a) void EthereumPeer::tick() { auto s = session(); - if (s && (chrono::system_clock::now() - m_lastAsk > chrono::seconds(10) && m_asking != Asking::Nothing)) + time_t now = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); + if (s && (now - m_lastAsk > 10 && m_asking != Asking::Nothing)) // timeout s->disconnect(PingTimeout); } @@ -228,6 +228,7 @@ bool EthereumPeer::isCriticalSyncing() const bool EthereumPeer::interpret(unsigned _id, RLP const& _r) { + m_lastAsk = std::chrono::system_clock::to_time_t(chrono::system_clock::now()); try { switch (_id) @@ -240,21 +241,10 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) m_latestHash = _r[3].toHash(); m_genesisHash = _r[4].toHash(); if (m_peerCapabilityVersion == host()->protocolVersion()) - { - if (_r.itemCount() != 6) - { - clog(NetImpolite) << "Peer does not support PV61+ status extension."; - m_protocolVersion = EthereumHost::c_oldProtocolVersion; - } - else - { - m_protocolVersion = host()->protocolVersion(); - m_latestBlockNumber = _r[5].toInt(); - } - } + m_protocolVersion = host()->protocolVersion(); - clog(NetMessageSummary) << "Status:" << m_protocolVersion << "/" << m_networkId << "/" << m_genesisHash << "/" << m_latestBlockNumber << ", TD:" << m_totalDifficulty << "=" << m_latestHash; - setAsking(Asking::Nothing); + clog(NetMessageSummary) << "Status:" << m_protocolVersion << "/" << m_networkId << "/" << m_genesisHash << ", TD:" << m_totalDifficulty << "=" << m_latestHash; + setIdle(); host()->onPeerStatus(dynamic_pointer_cast(dynamic_pointer_cast(shared_from_this()))); break; } @@ -311,6 +301,7 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) clog(NetWarn) << "Peer giving us hashes when we didn't ask for them."; break; } + setIdle(); h256s hashes(itemCount); for (unsigned i = 0; i < itemCount; ++i) hashes[i] = _r[i].toHash(); @@ -357,7 +348,10 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) if (m_asking != Asking::Blocks) clog(NetImpolite) << "Peer giving us blocks when we didn't ask for them."; else + { + setIdle(); host()->onPeerBlocks(dynamic_pointer_cast(shared_from_this()), _r); + } break; } case NewBlockPacket: @@ -381,9 +375,9 @@ bool EthereumPeer::interpret(unsigned _id, RLP const& _r) return false; } } - catch (Exception const& _e) + catch (Exception const&) { - clog(NetWarn) << "Peer causing an Exception:" << _e.what() << _r; + clog(NetWarn) << "Peer causing an Exception:" << boost::current_exception_diagnostic_information() << _r; } catch (std::exception const& _e) { diff --git a/libethereum/EthereumPeer.h b/libethereum/EthereumPeer.h index d506ffb3f..23d52b346 100644 --- a/libethereum/EthereumPeer.h +++ b/libethereum/EthereumPeer.h @@ -31,7 +31,6 @@ #include #include -#include #include #include #include "CommonNet.h" @@ -136,14 +135,12 @@ private: /// What, if anything, we last asked the other peer for. Asking m_asking = Asking::Nothing; /// When we asked for it. Allows a time out. - std::chrono::system_clock::time_point m_lastAsk; + std::atomic m_lastAsk; /// These are determined through either a Status message or from NewBlock. h256 m_latestHash; ///< Peer's latest block's hash that we know about or default null value if no need to sync. u256 m_totalDifficulty; ///< Peer's latest block's total difficulty. h256 m_genesisHash; ///< Peer's genesis hash - u256 m_latestBlockNumber; ///< Number of the latest block this peer has - /// This is built as we ask for hashes. Once no more hashes are given, we present this to the /// host who initialises the DownloadMan and m_sub becomes active for us to begin asking for blocks. diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 02e263ab1..866c9c8f9 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -153,6 +153,11 @@ u256 Executive::gasUsed() const return m_t.gas() - m_gas; } +u256 Executive::gasUsedNoRefunds() const +{ + return m_t.gas() - m_gas + m_refunded; +} + void Executive::accrueSubState(SubState& _parentContext) { if (m_ext) @@ -391,8 +396,8 @@ void Executive::finalize() // SSTORE refunds... // must be done before the miner gets the fees. - if (m_ext) - m_gas += min((m_t.gas() - m_gas) / 2, m_ext->sub.refunds); + m_refunded = m_ext ? min((m_t.gas() - m_gas) / 2, m_ext->sub.refunds) : 0; + m_gas += m_refunded; // cnote << "Refunding" << formatBalance(m_endGas * m_ext->gasPrice) << "to origin (=" << m_endGas << "*" << formatBalance(m_ext->gasPrice) << ")"; m_s.addBalance(m_t.sender(), m_gas * m_t.gasPrice()); diff --git a/libethereum/Executive.h b/libethereum/Executive.h index 41a8d1961..78a7a8bb5 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -53,7 +53,7 @@ public: std::string json(bool _styled = false) const; - OnOpFunc onOp() { return [&](uint64_t _steps, Instruction _inst, bigint _newMemSize, bigint _gasCost, bigint _gas, VM* _vm, ExtVMFace const* _extVM) { (*this)(_steps, _inst, _newMemSize, _gasCost, _gas, _vm, _extVM); }; } + OnOpFunc onOp() { return [=](uint64_t _steps, Instruction _inst, bigint _newMemSize, bigint _gasCost, bigint _gas, VM* _vm, ExtVMFace const* _extVM) { (*this)(_steps, _inst, _newMemSize, _gasCost, _gas, _vm, _extVM); }; } private: bool m_showMnemonics = false; @@ -110,6 +110,9 @@ public: /// @returns total gas used in the transaction/operation. /// @warning Only valid after finalise(). u256 gasUsed() const; + /// @returns total gas used in the transaction/operation, excluding anything refunded. + /// @warning Only valid after finalise(). + u256 gasUsedNoRefunds() const; /// Set up the executive for evaluating a bare CREATE (contract-creation) operation. /// @returns false iff go() must be called (and thus a VM execution in required). @@ -154,6 +157,7 @@ private: bool m_isCreation = false; ///< True if the transaction creates a contract, or if create() is called. TransactionException m_excepted = TransactionException::None; ///< Details if the VM's execution resulted in an exception. u256 m_gas = 0; ///< The gas for EVM code execution. Initial amount before go() execution, final amount after go() execution. + u256 m_refunded = 0; ///< The amount of gas refunded. Transaction m_t; ///< The original transaction. Set by setup(). LogEntries m_logs; ///< The log entries created by this transaction. Set by finalize(). diff --git a/libethereum/ExtVM.cpp b/libethereum/ExtVM.cpp index 305462511..903bf627c 100644 --- a/libethereum/ExtVM.cpp +++ b/libethereum/ExtVM.cpp @@ -33,13 +33,21 @@ namespace static unsigned const c_depthLimit = 1024; /// Upper bound of stack space needed by single CALL/CREATE execution. Set experimentally. -static size_t const c_singleExecutionStackSize = 12 * 1024; +static size_t const c_singleExecutionStackSize = +#ifdef NDEBUG + 12 * 1024; +#else + 33 * 1024; +#endif /// Standard OSX thread stack limit. Should be reasonable for other platforms too. static size_t const c_defaultStackSize = 512 * 1024; +/// Stack overhead prior to allocation. +static size_t const c_entryOverhead = 128 * 1024; + /// On what depth execution should be offloaded to additional separated stack space. -static unsigned const c_offloadPoint = c_defaultStackSize / c_singleExecutionStackSize; +static unsigned const c_offloadPoint = (c_defaultStackSize - c_entryOverhead) / c_singleExecutionStackSize; void goOnOffloadedStack(Executive& _e, OnOpFunc const& _onOp) { @@ -68,8 +76,9 @@ void go(unsigned _depth, Executive& _e, OnOpFunc const& _onOp) { // If in the offloading point we need to switch to additional separated stack space. // Current stack is too small to handle more CALL/CREATE executions. - // It needs to be done only once as newly allocated stack space it enough to handle + // It needs to be done only once as newly allocated stack space it enough to handle // the rest of the calls up to the depth limit (c_depthLimit). + if (_depth == c_offloadPoint) goOnOffloadedStack(_e, _onOp); else @@ -82,7 +91,11 @@ bool ExtVM::call(CallParameters& _p) Executive e(m_s, lastHashes, depth + 1); if (!e.call(_p, gasPrice, origin)) { + #if __clang__ // Enabled for clang only as the problem affects OSX go(depth, e, _p.onOp); + #else + e.go(_p.onOp); + #endif e.accrueSubState(sub); } _p.gas = e.gas(); @@ -104,4 +117,3 @@ h160 ExtVM::create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc io_gas = e.gas(); return e.newAddress(); } - diff --git a/libethereum/GasPricer.cpp b/libethereum/GasPricer.cpp new file mode 100644 index 000000000..21f061afc --- /dev/null +++ b/libethereum/GasPricer.cpp @@ -0,0 +1,26 @@ +/* + 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 GasPricer.cpp + * @author Gav Wood + * @date 2015 + */ + +#include "GasPricer.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; diff --git a/libethereum/GasPricer.h b/libethereum/GasPricer.h new file mode 100644 index 000000000..f0fc6b520 --- /dev/null +++ b/libethereum/GasPricer.h @@ -0,0 +1,74 @@ +/* + 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 GasPricer.h + * @author Gav Wood + * @date 2014 + */ + +#pragma once + +#include + +namespace dev +{ +namespace eth +{ + +class State; +class BlockChain; + +enum class TransactionPriority +{ + Lowest = 0, + Low = 2, + Medium = 4, + High = 6, + Highest = 8 +}; + +class GasPricer +{ +public: + GasPricer() = default; + virtual ~GasPricer() = default; + + virtual u256 ask(State const&) const = 0; + virtual u256 bid(TransactionPriority _p = TransactionPriority::Medium) const = 0; + + virtual void update(BlockChain const&) {} +}; + +class TrivialGasPricer: public GasPricer +{ +public: + TrivialGasPricer() = default; + TrivialGasPricer(u256 const& _ask, u256 const& _bid): m_ask(_ask), m_bid(_bid) {} + + void setAsk(u256 const& _ask) { m_ask = _ask; } + void setBid(u256 const& _bid) { m_bid = _bid; } + + u256 ask() const { return m_ask; } + u256 ask(State const&) const override { return m_ask; } + u256 bid(TransactionPriority = TransactionPriority::Medium) const override { return m_bid; } + +private: + u256 m_ask = 10 * szabo; + u256 m_bid = 10 * szabo; +}; + +} +} diff --git a/libethereum/Interface.cpp b/libethereum/Interface.cpp index 545604d90..e95e03a45 100644 --- a/libethereum/Interface.cpp +++ b/libethereum/Interface.cpp @@ -20,6 +20,31 @@ */ #include "Interface.h" +using namespace std; +using namespace dev; +using namespace eth; -#pragma GCC diagnostic ignored "-Wunused-variable" -namespace { char dummy; } +void Interface::submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data, u256 const& _gas, u256 const& _gasPrice, u256 const& _nonce) +{ + TransactionSkeleton ts; + ts.creation = false; + ts.value = _value; + ts.to = _dest; + ts.data = _data; + ts.gas = _gas; + ts.gasPrice = _gasPrice; + ts.nonce = _nonce; + submitTransaction(ts, _secret); +} + +Address Interface::submitTransaction(Secret const& _secret, u256 const& _endowment, bytes const& _init, u256 const& _gas, u256 const& _gasPrice, u256 const& _nonce) +{ + TransactionSkeleton ts; + ts.creation = true; + ts.value = _endowment; + ts.data = _init; + ts.gas = _gas; + ts.gasPrice = _gasPrice; + ts.nonce = _nonce; + return submitTransaction(ts, _secret).second; +} diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 1073b45ff..973433af9 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -65,16 +65,16 @@ public: // [TRANSACTION API] - /// Submits the given message-call transaction. - virtual void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo) = 0; + /// Submits a new transaction. + /// @returns the transaction's hash. + virtual std::pair submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0; - /// Submits a new contract-creation transaction. - /// @returns the new contract's address (assuming it all goes through). - virtual Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo) = 0; + /// Submits the given message-call transaction. + void submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data = bytes(), u256 const& _gas = 10000, u256 const& _gasPrice = 10 * szabo, u256 const& _nonce = UndefinedU256); /// Submits a new contract-creation transaction. /// @returns the new contract's address (assuming it all goes through). - Address submitTransaction(Secret const& _secret, TransactionSkeleton const& _t) { if (_t.creation) return submitTransaction(_secret, _t.value, _t.data, _t.gas, _t.gasPrice); submitTransaction(_secret, _t.value, _t.to, _t.data, _t.gas, _t.gasPrice); return Address(); } + Address submitTransaction(Secret const& _secret, u256 const& _endowment, bytes const& _init, u256 const& _gas = 10000, u256 const& _gasPrice = 10 * szabo, u256 const& _nonce = UndefinedU256); /// Blocks until all pending transactions have been processed. virtual void flushTransactions() = 0; @@ -133,15 +133,16 @@ public: // [BLOCK QUERY API] - virtual bool isKnownTransaction(h256 _transactionHash) const = 0; + virtual bool isKnownTransaction(h256 const& _transactionHash) const = 0; virtual Transaction transaction(h256 _transactionHash) const = 0; + virtual TransactionReceipt transactionReceipt(h256 const& _transactionHash) const = 0; virtual std::pair transactionLocation(h256 const& _transactionHash) const = 0; virtual h256 hashFromNumber(BlockNumber _number) const = 0; virtual BlockNumber numberFromHash(h256 _blockHash) const = 0; virtual int compareBlockHashes(h256 _h1, h256 _h2) const = 0; virtual bool isKnown(BlockNumber _block) const = 0; - virtual bool isKnown(h256 _hash) const = 0; + virtual bool isKnown(h256 const& _hash) const = 0; virtual BlockInfo blockInfo(h256 _hash) const = 0; virtual BlockDetails blockDetails(h256 _hash) const = 0; virtual Transaction transaction(h256 _blockHash, unsigned _i) const = 0; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 19640b09e..10d637509 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -38,37 +38,44 @@ #include "Executive.h" #include "CachedAddressState.h" #include "CanonBlockChain.h" +#include "TransactionQueue.h" using namespace std; using namespace dev; using namespace dev::eth; +namespace fs = boost::filesystem; #define ctrace clog(StateTrace) #define ETH_TIMED_ENACTMENTS 0 static const u256 c_blockReward = c_network == Network::Olympic ? (1500 * finney) : (5 * ether); +static const unsigned c_maxSyncTransactions = 256; const char* StateSafeExceptions::name() { return EthViolet "⚙" EthBlue " ℹ"; } const char* StateDetail::name() { return EthViolet "⚙" EthWhite " ◌"; } const char* StateTrace::name() { return EthViolet "⚙" EthGray " ◎"; } const char* StateChat::name() { return EthViolet "⚙" EthWhite " ◌"; } -OverlayDB State::openDB(std::string _path, WithExisting _we) +OverlayDB State::openDB(std::string const& _basePath, WithExisting _we) { - if (_path.empty()) - _path = Defaults::get()->m_dbPath; - boost::filesystem::create_directory(_path); + std::string path = _basePath.empty() ? Defaults::get()->m_dbPath : _basePath; if (_we == WithExisting::Kill) - boost::filesystem::remove_all(_path + "/state"); + { + cnote << "Killing state database (WithExisting::Kill)."; + boost::filesystem::remove_all(path + "/state"); + } + + path += "/" + toHex(CanonBlockChain::genesis().hash().ref().cropped(0, 4)) + "/" + toString(c_databaseVersion); + boost::filesystem::create_directories(path); ldb::Options o; o.max_open_files = 256; o.create_if_missing = true; ldb::DB* db = nullptr; - ldb::DB::Open(o, _path + "/state", &db); + ldb::DB::Open(o, path + "/state", &db); if (!db) { - if (boost::filesystem::space(_path + "/state").available < 1024) + if (boost::filesystem::space(path + "/state").available < 1024) { cwarn << "Not enough available space found on hard drive. Please free some up and then re-run. Bailing."; BOOST_THROW_EXCEPTION(NotEnoughAvailableSpace()); @@ -438,7 +445,8 @@ u256 State::enactOn(VerifiedBlockRef const& _block, BlockChain const& _bc, Impor #if ETH_TIMED_ENACTMENTS enactment = t.elapsed(); - cnote << "popVer/popGrand/syncReset/enactment = " << populateVerify << "/" << populateGrand << "/" << syncReset << "/" << enactment; + if (populateVerify + populateGrand + syncReset + enactment > 0.5) + clog(StateChat) << "popVer/popGrand/syncReset/enactment = " << populateVerify << "/" << populateGrand << "/" << syncReset << "/" << enactment; #endif return ret; } @@ -490,7 +498,7 @@ pair State::sync(BlockChain const& _bc, TransactionQu pair ret; ret.second = false; - auto ts = _tq.transactions(); + auto ts = _tq.topTransactions(c_maxSyncTransactions); LastHashes lh; @@ -499,27 +507,25 @@ pair State::sync(BlockChain const& _bc, TransactionQu for (int goodTxs = 1; goodTxs; ) { goodTxs = 0; - for (auto const& i: ts) - if (!m_transactionSet.count(i.first)) + for (auto const& t: ts) + if (!m_transactionSet.count(t.sha3())) { try { - if (i.second.gasPrice() >= _gp.ask(*this)) + if (t.gasPrice() >= _gp.ask(*this)) { - // Timer t; +// Timer t; if (lh.empty()) lh = _bc.lastHashes(); - execute(lh, i.second); + execute(lh, t); ret.first.push_back(m_receipts.back()); - _tq.noteGood(i); ++goodTxs; - // cnote << "TX took:" << t.elapsed() * 1000; +// cnote << "TX took:" << t.elapsed() * 1000; } - else if (i.second.gasPrice() < _gp.ask(*this) * 9 / 10) + else if (t.gasPrice() < _gp.ask(*this) * 9 / 10) { - // less than 90% of our ask price for gas. drop. - cnote << i.first << "Dropping El Cheapo transaction (<90% of ask price)"; - _tq.drop(i.first); + clog(StateTrace) << t.sha3() << "Dropping El Cheapo transaction (<90% of ask price)"; + _tq.drop(t.sha3()); } } catch (InvalidNonce const& in) @@ -530,57 +536,45 @@ pair State::sync(BlockChain const& _bc, TransactionQu if (req > got) { // too old - for (Transaction const& t: m_transactions) - if (t.from() == i.second.from()) - { - if (t.nonce() < i.second.nonce()) - { - cnote << i.first << "Dropping old transaction (nonce too low)"; - _tq.drop(i.first); - } - else if (t.nonce() == i.second.nonce() && t.gasPrice() <= i.second.gasPrice()) - { - cnote << i.first << "Dropping old transaction (gas price lower)"; - _tq.drop(i.first); - } - } + clog(StateTrace) << t.sha3() << "Dropping old transaction (nonce too low)"; + _tq.drop(t.sha3()); } - else if (got > req + _tq.waiting(i.second.sender())) + else if (got > req + _tq.waiting(t.sender())) { // too new - cnote << i.first << "Dropping new transaction (too many nonces ahead)"; - _tq.drop(i.first); + clog(StateTrace) << t.sha3() << "Dropping new transaction (too many nonces ahead)"; + _tq.drop(t.sha3()); } else - _tq.setFuture(i); + _tq.setFuture(t.sha3()); } catch (BlockGasLimitReached const& e) { bigint const& got = *boost::get_error_info(e); if (got > m_currentBlock.gasLimit) { - cnote << i.first << "Dropping over-gassy transaction (gas > block's gas limit)"; - _tq.drop(i.first); + clog(StateTrace) << t.sha3() << "Dropping over-gassy transaction (gas > block's gas limit)"; + _tq.drop(t.sha3()); } else { // 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); +// _tq.setFuture(t.sha3()); } } catch (Exception const& _e) { // Something else went wrong - drop it. - cnote << i.first << "Dropping invalid transaction:" << diagnostic_information(_e); - _tq.drop(i.first); + clog(StateTrace) << t.sha3() << "Dropping invalid transaction:" << diagnostic_information(_e); + _tq.drop(t.sha3()); } catch (std::exception const&) { // Something else went wrong - drop it. - _tq.drop(i.first); - cnote << i.first << "Transaction caused low-level exception :("; + _tq.drop(t.sha3()); + cwarn << t.sha3() << "Transaction caused low-level exception :("; } } if (chrono::steady_clock::now() > deadline) @@ -603,7 +597,6 @@ string State::vmTrace(bytesConstRef _block, BlockChain const& _bc, ImportRequire m_currentBlock.noteDirty(); LastHashes lh = _bc.lastHashes((unsigned)m_previousBlock.number); - vector receipts; string ret; unsigned i = 0; @@ -613,10 +606,6 @@ string State::vmTrace(bytesConstRef _block, BlockChain const& _bc, ImportRequire st.setShowMnemonics(); execute(lh, Transaction(tr.data(), CheckTransaction::Everything), Permanence::Committed, st.onOp()); ret += (ret.empty() ? "[" : ",") + st.json(); - - RLPStream receiptRLP; - m_receipts.back().streamRLP(receiptRLP); - receipts.push_back(receiptRLP.out()); ++i; } return ret.empty() ? "[]" : (ret + "]"); @@ -883,7 +872,7 @@ LogBloom State::logBloom() const return ret; } -void State::commitToMine(BlockChain const& _bc) +void State::commitToMine(BlockChain const& _bc, bytes const& _extraData) { uncommitToMine(); @@ -966,6 +955,9 @@ void State::commitToMine(BlockChain const& _bc) m_currentBlock.gasUsed = gasUsed(); m_currentBlock.stateRoot = m_state.root(); m_currentBlock.parentHash = m_previousBlock.hash(); + m_currentBlock.extraData = _extraData; + if (m_currentBlock.extraData.size() > 32) + m_currentBlock.extraData.resize(32); m_committedToMine = true; } diff --git a/libethereum/State.h b/libethereum/State.h index 6ad8fed09..ef8a3251a 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -32,11 +32,11 @@ #include #include #include -#include "TransactionQueue.h" #include "Account.h" #include "Transaction.h" #include "TransactionReceipt.h" #include "AccountDiff.h" +#include "GasPricer.h" namespace dev { @@ -66,6 +66,7 @@ using LogBloomRequirementError = boost::tuple(&_e)) + if (!!dynamic_cast(&_e)) return TransactionException::BadRLP; if (!!dynamic_cast(&_e)) return TransactionException::OutOfGasIntrinsic; @@ -94,99 +94,16 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, TransactionException cons return _out; } -Transaction::Transaction(bytesConstRef _rlpData, CheckTransaction _checkSig) +Transaction::Transaction(bytesConstRef _rlpData, CheckTransaction _checkSig): + TransactionBase(_rlpData, _checkSig) { - int field = 0; - RLP rlp(_rlpData); - try - { - if (!rlp.isList()) - BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction RLP must be a list")); - - m_nonce = rlp[field = 0].toInt(); - m_gasPrice = rlp[field = 1].toInt(); - m_gas = rlp[field = 2].toInt(); - m_type = rlp[field = 3].isEmpty() ? ContractCreation : MessageCall; - m_receiveAddress = rlp[field = 3].isEmpty() ? Address() : rlp[field = 3].toHash
(RLP::VeryStrict); - m_value = rlp[field = 4].toInt(); - - if (!rlp[field = 5].isData()) - BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("transaction data RLP must be an array")); - - m_data = rlp[field = 5].toBytes(); - byte v = rlp[field = 6].toInt() - 27; - h256 r = rlp[field = 7].toInt(); - h256 s = rlp[field = 8].toInt(); - - if (rlp.itemCount() > 9) - BOOST_THROW_EXCEPTION(InvalidTransactionFormat() << errinfo_comment("to many fields in the transaction RLP")); - - m_vrs = SignatureStruct{ r, s, v }; - if (_checkSig >= CheckTransaction::Cheap && !m_vrs.isValid()) - BOOST_THROW_EXCEPTION(InvalidSignature()); - if (_checkSig == CheckTransaction::Everything) - m_sender = sender(); - } - catch (Exception& _e) - { - _e << errinfo_name("invalid transaction format") << BadFieldError(field, toHex(rlp[field].data().toBytes())); - throw; - } if (_checkSig >= CheckTransaction::Cheap && !checkPayment()) BOOST_THROW_EXCEPTION(OutOfGasIntrinsic() << RequirementError(gasRequired(), (bigint)gas())); } -Address const& Transaction::safeSender() const noexcept -{ - try - { - return sender(); - } - catch (...) - { - cwarn << "safeSender() did throw an exception: " << boost::current_exception_diagnostic_information(); - return ZeroAddress; - } -} - -Address const& Transaction::sender() const -{ - if (!m_sender) - { - auto p = recover(m_vrs, sha3(WithoutSignature)); - if (!p) - BOOST_THROW_EXCEPTION(InvalidSignature()); - m_sender = right160(dev::sha3(bytesConstRef(p.data(), sizeof(p)))); - } - return m_sender; -} - bigint Transaction::gasRequired() const { if (!m_gasRequired) m_gasRequired = Transaction::gasRequired(m_data); return m_gasRequired; } - -void Transaction::sign(Secret _priv) -{ - auto sig = dev::sign(_priv, sha3(WithoutSignature)); - SignatureStruct sigStruct = *(SignatureStruct const*)&sig; - if (sigStruct.isValid()) - m_vrs = sigStruct; -} - -void Transaction::streamRLP(RLPStream& _s, IncludeSignature _sig) const -{ - if (m_type == NullTransaction) - return; - _s.appendList((_sig ? 3 : 0) + 6); - _s << m_nonce << m_gasPrice << m_gas; - if (m_type == MessageCall) - _s << m_receiveAddress; - else - _s << ""; - _s << m_value << m_data; - if (_sig) - _s << (m_vrs.v + 27) << (u256)m_vrs.r << (u256)m_vrs.s; -} diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 4de9d7e92..8ed0043c9 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -24,6 +24,7 @@ #include #include #include +#include #include namespace dev @@ -31,20 +32,6 @@ namespace dev namespace eth { -/// Named-boolean type to encode whether a signature be included in the serialisation process. -enum IncludeSignature -{ - WithoutSignature = 0, ///< Do not include a signature. - WithSignature = 1, ///< Do include a signature. -}; - -enum class CheckTransaction -{ - None, - Cheap, - Everything -}; - enum class TransactionException { None = 0, @@ -92,23 +79,34 @@ struct ExecutionResult std::ostream& operator<<(std::ostream& _out, ExecutionResult const& _er); /// Encodes a transaction, ready to be exported to or freshly imported from RLP. -class Transaction +class Transaction: public TransactionBase { public: /// Constructs a null transaction. Transaction() {} + /// Constructs from a transaction skeleton & optional secret. + Transaction(TransactionSkeleton const& _ts, Secret const& _s = Secret()): TransactionBase(_ts, _s) {} + /// Constructs a signed message-call transaction. - Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce, Secret const& _secret): + TransactionBase(_value, _gasPrice, _gas, _dest, _data, _nonce, _secret) + {} /// Constructs a signed contract-creation transaction. - Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) { sign(_secret); } + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce, Secret const& _secret): + TransactionBase(_value, _gasPrice, _gas, _data, _nonce, _secret) + {} /// Constructs an unsigned message-call transaction. - Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce = 0): m_type(MessageCall), m_nonce(_nonce), m_value(_value), m_receiveAddress(_dest), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, Address const& _dest, bytes const& _data, u256 const& _nonce = UndefinedU256): + TransactionBase(_value, _gasPrice, _gas, _dest, _data, _nonce) + {} /// Constructs an unsigned contract-creation transaction. - Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce = 0): m_type(ContractCreation), m_nonce(_nonce), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} + Transaction(u256 const& _value, u256 const& _gasPrice, u256 const& _gas, bytes const& _data, u256 const& _nonce = UndefinedU256): + TransactionBase(_value, _gasPrice, _gas, _data, _nonce) + {} /// Constructs a transaction from the given RLP. explicit Transaction(bytesConstRef _rlp, CheckTransaction _checkSig); @@ -116,68 +114,6 @@ public: /// Constructs a transaction from the given RLP. explicit Transaction(bytes const& _rlp, CheckTransaction _checkSig): Transaction(&_rlp, _checkSig) {} - - /// Checks equality of transactions. - bool operator==(Transaction const& _c) const { return m_type == _c.m_type && (m_type == ContractCreation || m_receiveAddress == _c.m_receiveAddress) && m_value == _c.m_value && m_data == _c.m_data; } - /// Checks inequality of transactions. - bool operator!=(Transaction const& _c) const { return !operator==(_c); } - - /// @returns sender of the transaction from the signature (and hash). - Address const& sender() const; - /// Like sender() but will never throw. @returns a null Address if the signature is invalid. - Address const& safeSender() const noexcept; - /// Force the sender to a particular value. This will result in an invalid transaction RLP. - void forceSender(Address const& _a) { m_sender = _a; } - - /// @returns true if transaction is non-null. - explicit operator bool() const { return m_type != NullTransaction; } - - /// @returns true if transaction is contract-creation. - bool isCreation() const { return m_type == ContractCreation; } - - /// @returns true if transaction is message-call. - bool isMessageCall() const { return m_type == MessageCall; } - - /// Serialises this transaction to an RLPStream. - void streamRLP(RLPStream& _s, IncludeSignature _sig = WithSignature) const; - - /// @returns the RLP serialisation of this transaction. - bytes rlp(IncludeSignature _sig = WithSignature) const { RLPStream s; streamRLP(s, _sig); return s.out(); } - - /// @returns the SHA3 hash of the RLP serialisation of this transaction. - h256 sha3(IncludeSignature _sig = WithSignature) const { if (_sig == WithSignature && m_hashWith) return m_hashWith; RLPStream s; streamRLP(s, _sig); auto ret = dev::sha3(s.out()); if (_sig == WithSignature) m_hashWith = ret; return ret; } - - /// @returns the amount of ETH to be transferred by this (message-call) transaction, in Wei. Synonym for endowment(). - u256 value() const { return m_value; } - /// @returns the amount of ETH to be endowed by this (contract-creation) transaction, in Wei. Synonym for value(). - u256 endowment() const { return m_value; } - - /// @returns the base fee and thus the implied exchange rate of ETH to GAS. - u256 gasPrice() const { return m_gasPrice; } - - /// @returns the total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. - u256 gas() const { return m_gas; } - - /// @returns the receiving address of the message-call transaction (undefined for contract-creation transactions). - Address receiveAddress() const { return m_receiveAddress; } - - /// Synonym for receiveAddress(). - Address to() const { return m_receiveAddress; } - - /// Synonym for safeSender(). - Address from() const { return safeSender(); } - - /// @returns the data associated with this (message-call) transaction. Synonym for initCode(). - bytes const& data() const { return m_data; } - /// @returns the initialisation code associated with this (contract-creation) transaction. Synonym for data(). - bytes const& initCode() const { return m_data; } - - /// @returns the transaction-count of the sender. - u256 nonce() const { return m_nonce; } - - /// @returns the signature of the transaction. Encodes the sender. - SignatureStruct const& signature() const { return m_vrs; } - /// @returns true if the transaction contains enough gas for the basic payment. bool checkPayment() const { return m_gas >= gasRequired(); } @@ -188,46 +124,11 @@ public: template static bigint gasRequired(T const& _data, u256 _gas = 0) { bigint ret = c_txGas + _gas; for (auto i: _data) ret += i ? c_txDataNonZeroGas : c_txDataZeroGas; return ret; } private: - /// Type of transaction. - enum Type - { - NullTransaction, ///< Null transaction. - ContractCreation, ///< Transaction to create contracts - receiveAddress() is ignored. - MessageCall ///< Transaction to invoke a message call - receiveAddress() is used. - }; - - void sign(Secret _priv); ///< Sign the transaction. - - Type m_type = NullTransaction; ///< Is this a contract-creation transaction or a message-call transaction? - u256 m_nonce; ///< The transaction-count of the sender. - u256 m_value; ///< The amount of ETH to be transferred by this transaction. Called 'endowment' for contract-creation transactions. - Address m_receiveAddress; ///< The receiving address of the transaction. - u256 m_gasPrice; ///< The base fee and thus the implied exchange rate of ETH to GAS. - u256 m_gas; ///< The total gas to convert, paid for from sender's account. Any unused gas gets refunded once the contract is ended. - bytes m_data; ///< The data associated with the transaction, or the initialiser if it's a creation transaction. - SignatureStruct m_vrs; ///< The signature of the transaction. Encodes the sender. - - mutable h256 m_hashWith; ///< Cached hash of transaction with signature. - mutable Address m_sender; ///< Cached sender, determined from signature. mutable bigint m_gasRequired = 0; ///< Memoised amount required for the transaction to run. }; /// Nice name for vector of Transaction. using Transactions = std::vector; -/// Simple human-readable stream-shift operator. -inline std::ostream& operator<<(std::ostream& _out, Transaction const& _t) -{ - _out << _t.sha3().abridged() << "{"; - if (_t.receiveAddress()) - _out << _t.receiveAddress().abridged(); - else - _out << "[CREATE]"; - - _out << "/" << _t.data().size() << "$" << _t.value() << "+" << _t.gas() << "@" << _t.gasPrice(); - _out << "<-" << _t.safeSender().abridged() << " #" << _t.nonce() << "}"; - return _out; -} - } } diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 8fcf3cfb6..2554544a3 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -31,7 +31,28 @@ using namespace dev::eth; const char* TransactionQueueChannel::name() { return EthCyan "┉┅▶"; } const char* TransactionQueueTraceChannel::name() { return EthCyan " ┅▶"; } -ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallback const& _cb, IfDropped _ik) +TransactionQueue::TransactionQueue(unsigned _limit, unsigned _futureLimit): + m_current(PriorityCompare { *this }), + m_limit(_limit), + m_futureLimit(_futureLimit) +{ + unsigned verifierThreads = std::max(thread::hardware_concurrency(), 3U) - 2U; + for (unsigned i = 0; i < verifierThreads; ++i) + m_verifiers.emplace_back([=](){ + setThreadName("txcheck" + toString(i)); + this->verifierBody(); + }); +} + +TransactionQueue::~TransactionQueue() +{ + m_aborting = true; + m_queueReady.notify_all(); + for (auto& i: m_verifiers) + i.join(); +} + +ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, IfDropped _ik) { // Check if we already know this transaction. h256 h = sha3(_transactionRLP); @@ -47,16 +68,18 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallb try { + // Check validity of _transactionRLP as a transaction. To do this we just deserialise and attempt to determine the sender. + // If it doesn't work, the signature is bad. + // The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction). t = Transaction(_transactionRLP, CheckTransaction::Everything); UpgradeGuard ul(l); - ir = manageImport_WITH_LOCK(h, t, _cb); + ir = manageImport_WITH_LOCK(h, t); } catch (...) { return ImportResult::Malformed; } } -// cdebug << "import-END: Nonce of" << t.sender() << "now" << maxNonce(t.sender()); return ir; } @@ -71,74 +94,86 @@ ImportResult TransactionQueue::check_WITH_LOCK(h256 const& _h, IfDropped _ik) return ImportResult::Success; } -ImportResult TransactionQueue::import(Transaction const& _transaction, ImportCallback const& _cb, IfDropped _ik) +ImportResult TransactionQueue::import(Transaction const& _transaction, IfDropped _ik) { // Check if we already know this transaction. h256 h = _transaction.sha3(WithSignature); -// 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; { UpgradeGuard ul(l); - ret = manageImport_WITH_LOCK(h, _transaction, _cb); + ret = manageImport_WITH_LOCK(h, _transaction); } } -// cdebug << "import-END: Nonce of" << _transaction.sender() << "now" << maxNonce(_transaction.sender()); return ret; } -std::unordered_map TransactionQueue::transactions() const +Transactions TransactionQueue::topTransactions(unsigned _limit) 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; + Transactions res; + unsigned n = _limit; + for (auto t = m_current.begin(); n != 0 && t != m_current.end(); ++t, --n) + res.push_back(t->transaction); + return res; } -ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction, ImportCallback const& _cb) +h256Hash TransactionQueue::knownTransactions() const +{ + ReadGuard l(m_lock); + return m_known; +} + +ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction) { try { - // Check validity of _transactionRLP as a transaction. To do this we just deserialise and attempt to determine the sender. - // If it doesn't work, the signature is bad. - // The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction). - - auto r = m_senders.equal_range(_transaction.from()); - for (auto it = r.first; it != r.second; ++it) - if (m_current.count(it->second) && m_current[it->second].nonce() == _transaction.nonce()) - if (_transaction.gasPrice() < m_current[it->second].gasPrice()) + assert(_h == _transaction.sha3()); + // Remove any prior transaction with the same nonce but a lower gas price. + // Bomb out if there's a prior transaction with higher gas price. + auto cs = m_currentByAddressAndNonce.find(_transaction.from()); + if (cs != m_currentByAddressAndNonce.end()) + { + auto t = cs->second.find(_transaction.nonce()); + if (t != cs->second.end()) + { + if (_transaction.gasPrice() < (*t->second).transaction.gasPrice()) return ImportResult::OverbidGasPrice; else - { - remove_WITH_LOCK(it->second); - break; - } - else if (m_future.count(it->second) && m_future[it->second].nonce() == _transaction.nonce()) - if (_transaction.gasPrice() < m_future[it->second].gasPrice()) + remove_WITH_LOCK((*t->second).transaction.sha3()); + } + } + auto fs = m_future.find(_transaction.from()); + if (fs != m_future.end()) + { + auto t = fs->second.find(_transaction.nonce()); + if (t != fs->second.end()) + { + if (_transaction.gasPrice() < t->second.transaction.gasPrice()) return ImportResult::OverbidGasPrice; else { - remove_WITH_LOCK(it->second); - break; + fs->second.erase(t); + --m_futureSize; } - else {} - - // If valid, append to blocks. + } + } + // If valid, append to transactions. insertCurrent_WITH_LOCK(make_pair(_h, _transaction)); - m_known.insert(_h); - if (_cb) - m_callbacks[_h] = _cb; clog(TransactionQueueTraceChannel) << "Queued vaguely legit-looking transaction" << _h; + + while (m_current.size() > m_limit) + { + clog(TransactionQueueTraceChannel) << "Dropping out of bounds transaction" << _h; + remove_WITH_LOCK(m_current.rbegin()->transaction.sha3()); + } + m_onReady(); } catch (Exception const& _e) @@ -157,7 +192,6 @@ ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transactio u256 TransactionQueue::maxNonce(Address const& _a) const { -// cdebug << "txQ::maxNonce" << _a; ReadGuard l(m_lock); return maxNonce_WITH_LOCK(_a); } @@ -165,93 +199,128 @@ u256 TransactionQueue::maxNonce(Address const& _a) const 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) - 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; + auto cs = m_currentByAddressAndNonce.find(_a); + if (cs != m_currentByAddressAndNonce.end() && !cs->second.empty()) + ret = cs->second.rbegin()->first; + auto fs = m_future.find(_a); + if (fs != m_future.end() && !fs->second.empty()) + ret = std::max(ret, fs->second.rbegin()->first); + return ret + 1; } void TransactionQueue::insertCurrent_WITH_LOCK(std::pair const& _p) { -// 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)) + if (m_currentByHash.count(_p.first)) + { cwarn << "Transaction hash" << _p.first << "already in current?!"; - m_current.insert(_p); + return; + } + + Transaction const& t = _p.second; + // Insert into current + auto inserted = m_currentByAddressAndNonce[t.from()].insert(std::make_pair(t.nonce(), PriorityQueue::iterator())); + PriorityQueue::iterator handle = m_current.emplace(VerifiedTransaction(t)); + inserted.first->second = handle; + m_currentByHash[_p.first] = handle; + + // Move following transactions from future to current + makeCurrent_WITH_LOCK(t); + m_known.insert(_p.first); } bool TransactionQueue::remove_WITH_LOCK(h256 const& _txHash) { -// cdebug << "txQ::remove" << _txHash; - for (std::unordered_map* pool: { &m_current, &m_future }) - { - 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; + auto t = m_currentByHash.find(_txHash); + if (t == m_currentByHash.end()) + return false; + + Address from = (*t->second).transaction.from(); + auto it = m_currentByAddressAndNonce.find(from); + assert (it != m_currentByAddressAndNonce.end()); + it->second.erase((*t->second).transaction.nonce()); + m_current.erase(t->second); + m_currentByHash.erase(t); + if (it->second.empty()) + m_currentByAddressAndNonce.erase(it); + m_known.erase(_txHash); + return true; } unsigned TransactionQueue::waiting(Address const& _a) const { ReadGuard l(m_lock); - auto it = m_senders.equal_range(_a); unsigned ret = 0; - for (auto i = it.first; i != it.second; ++i, ++ret) {} + auto cs = m_currentByAddressAndNonce.find(_a); + if (cs != m_currentByAddressAndNonce.end()) + ret = cs->second.size(); + auto fs = m_future.find(_a); + if (fs != m_future.end()) + ret += fs->second.size(); return ret; } -void TransactionQueue::setFuture(std::pair const& _t) +void TransactionQueue::setFuture(h256 const& _txHash) { -// cdebug << "txQ::setFuture" << _t.first; WriteGuard l(m_lock); - if (m_current.count(_t.first)) + auto it = m_currentByHash.find(_txHash); + if (it == m_currentByHash.end()) + return; + + VerifiedTransaction const& st = *(it->second); + + Address from = st.transaction.from(); + auto& queue = m_currentByAddressAndNonce[from]; + auto& target = m_future[from]; + auto cutoff = queue.lower_bound(st.transaction.nonce()); + for (auto m = cutoff; m != queue.end(); ++m) { - m_future.insert(_t); - m_current.erase(_t.first); + VerifiedTransaction& t = const_cast(*(m->second)); // set has only const iterators. Since we are moving out of container that's fine + m_currentByHash.erase(t.transaction.sha3()); + target.emplace(t.transaction.nonce(), move(t)); + m_current.erase(m->second); + ++m_futureSize; } + queue.erase(cutoff, queue.end()); + if (queue.empty()) + m_currentByAddressAndNonce.erase(from); } -void TransactionQueue::noteGood(std::pair const& _t) +void TransactionQueue::makeCurrent_WITH_LOCK(Transaction const& _t) { -// cdebug << "txQ::noteGood" << _t.first; - WriteGuard l(m_lock); - auto r = m_senders.equal_range(_t.second.sender()); - for (auto it = r.first; it != r.second; ++it) + auto fs = m_future.find(_t.from()); + if (fs != m_future.end()) { - auto fit = m_future.find(it->second); - if (fit != m_future.end()) + u256 nonce = _t.nonce() + 1; + auto fb = fs->second.find(nonce); + if (fb != fs->second.end()) { - m_current.insert(*fit); - m_future.erase(fit); + auto ft = fb; + while (ft != fs->second.end() && ft->second.transaction.nonce() == nonce) + { + auto inserted = m_currentByAddressAndNonce[_t.from()].insert(std::make_pair(ft->second.transaction.nonce(), PriorityQueue::iterator())); + PriorityQueue::iterator handle = m_current.emplace(move(ft->second)); + inserted.first->second = handle; + m_currentByHash[(*handle).transaction.sha3()] = handle; + --m_futureSize; + ++ft; + ++nonce; + } + fs->second.erase(fb, ft); + if (fs->second.empty()) + m_future.erase(_t.from()); } } + + while (m_futureSize > m_futureLimit) + { + // TODO: priority queue for future transactions + // For now just drop random chain end + --m_futureSize; + clog(TransactionQueueTraceChannel) << "Dropping out of bounds future transaction" << m_future.begin()->second.rbegin()->second.transaction.sha3(); + m_future.begin()->second.erase(--m_future.begin()->second.end()); + if (m_future.begin()->second.empty()) + m_future.erase(m_future.begin()); + } } void TransactionQueue::drop(h256 const& _txHash) @@ -263,7 +332,67 @@ void TransactionQueue::drop(h256 const& _txHash) UpgradeGuard ul(l); m_dropped.insert(_txHash); - m_known.erase(_txHash); - remove_WITH_LOCK(_txHash); } + +void TransactionQueue::dropGood(Transaction const& _t) +{ + WriteGuard l(m_lock); + makeCurrent_WITH_LOCK(_t); + if (!m_known.count(_t.sha3())) + return; + m_dropped.insert(_t.sha3()); + remove_WITH_LOCK(_t.sha3()); +} + +void TransactionQueue::clear() +{ + WriteGuard l(m_lock); + m_known.clear(); + m_current.clear(); + m_currentByAddressAndNonce.clear(); + m_currentByHash.clear(); + m_future.clear(); + m_futureSize = 0; +} + +void TransactionQueue::enqueue(RLP const& _data, h512 const& _nodeId) +{ + { + Guard l(x_queue); + unsigned itemCount = _data.itemCount(); + for (unsigned i = 0; i < itemCount; ++i) + m_unverified.emplace_back(UnverifiedTransaction(_data[i].data(), _nodeId)); + } + m_queueReady.notify_all(); +} + +void TransactionQueue::verifierBody() +{ + while (!m_aborting) + { + UnverifiedTransaction work; + + { + unique_lock l(x_queue); + m_queueReady.wait(l, [&](){ return !m_unverified.empty() || m_aborting; }); + if (m_aborting) + return; + work = move(m_unverified.front()); + m_unverified.pop_front(); + } + + try + { + Transaction t(work.transaction, CheckTransaction::Cheap); //Signature will be checked later + ImportResult ir = import(t); + m_onImport(ir, t.sha3(), work.nodeId); + } + catch (...) + { + // should not happen as exceptions are handled in import. + cwarn << "Bad transaction:" << boost::current_exception_diagnostic_information(); + } + } +} + diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index d9bfef847..f6c140e6f 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -22,6 +22,9 @@ #pragma once #include +#include +#include +#include #include #include #include @@ -39,50 +42,157 @@ struct TransactionQueueChannel: public LogChannel { static const char* name(); s struct TransactionQueueTraceChannel: public LogChannel { static const char* name(); static const int verbosity = 7; }; #define ctxq dev::LogOutputStream() -enum class IfDropped { Ignore, Retry }; +/// Import transaction policy +enum class IfDropped +{ + Ignore, ///< Don't import transaction that was previously dropped. + Retry ///< Import transaction even if it was dropped before. +}; /** * @brief A queue of Transactions, each stored as RLP. + * Maintains a transaction queue sorted by nonce diff and gas price. * @threadsafe */ class TransactionQueue { public: - using ImportCallback = std::function; - - ImportResult import(Transaction const& _tx, ImportCallback const& _cb = ImportCallback(), IfDropped _ik = IfDropped::Ignore); - ImportResult import(bytes const& _tx, ImportCallback const& _cb = ImportCallback(), IfDropped _ik = IfDropped::Ignore) { return import(&_tx, _cb, _ik); } - ImportResult import(bytesConstRef _tx, ImportCallback const& _cb = ImportCallback(), IfDropped _ik = IfDropped::Ignore); - + /// @brief TransactionQueue + /// @param _limit Maximum number of pending transactions in the queue. + /// @param _futureLimit Maximum number of future nonce transactions. + TransactionQueue(unsigned _limit = 1024, unsigned _futureLimit = 1024); + ~TransactionQueue(); + /// Add transaction to the queue to be verified and imported. + /// @param _data RLP encoded transaction data. + /// @param _nodeId Optional network identified of a node transaction comes from. + void enqueue(RLP const& _data, h512 const& _nodeId); + + /// Verify and add transaction to the queue synchronously. + /// @param _tx RLP encoded transaction data. + /// @param _ik Set to Retry to force re-addinga transaction that was previously dropped. + /// @returns Import result code. + ImportResult import(bytes const& _tx, IfDropped _ik = IfDropped::Ignore) { return import(&_tx, _ik); } + + /// Verify and add transaction to the queue synchronously. + /// @param _tx Trasnaction data. + /// @param _ik Set to Retry to force re-addinga transaction that was previously dropped. + /// @returns Import result code. + ImportResult import(Transaction const& _tx, IfDropped _ik = IfDropped::Ignore); + + /// Remove transaction from the queue + /// @param _txHash Trasnaction hash void drop(h256 const& _txHash); + /// Get number of pending transactions for account. + /// @returns Pending transaction count. 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()); } + + /// Get top transactions from the queue. Returned transactions are not removed from the queue automatically. + /// @param _limit Max number of transactions to return. + /// @returns up to _limit transactions ordered by nonce and gas price. + Transactions topTransactions(unsigned _limit) const; + + /// Get a hash set of transactions in the queue + /// @returns A hash set of all transactions in the queue + h256Hash knownTransactions() const; + + /// Get max nonce for an account + /// @returns Max transaction nonce for account in the queue u256 maxNonce(Address const& _a) const; - void setFuture(std::pair const& _t); - void noteGood(std::pair const& _t); + /// Mark transaction as future. It wont be retured in topTransactions list until a transaction with a preceeding nonce is imported or marked with dropGood + /// @param _t Transaction hash + void setFuture(h256 const& _t); + + /// Drop a trasnaction from the list if exists and move following future trasnactions to current (if any) + /// @param _t Transaction hash + void dropGood(Transaction const& _t); + + /// Clear the queue + void 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); } + /// Register a handler that will be called once there is a new transaction imported + template Handler<> onReady(T const& _t) { return m_onReady.add(_t); } + + /// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported + template Handler onImport(T const& _t) { return m_onImport.add(_t); } private: + + /// Verified and imported transaction + struct VerifiedTransaction + { + VerifiedTransaction(Transaction const& _t): transaction(_t) {} + VerifiedTransaction(VerifiedTransaction&& _t): transaction(std::move(_t.transaction)) {} + + VerifiedTransaction(VerifiedTransaction const&) = delete; + VerifiedTransaction& operator=(VerifiedTransaction const&) = delete; + + Transaction transaction; ///< Transaction data + }; + + /// Trasnaction pending verification + struct UnverifiedTransaction + { + UnverifiedTransaction() {} + UnverifiedTransaction(bytesConstRef const& _t, h512 const& _nodeId): transaction(_t.toBytes()), nodeId(_nodeId) {} + UnverifiedTransaction(UnverifiedTransaction&& _t): transaction(std::move(_t.transaction)) {} + UnverifiedTransaction& operator=(UnverifiedTransaction&& _other) { transaction = std::move(_other.transaction); nodeId = std::move(_other.nodeId); return *this; } + + UnverifiedTransaction(UnverifiedTransaction const&) = delete; + UnverifiedTransaction& operator=(UnverifiedTransaction const&) = delete; + + bytes transaction; ///< RLP encoded transaction data + h512 nodeId; ///< Network Id of the peer transaction comes from + }; + + struct PriorityCompare + { + TransactionQueue& queue; + /// Compare transaction by nonce height and gas price. + bool operator()(VerifiedTransaction const& _first, VerifiedTransaction const& _second) const + { + u256 const& height1 = _first.transaction.nonce() - queue.m_currentByAddressAndNonce[_first.transaction.sender()].begin()->first; + u256 const& height2 = _second.transaction.nonce() - queue.m_currentByAddressAndNonce[_second.transaction.sender()].begin()->first; + return height1 < height2 || (height1 == height2 && _first.transaction.gasPrice() > _second.transaction.gasPrice()); + } + }; + + // Use a set with dynamic comparator for minmax priority queue. The comparator takes into account min account nonce. Updating it does not affect the order. + using PriorityQueue = std::multiset; + + ImportResult import(bytesConstRef _tx, IfDropped _ik = IfDropped::Ignore); ImportResult check_WITH_LOCK(h256 const& _h, IfDropped _ik); - ImportResult manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction, ImportCallback const& _cb); + ImportResult manageImport_WITH_LOCK(h256 const& _h, Transaction const& _transaction); void insertCurrent_WITH_LOCK(std::pair const& _p); + void makeCurrent_WITH_LOCK(Transaction const& _t); bool remove_WITH_LOCK(h256 const& _txHash); u256 maxNonce_WITH_LOCK(Address const& _a) const; + void verifierBody(); 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_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. - Signal m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast. + h256Hash m_dropped; ///< Transactions that have previously been dropped + + PriorityQueue m_current; + std::unordered_map m_currentByHash; ///< Transaction hash to set ref + std::unordered_map> m_currentByAddressAndNonce; ///< Transactions grouped by account and nonce + std::unordered_map> m_future; /// Future transactions + + Signal<> m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast. + Signal m_onImport; ///< Called for each import attempt. Arguments are result, transaction id an node id. Be nice and exit fast. + unsigned m_limit; ///< Max number of pending transactions + unsigned m_futureLimit; ///< Max number of future transactions + unsigned m_futureSize = 0; ///< Current number of future transactions + + std::condition_variable m_queueReady; ///< Signaled when m_unverified has a new entry. + std::vector m_verifiers; + std::deque m_unverified; ///< Pending verification queue + mutable Mutex x_queue; ///< Verification queue mutex + bool m_aborting = false; ///< Exit condition for verifier. }; } diff --git a/libethereum/Utility.cpp b/libethereum/Utility.cpp index adfea4a51..e02012cd5 100644 --- a/libethereum/Utility.cpp +++ b/libethereum/Utility.cpp @@ -22,11 +22,17 @@ #include "Utility.h" #include -#include +#include #include +#include +#include +#include +#include "CanonBlockChain.h" +#include "Defaults.h" using namespace std; using namespace dev; using namespace dev::eth; +namespace fs = boost::filesystem; bytes dev::eth::parseData(string const& _args) { @@ -84,3 +90,51 @@ bytes dev::eth::parseData(string const& _args) return m_data; } + +void dev::eth::upgradeDatabase(std::string const& _basePath) +{ + std::string path = _basePath.empty() ? Defaults::get()->dbPath() : _basePath; + + if (fs::exists(path + "/state") && fs::exists(path + "/details") && fs::exists(path + "/blocks")) + { + // upgrade + cnote << "Upgrading database to new layout..."; + bytes statusBytes = contents(path + "/status"); + RLP status(statusBytes); + try + { + auto minorProtocolVersion = (unsigned)status[1]; + auto databaseVersion = (unsigned)status[2]; + auto genesisHash = status.itemCount() > 3 ? (h256)status[3] : CanonBlockChain::genesis().hash(); + + string chainPath = path + "/" + toHex(genesisHash.ref().cropped(0, 4)); + string extrasPath = chainPath + "/" + toString(databaseVersion); + + // write status + if (!fs::exists(chainPath + "/blocks")) + { + boost::filesystem::create_directories(chainPath); + fs::rename(path + "/blocks", chainPath + "/blocks"); + + if (!fs::exists(extrasPath + "/extras")) + { + boost::filesystem::create_directories(extrasPath); + fs::rename(path + "/details", extrasPath + "/extras"); + fs::rename(path + "/state", extrasPath + "/state"); + writeFile(extrasPath + "/minor", rlp(minorProtocolVersion)); + } + } + } + catch (Exception& ex) + { + cwarn << "Couldn't upgrade: " << ex.what() << boost::diagnostic_information(ex); + } + catch (...) + { + cwarn << "Couldn't upgrade. Some issue with moving files around. Probably easiest just to redownload."; + } + + fs::rename(path + "/status", path + "/status.old"); + } +} + diff --git a/libethereum/Utility.h b/libethereum/Utility.h index 893604139..0dfe8509b 100644 --- a/libethereum/Utility.h +++ b/libethereum/Utility.h @@ -42,5 +42,7 @@ namespace eth */ bytes parseData(std::string const& _args); +void upgradeDatabase(std::string const& _basePath); + } } diff --git a/libethereum/VerifiedBlock.h b/libethereum/VerifiedBlock.h index 6cafe4b2f..8bac12f90 100644 --- a/libethereum/VerifiedBlock.h +++ b/libethereum/VerifiedBlock.h @@ -43,11 +43,11 @@ struct VerifiedBlockRef /// @brief Verified block info, combines block data and verified info/transactions struct VerifiedBlock { - VerifiedBlock() {}; + VerifiedBlock() {} VerifiedBlock(BlockInfo&& _bi) { - verified.info = _bi; + verified.info = std::move(_bi); } VerifiedBlock(VerifiedBlock&& _other): diff --git a/libevm/ExtVMFace.cpp b/libevm/ExtVMFace.cpp index ad419d2a3..f4614d669 100644 --- a/libevm/ExtVMFace.cpp +++ b/libevm/ExtVMFace.cpp @@ -21,22 +21,20 @@ #include "ExtVMFace.h" -using namespace std; using namespace dev; using namespace dev::eth; -ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth): +ExtVMFace::ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth): myAddress(_myAddress), caller(_caller), origin(_origin), value(_value), gasPrice(_gasPrice), data(_data), - code(_code), + code(std::move(_code)), codeHash(_codeHash), lastHashes(_lh), previousBlock(_previousBlock), currentBlock(_currentBlock), depth(_depth) {} - diff --git a/libevm/ExtVMFace.h b/libevm/ExtVMFace.h index feb5e8ac2..6c2057559 100644 --- a/libevm/ExtVMFace.h +++ b/libevm/ExtVMFace.h @@ -171,7 +171,7 @@ public: ExtVMFace() = default; /// Full constructor. - ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes const& _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth); + ExtVMFace(Address _myAddress, Address _caller, Address _origin, u256 _value, u256 _gasPrice, bytesConstRef _data, bytes _code, h256 const& _codeHash, BlockInfo const& _previousBlock, BlockInfo const& _currentBlock, LastHashes const& _lh, unsigned _depth); virtual ~ExtVMFace() = default; diff --git a/libevm/SmartVM.cpp b/libevm/SmartVM.cpp index 12f2f7078..add43302e 100644 --- a/libevm/SmartVM.cpp +++ b/libevm/SmartVM.cpp @@ -20,8 +20,13 @@ #include "SmartVM.h" #include +#include +#include +#include +#include #include #include +#include #include #include #include "VMFactory.h" @@ -32,6 +37,8 @@ namespace eth { namespace { + struct JitInfo: LogChannel { static const char* name() { return "JIT"; }; static const int verbosity = 11; }; + using HitMap = std::unordered_map; HitMap& getHitMap() @@ -39,30 +46,93 @@ namespace static HitMap s_hitMap; return s_hitMap; } + + struct JitTask + { + bytes code; + h256 codeHash; + }; + + class JitWorker + { + bool m_finished = false; + std::mutex x_mutex; + std::condition_variable m_cv; + std::thread m_worker; + std::queue m_queue; + + bool pop(JitTask& o_task) + { + std::unique_lock lock{x_mutex}; + m_cv.wait(lock, [this]{ return m_finished || !m_queue.empty(); }); + if (m_finished) + return false; + + assert(!m_queue.empty()); + o_task = std::move(m_queue.front()); + m_queue.pop(); + return true; + } + + void work() + { + clog(JitInfo) << "JIT worker started."; + JitTask task; + while (pop(task)) + { + clog(JitInfo) << "Compilation... " << task.codeHash; + evmjit::JIT::compile(task.code.data(), task.code.size(), eth2jit(task.codeHash)); + clog(JitInfo) << " ...finished " << task.codeHash; + } + clog(JitInfo) << "JIT worker finished."; + } + + public: + JitWorker() noexcept: m_worker([this]{ work(); }) + {} + + ~JitWorker() + { + DEV_GUARDED(x_mutex) + m_finished = true; + m_cv.notify_one(); + m_worker.join(); + } + + void push(JitTask&& _task) + { + DEV_GUARDED(x_mutex) + m_queue.push(std::move(_task)); + m_cv.notify_one(); + } + }; } bytesConstRef SmartVM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp) { - auto codeHash = sha3(_ext.code); + auto codeHash = _ext.codeHash; auto vmKind = VMKind::Interpreter; // default VM // Jitted EVM code already in memory? - if (evmjit::JIT::isCodeReady(eth2llvm(codeHash))) + if (evmjit::JIT::isCodeReady(eth2jit(codeHash))) { - cnote << "Jitted"; + clog(JitInfo) << "JIT: " << codeHash; vmKind = VMKind::JIT; } else { + static JitWorker s_worker; + // Check EVM code hit count - static const uint64_t c_hitTreshold = 1; + static const uint64_t c_hitTreshold = 2; auto& hits = getHitMap()[codeHash]; ++hits; - if (hits > c_hitTreshold) + if (hits == c_hitTreshold) { - cnote << "JIT selected"; - vmKind = VMKind::JIT; + clog(JitInfo) << "Schedule: " << codeHash; + s_worker.push({_ext.code, codeHash}); } + clog(JitInfo) << "Interpreter: " << codeHash; } // TODO: Selected VM must be kept only because it returns reference to its internal memory. diff --git a/libjsconsole/CMakeLists.txt b/libjsconsole/CMakeLists.txt index 761435fe1..b5362b31a 100644 --- a/libjsconsole/CMakeLists.txt +++ b/libjsconsole/CMakeLists.txt @@ -12,7 +12,9 @@ aux_source_directory(. SRC_LIST) include_directories(BEFORE ${V8_INCLUDE_DIRS}) include_directories(BEFORE ..) -include_directories(${READLINE_INCLUDE_DIRS}) +if (READLINE_FOUND) + include_directories(${READLINE_INCLUDE_DIRS}) +endif() include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(${CURL_INCLUDE_DIRS}) @@ -24,7 +26,9 @@ add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) target_link_libraries(${EXECUTABLE} jsengine) target_link_libraries(${EXECUTABLE} devcore) -target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) +if (READLINE_FOUND) + target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) +endif() target_link_libraries(${EXECUTABLE} ${JSON_RPC_CPP_SERVER_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${CURL_LIBRARIES}) diff --git a/libjsconsole/JSConsole.h b/libjsconsole/JSConsole.h index 50f6d6ae5..fc190a637 100644 --- a/libjsconsole/JSConsole.h +++ b/libjsconsole/JSConsole.h @@ -23,9 +23,11 @@ #pragma once #include -// TODO! make readline optional! + +#if ETH_READLINE #include #include +#endif namespace dev { @@ -42,18 +44,35 @@ public: void readExpression() const { std::string cmd = ""; - g_logPost = [](std::string const& a, char const*) { std::cout << "\r \r" << a << std::endl << std::flush; rl_forced_update_display(); }; + g_logPost = [](std::string const& a, char const*) + { + std::cout << "\r \r" << a << std::endl << std::flush; +#if ETH_READLINE + rl_forced_update_display(); +#endif + }; bool isEmpty = true; int openBrackets = 0; do { + std::string rl; +#if ETH_READLINE char* buff = readline(promptForIndentionLevel(openBrackets).c_str()); - isEmpty = !(buff && *buff); + isEmpty = !buff; if (!isEmpty) { - cmd += std::string(buff); - cmd += " "; + rl = std::string(buff); free(buff); + } +#else + std::cout << promptForIndentionLevel(openBrackets) << std::flush; + std::getline(std::cin, rl); + isEmpty = rl.length() == 0; +#endif + if (!isEmpty) + { + cmd += rl; + cmd += " "; int open = std::count(cmd.begin(), cmd.end(), '{'); open += std::count(cmd.begin(), cmd.end(), '('); int closed = std::count(cmd.begin(), cmd.end(), '}'); @@ -64,7 +83,9 @@ public: if (!isEmpty) { +#if ETH_READLINE add_history(cmd.c_str()); +#endif auto value = m_engine.eval(cmd.c_str()); std::string result = m_printer.prettyPrint(value).cstr(); std::cout << result << std::endl; diff --git a/libjsengine/CMakeLists.txt b/libjsengine/CMakeLists.txt index 0023494c6..d8599cc0f 100644 --- a/libjsengine/CMakeLists.txt +++ b/libjsengine/CMakeLists.txt @@ -19,9 +19,10 @@ file(GLOB HEADERS "*.h") include(EthUtils) eth_add_resources("${CMAKE_CURRENT_SOURCE_DIR}/JSResources.cmake" "JSRES") -message(STATUS "HERE!!! ${JSRES}") add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS} ${JSRES}) +add_dependencies(${EXECUTABLE} BuildInfo.h) + # macos brew version of v8 needs to be compiled with libstdc++ # it also needs to be dynamic library # xcode needs libstdc++ to be explicitly set as it's attribute diff --git a/libjsengine/JSEngine.h b/libjsengine/JSEngine.h index ce54379a1..d44fc7828 100644 --- a/libjsengine/JSEngine.h +++ b/libjsengine/JSEngine.h @@ -29,7 +29,11 @@ namespace eth { class JSException: public std::exception {}; +#if defined(_MSC_VER) +class JSPrintException: public JSException { char const* what() const { return "Cannot print expression!"; } }; +#else class JSPrintException: public JSException { char const* what() const noexcept { return "Cannot print expression!"; } }; +#endif class JSString { diff --git a/libjsengine/JSV8Engine.cpp b/libjsengine/JSV8Engine.cpp index ebf0a0e72..a97120a67 100644 --- a/libjsengine/JSV8Engine.cpp +++ b/libjsengine/JSV8Engine.cpp @@ -23,6 +23,10 @@ #include #include "JSV8Engine.h" #include "libjsengine/JSEngineResources.hpp" +#include "BuildInfo.h" + +#define TO_STRING_HELPER(s) #s +#define TO_STRING(s) TO_STRING_HELPER(s) using namespace std; using namespace dev; @@ -87,15 +91,6 @@ void reportException(v8::TryCatch* _tryCatch) } } -class JSV8Env -{ -public: - ~JSV8Env() - { - v8::V8::Dispose(); - } -}; - class JSV8Scope { public: @@ -124,8 +119,6 @@ private: } } -JSV8Env JSV8Engine::s_env = JSV8Env(); - JSString JSV8Value::toString() const { if (m_value.IsEmpty()) @@ -141,6 +134,7 @@ JSString JSV8Value::toString() const JSV8Engine::JSV8Engine(): m_scope(new JSV8Scope()) { JSEngineResources resources; + eval("env = typeof(env) === 'undefined' ? {} : env; env.os = '" TO_STRING(ETH_BUILD_PLATFORM) "'"); string common = resources.loadResourceAsString("common"); string web3 = resources.loadResourceAsString("web3"); string admin = resources.loadResourceAsString("admin"); @@ -157,7 +151,6 @@ JSV8Engine::~JSV8Engine() JSV8Value JSV8Engine::eval(char const* _cstr) const { - v8::HandleScope handleScope; v8::TryCatch tryCatch; v8::Local source = v8::String::New(_cstr); v8::Local name(v8::String::New("(shell)")); diff --git a/libjsengine/JSV8Engine.h b/libjsengine/JSV8Engine.h index 563642d73..db75cafbc 100644 --- a/libjsengine/JSV8Engine.h +++ b/libjsengine/JSV8Engine.h @@ -56,7 +56,6 @@ public: v8::Handle const& context() const; private: - static JSV8Env s_env; JSV8Scope* m_scope; }; diff --git a/libjsengine/JSV8Printer.cpp b/libjsengine/JSV8Printer.cpp index 93c235859..53a9c94a8 100644 --- a/libjsengine/JSV8Printer.cpp +++ b/libjsengine/JSV8Printer.cpp @@ -37,7 +37,6 @@ JSV8Printer::JSV8Printer(JSV8Engine const& _engine): m_engine(_engine) JSString JSV8Printer::prettyPrint(JSV8Value const& _value) const { - v8::HandleScope handleScope; v8::Local pp = v8::String::New("prettyPrint"); v8::Handle func = v8::Handle::Cast(m_engine.context()->Global()->Get(pp)); v8::Local values[1] = {v8::Local::New(_value.value())}; diff --git a/libjsengine/PrettyPrint.js b/libjsengine/PrettyPrint.js index f617cf29c..080c1a485 100644 --- a/libjsengine/PrettyPrint.js +++ b/libjsengine/PrettyPrint.js @@ -1,4 +1,14 @@ var prettyPrint = (function () { + var onlyDecentPlatform = function (x) { + return env.os.indexOf('Windows') === -1 ? x : ''; + }; + + var color_red = onlyDecentPlatform('\033[31m'); + var color_green = onlyDecentPlatform('\033[32m'); + var color_pink = onlyDecentPlatform('\033[35m'); + var color_white = onlyDecentPlatform('\033[0m'); + var color_blue = onlyDecentPlatform('\033[30m'); + function pp(object, indent) { try { JSON.stringify(object) @@ -16,13 +26,13 @@ var prettyPrint = (function () { } str += " ]"; } else if (object instanceof Error) { - str += "\033[31m" + "Error:\033[0m " + object.message; + str += color_red + "Error: " + color_white + object.message; } else if (object === null) { - str += "\033[1m\033[30m" + "null"; + str += color_blue + "null"; } else if(typeof(object) === "undefined") { - str += "\033[1m\033[30m" + object; + str += color_blue + object; } else if (isBigNumber(object)) { - str += "\033[32m'" + object.toString(10) + "'"; + str += color_green + object.toString(10) + "'"; } else if(typeof(object) === "object") { str += "{\n"; indent += " "; @@ -41,15 +51,15 @@ var prettyPrint = (function () { }); str += indent.substr(2, indent.length) + "}"; } else if(typeof(object) === "string") { - str += "\033[32m'" + object + "'"; + str += color_green + object + "'"; } else if(typeof(object) === "number") { - str += "\033[31m" + object; + str += color_red + object; } else if(typeof(object) === "function") { - str += "\033[35m[Function]"; + str += color_pink + "[Function]"; } else { str += object; } - str += "\033[0m"; + str += color_white; return str; } var redundantFields = [ diff --git a/libjsqrc/ethereumjs/.travis.yml b/libjsqrc/ethereumjs/.travis.yml index 92fa1cf35..175cd47b8 100644 --- a/libjsqrc/ethereumjs/.travis.yml +++ b/libjsqrc/ethereumjs/.travis.yml @@ -11,7 +11,6 @@ script: - "jshint *.js lib" after_script: - npm run-script build - - npm run-script karma - npm run-script test-coveralls - cd test/node && npm install && node app.js diff --git a/libjsqrc/ethereumjs/bower.json b/libjsqrc/ethereumjs/bower.json index cb63bd076..fb38bda61 100644 --- a/libjsqrc/ethereumjs/bower.json +++ b/libjsqrc/ethereumjs/bower.json @@ -1,7 +1,7 @@ { "name": "web3", "namespace": "ethereum", - "version": "0.6.0", + "version": "0.7.1", "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 a57cac292..f939d164b 100644 --- a/libjsqrc/ethereumjs/dist/web3-light.js +++ b/libjsqrc/ethereumjs/dist/web3-light.js @@ -263,6 +263,13 @@ var coder = new SolidityCoder([ inputFormatter: f.formatInputBytes, outputFormatter: f.formatOutputBytes }), + new SolidityType({ + name: 'string', + match: 'strict', + mode: 'bytes', + inputFormatter: f.formatInputString, + outputFormatter: f.formatOutputString + }), new SolidityType({ name: 'real', match: 'prefix', @@ -328,26 +335,43 @@ var formatInputInt = function (value) { }; /** - * Formats input value to byte representation of string + * Formats input bytes * * @method formatInputBytes * @param {String} * @returns {SolidityParam} */ var formatInputBytes = function (value) { - var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); + var result = utils.padRight(utils.toHex(value).substr(2), 64); return new SolidityParam(result); }; /** - * Formats input value to byte representation of string + * Formats input bytes * - * @method formatInputDynamicBytes + * @method formatDynamicInputBytes * @param {String} * @returns {SolidityParam} */ var formatInputDynamicBytes = function (value) { - var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); + value = utils.toHex(value).substr(2); + var l = Math.floor((value.length + 63) / 64); + var result = utils.padRight(value, l * 64); + var length = Math.floor(value.length / 2); + return new SolidityParam(formatInputInt(length).value + result, 32); +}; + +/** + * Formats input value to byte representation of string + * + * @method formatInputString + * @param {String} + * @returns {SolidityParam} + */ +var formatInputString = function (value) { + var result = utils.fromAscii(value).substr(2); + var l = Math.floor((result.length + 63) / 64); + result = utils.padRight(result, l * 64); return new SolidityParam(formatInputInt(value.length).value + result, 32); }; @@ -450,27 +474,38 @@ var formatOutputBool = function (param) { }; /** - * Should be used to format output string + * Should be used to format output bytes * * @method formatOutputBytes * @param {SolidityParam} left-aligned hex representation of string - * @returns {String} ascii string + * @returns {String} hex string */ var formatOutputBytes = function (param) { - // length might also be important! - return utils.toAscii(param.staticPart()); + return '0x' + param.staticPart(); }; /** - * Should be used to format output string + * Should be used to format output bytes * * @method formatOutputDynamicBytes * @param {SolidityParam} left-aligned hex representation of string - * @returns {String} ascii string + * @returns {String} hex string */ var formatOutputDynamicBytes = function (param) { - // length might also be important! - return utils.toAscii(param.dynamicPart().slice(64)); + var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; + return '0x' + param.dynamicPart().substr(64, length); +}; + +/** + * Should be used to format output string + * + * @method formatOutputString + * @param {SolidityParam} left-aligned hex representation of string + * @returns {String} ascii string + */ +var formatOutputString = function (param) { + var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; + return utils.toAscii(param.dynamicPart().substr(64, length)); }; /** @@ -489,6 +524,7 @@ module.exports = { formatInputInt: formatInputInt, formatInputBytes: formatInputBytes, formatInputDynamicBytes: formatInputDynamicBytes, + formatInputString: formatInputString, formatInputBool: formatInputBool, formatInputReal: formatInputReal, formatOutputInt: formatOutputInt, @@ -498,6 +534,7 @@ module.exports = { formatOutputBool: formatOutputBool, formatOutputBytes: formatOutputBytes, formatOutputDynamicBytes: formatOutputDynamicBytes, + formatOutputString: formatOutputString, formatOutputAddress: formatOutputAddress }; @@ -687,13 +724,14 @@ var getOffset = function (bytes, index) { */ SolidityParam.decodeBytes = function (bytes, index) { index = index || 0; - //TODO add support for strings longer than 32 bytes - //var length = parseInt('0x' + bytes.substr(offset * 64, 64)); var offset = getOffset(bytes, index); - // 2 * , cause we also parse length - return new SolidityParam(bytes.substr(offset * 2, 2 * 64), 0); + var l = parseInt('0x' + bytes.substr(offset * 2, 64)); + l = Math.floor((l + 31) / 32); + + // (1 + l) * , cause we also parse length + return new SolidityParam(bytes.substr(offset * 2, (1 + l) * 64), 0); }; /** @@ -846,7 +884,7 @@ module.exports = function (str, isNew) { }; -},{"./utils":7,"crypto-js/sha3":33}],7:[function(require,module,exports){ +},{"./utils":7,"crypto-js/sha3":34}],7:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -924,6 +962,19 @@ var padLeft = function (string, chars, sign) { return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; }; +/** + * Should be called to pad string to expected length + * + * @method padRight + * @param {String} string to be padded + * @param {Number} characters that result string should have + * @param {String} sign, by default 0 + * @returns {String} right aligned string + */ +var padRight = function (string, chars, sign) { + return string + (new Array(chars - string.length + 1).join(sign ? sign : "0")); +}; + /** * Should be called to get sting from it's hex representation * @@ -940,10 +991,6 @@ var toAscii = function(hex) { } for (; i < l; i+=2) { var code = parseInt(hex.substr(i, 2), 16); - if (code === 0) { - break; - } - str += String.fromCharCode(code); } @@ -1053,7 +1100,7 @@ var fromDecimal = function (value) { * @return {String} */ var toHex = function (val) { - /*jshint maxcomplexity:7 */ + /*jshint maxcomplexity: 8 */ if (isBoolean(val)) return fromDecimal(+val); @@ -1067,9 +1114,11 @@ var toHex = function (val) { // if its a negative number, pass it through fromDecimal if (isString(val)) { if (val.indexOf('-0x') === 0) - return fromDecimal(val); + return fromDecimal(val); else if (!isFinite(val)) return fromAscii(val); + else if(val.indexOf('0x') === 0) + return val; } return fromDecimal(val); @@ -1320,6 +1369,7 @@ var isIBAN = function (iban) { module.exports = { padLeft: padLeft, + padRight: padRight, toHex: toHex, toDecimal: toDecimal, fromDecimal: fromDecimal, @@ -1348,7 +1398,7 @@ module.exports = { },{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ module.exports={ - "version": "0.6.0" + "version": "0.7.1" } },{}],9:[function(require,module,exports){ @@ -1434,31 +1484,25 @@ var setupProperties = function (obj, properties) { /// setups web3 object, and it's in-browser executed methods var web3 = {}; web3.providers = {}; +web3.currentProvider = null; web3.version = {}; web3.version.api = version.version; web3.eth = {}; /*jshint maxparams:4 */ -web3.eth.filter = function (fil, eventParams, options, formatter) { - - // if its event, treat it differently - // TODO: simplify and remove - if (fil._isEvent) { - return fil(eventParams, options); - } - - // output logs works for blockFilter and pendingTransaction filters? - return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter); +web3.eth.filter = function (fil, callback) { + return new Filter(fil, watches.eth(), formatters.outputLogFormatter, callback); }; /*jshint maxparams:3 */ web3.shh = {}; -web3.shh.filter = function (fil) { - return new Filter(fil, watches.shh(), formatters.outputPostFormatter); +web3.shh.filter = function (fil, callback) { + return new Filter(fil, watches.shh(), formatters.outputPostFormatter, callback); }; web3.net = {}; web3.db = {}; web3.setProvider = function (provider) { + this.currentProvider = provider; RequestManager.getInstance().setProvider(provider); }; web3.reset = function () { @@ -1531,7 +1575,90 @@ setupMethods(web3.shh, shh.methods); module.exports = web3; -},{"./utils/config":5,"./utils/sha3":6,"./utils/utils":7,"./version.json":8,"./web3/batch":10,"./web3/db":12,"./web3/eth":14,"./web3/filter":16,"./web3/formatters":17,"./web3/method":22,"./web3/net":24,"./web3/property":25,"./web3/requestmanager":27,"./web3/shh":28,"./web3/watches":30}],10:[function(require,module,exports){ +},{"./utils/config":5,"./utils/sha3":6,"./utils/utils":7,"./version.json":8,"./web3/batch":11,"./web3/db":13,"./web3/eth":15,"./web3/filter":17,"./web3/formatters":18,"./web3/method":23,"./web3/net":25,"./web3/property":26,"./web3/requestmanager":28,"./web3/shh":29,"./web3/watches":31}],10:[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 allevents.js + * @author Marek Kotewicz + * @date 2014 + */ + +var sha3 = require('../utils/sha3'); +var SolidityEvent = require('./event'); +var formatters = require('./formatters'); +var utils = require('../utils/utils'); +var Filter = require('./filter'); +var watches = require('./watches'); + +var AllSolidityEvents = function (json, address) { + this._json = json; + this._address = address; +}; + +AllSolidityEvents.prototype.encode = function (options) { + options = options || {}; + var result = {}; + + ['fromBlock', 'toBlock'].filter(function (f) { + return options[f] !== undefined; + }).forEach(function (f) { + result[f] = formatters.inputBlockNumberFormatter(options[f]); + }); + + result.topics = [null, null, null, null, null]; // match all topics + result.address = this._address; + + return result; +}; + +AllSolidityEvents.prototype.decode = function (data) { + data.data = data.data || ''; + data.topics = data.topics || []; + + var eventTopic = data.topics[0].slice(2); + var match = this._json.filter(function (j) { + return eventTopic === sha3(utils.transformToFullName(j)); + })[0]; + + if (!match) { // cannot find matching event? + console.warn('cannot find event for log'); + return data; + } + + var event = new SolidityEvent(match, this._address); + return event.decode(data); +}; + +AllSolidityEvents.prototype.execute = function (options, callback) { + var o = this.encode(options); + var formatter = this.decode.bind(this); + return new Filter(o, watches.eth(), formatter, callback); +}; + +AllSolidityEvents.prototype.attachToContract = function (contract) { + var execute = this.execute.bind(this); + contract.allEvents = execute; +}; + +module.exports = AllSolidityEvents; + + +},{"../utils/sha3":6,"../utils/utils":7,"./event":16,"./filter":17,"./formatters":18,"./watches":31}],11:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1594,7 +1721,7 @@ Batch.prototype.execute = function () { module.exports = Batch; -},{"./requestmanager":27}],11:[function(require,module,exports){ +},{"./requestmanager":28}],12:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1622,6 +1749,7 @@ var utils = require('../utils/utils'); var coder = require('../solidity/coder'); var SolidityEvent = require('./event'); var SolidityFunction = require('./function'); +var AllEvents = require('./allevents'); /** * Should be called to encode constructor params @@ -1667,9 +1795,14 @@ var addFunctionsToContract = function (contract, abi) { * @param {Array} abi */ var addEventsToContract = function (contract, abi) { - abi.filter(function (json) { + var events = abi.filter(function (json) { return json.type === 'event'; - }).map(function (json) { + }); + + var All = new AllEvents(events, contract.address); + All.attachToContract(contract); + + events.map(function (json) { return new SolidityEvent(json, contract.address); }).forEach(function (e) { e.attachToContract(contract); @@ -1776,7 +1909,7 @@ var Contract = function (abi, address) { module.exports = contract; -},{"../solidity/coder":1,"../utils/utils":7,"../web3":9,"./event":15,"./function":18}],12:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":7,"../web3":9,"./allevents":10,"./event":16,"./function":19}],13:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1834,7 +1967,7 @@ module.exports = { methods: methods }; -},{"./method":22}],13:[function(require,module,exports){ +},{"./method":23}],14:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1874,7 +2007,7 @@ module.exports = { }; -},{}],14:[function(require,module,exports){ +},{}],15:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2159,7 +2292,7 @@ module.exports = { }; -},{"../utils/utils":7,"./formatters":17,"./method":22,"./property":25}],15:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":18,"./method":23,"./property":26}],16:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2184,9 +2317,10 @@ module.exports = { var utils = require('../utils/utils'); var coder = require('../solidity/coder'); -var web3 = require('../web3'); var formatters = require('./formatters'); var sha3 = require('../utils/sha3'); +var Filter = require('./filter'); +var watches = require('./watches'); /** * This prototype should be used to create event filters @@ -2332,10 +2466,21 @@ SolidityEvent.prototype.decode = function (data) { * @param {Object} options * @return {Object} filter object */ -SolidityEvent.prototype.execute = function (indexed, options) { +SolidityEvent.prototype.execute = function (indexed, options, callback) { + + if (utils.isFunction(arguments[arguments.length - 1])) { + callback = arguments[arguments.length - 1]; + if(arguments.length === 2) + options = null; + if(arguments.length === 1) { + options = null; + indexed = {}; + } + } + var o = this.encode(indexed, options); var formatter = this.decode.bind(this); - return web3.eth.filter(o, undefined, undefined, formatter); + return new Filter(o, watches.eth(), formatter, callback); }; /** @@ -2356,7 +2501,7 @@ SolidityEvent.prototype.attachToContract = function (contract) { module.exports = SolidityEvent; -},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":17}],16:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"./filter":17,"./formatters":18,"./watches":31}],17:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2486,7 +2631,7 @@ var pollFilter = function(self) { }; -var Filter = function (options, methods, formatter) { +var Filter = function (options, methods, formatter, callback) { var self = this; var implementation = {}; methods.forEach(function (method) { @@ -2494,23 +2639,32 @@ var Filter = function (options, methods, formatter) { }); this.options = getOptions(options); this.implementation = implementation; + this.filterId = null; this.callbacks = []; this.pollFilters = []; this.formatter = formatter; this.implementation.newFilter(this.options, function(error, id){ if(error) { - self.callbacks.forEach(function(callback){ - callback(error); + self.callbacks.forEach(function(cb){ + cb(error); }); } else { self.filterId = id; - // get filter logs at start - self.callbacks.forEach(function(callback){ - getLogsAtStart(self, callback); + + // get filter logs for the already existing watch calls + self.callbacks.forEach(function(cb){ + getLogsAtStart(self, cb); }); - pollFilter(self); + if(self.callbacks.length > 0) + pollFilter(self); + + // start to watch immediately + if(callback) { + return self.watch(callback); + } } }); + }; Filter.prototype.watch = function (callback) { @@ -2556,7 +2710,7 @@ Filter.prototype.get = function (callback) { module.exports = Filter; -},{"../utils/utils":7,"./formatters":17,"./requestmanager":27}],17:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":18,"./requestmanager":28}],18:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2778,7 +2932,7 @@ module.exports = { }; -},{"../utils/config":5,"../utils/utils":7}],18:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":7}],19:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2969,8 +3123,9 @@ SolidityFunction.prototype.request = function () { var format = this.unpackOutput.bind(this); return { + method: this._constant ? 'eth_call' : 'eth_sendTransaction', callback: callback, - payload: payload, + params: [payload], format: format }; }; @@ -3014,7 +3169,7 @@ SolidityFunction.prototype.attachToContract = function (contract) { module.exports = SolidityFunction; -},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":17}],19:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":18}],20:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3041,7 +3196,8 @@ module.exports = SolidityFunction; "use strict"; -var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line +// resolves the problem for electron/atom shell environments, which use node integration, but have no process variable available +var XMLHttpRequest = (typeof window !== 'undefined' && window.XMLHttpRequest) ? window.XMLHttpRequest : require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line var errors = require('./errors'); var HttpProvider = function (host) { @@ -3108,7 +3264,7 @@ HttpProvider.prototype.sendAsync = function (payload, callback) { module.exports = HttpProvider; -},{"./errors":13,"xmlhttprequest":4}],20:[function(require,module,exports){ +},{"./errors":14,"xmlhttprequest":4}],21:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3218,7 +3374,7 @@ ICAP.prototype.address = function () { module.exports = ICAP; -},{"../utils/utils":7}],21:[function(require,module,exports){ +},{"../utils/utils":7}],22:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3311,7 +3467,7 @@ Jsonrpc.prototype.toBatchPayload = function (messages) { module.exports = Jsonrpc; -},{}],22:[function(require,module,exports){ +},{}],23:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3485,7 +3641,7 @@ Method.prototype.send = function () { module.exports = Method; -},{"../utils/utils":7,"./errors":13,"./requestmanager":27}],23:[function(require,module,exports){ +},{"../utils/utils":7,"./errors":14,"./requestmanager":28}],24:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3533,7 +3689,7 @@ var abi = [ module.exports = contract(abi).at(address); -},{"./contract":11}],24:[function(require,module,exports){ +},{"./contract":12}],25:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3583,7 +3739,7 @@ module.exports = { }; -},{"../utils/utils":7,"./property":25}],25:[function(require,module,exports){ +},{"../utils/utils":7,"./property":26}],26:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3701,7 +3857,7 @@ Property.prototype.getAsync = function (callback) { module.exports = Property; -},{"./requestmanager":27}],26:[function(require,module,exports){ +},{"./requestmanager":28}],27:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3736,7 +3892,7 @@ QtSyncProvider.prototype.send = function (payload) { module.exports = QtSyncProvider; -},{}],27:[function(require,module,exports){ +},{}],28:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4001,7 +4157,7 @@ RequestManager.prototype.poll = function () { module.exports = RequestManager; -},{"../utils/config":5,"../utils/utils":7,"./errors":13,"./jsonrpc":21}],28:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":7,"./errors":14,"./jsonrpc":22}],29:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4071,7 +4227,7 @@ module.exports = { }; -},{"./formatters":17,"./method":22}],29:[function(require,module,exports){ +},{"./formatters":18,"./method":23}],30:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4167,7 +4323,7 @@ var deposit = function (from, address, value, client, callback) { module.exports = transfer; -},{"../web3":9,"./contract":11,"./icap":20,"./namereg":23}],30:[function(require,module,exports){ +},{"../web3":9,"./contract":12,"./icap":21,"./namereg":24}],31:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4283,9 +4439,9 @@ module.exports = { }; -},{"./method":22}],31:[function(require,module,exports){ +},{"./method":23}],32:[function(require,module,exports){ -},{}],32:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS @@ -5028,7 +5184,7 @@ module.exports = { return CryptoJS; })); -},{}],33:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ ;(function (root, factory, undef) { if (typeof exports === "object") { // CommonJS @@ -5352,7 +5508,7 @@ module.exports = { return CryptoJS.SHA3; })); -},{"./core":32,"./x64-core":34}],34:[function(require,module,exports){ +},{"./core":33,"./x64-core":35}],35:[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS @@ -5657,7 +5813,7 @@ module.exports = { return CryptoJS; })); -},{"./core":32}],"bignumber.js":[function(require,module,exports){ +},{"./core":33}],"bignumber.js":[function(require,module,exports){ 'use strict'; module.exports = BigNumber; // jshint ignore:line @@ -5679,5 +5835,5 @@ if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { module.exports = web3; -},{"./lib/web3":9,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/namereg":23,"./lib/web3/qtsync":26,"./lib/web3/transfer":29}]},{},["web3"]) +},{"./lib/web3":9,"./lib/web3/contract":12,"./lib/web3/httpprovider":20,"./lib/web3/namereg":24,"./lib/web3/qtsync":27,"./lib/web3/transfer":30}]},{},["web3"]) //# sourceMappingURL=web3-light.js.map diff --git a/libjsqrc/ethereumjs/dist/web3-light.min.js b/libjsqrc/ethereumjs/dist/web3-light.min.js index 962e16e5f..9907881ad 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,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":7,"./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":7,"./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||void 0!==this.offset},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),0)},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)),0)},e.exports=o},{"../utils/utils":7}],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","femtoether","picoether","nanoether","microether","milliether","nano","micro","milli","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:500,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],6:[function(t,e,n){var r=t("./utils"),o=t("crypto-js/sha3");e.exports=function(t,e){return"0x"!==t.substr(0,2)||e||(console.warn("requirement of using web3.fromAscii before sha3 is deprecated"),console.warn("new usage: 'web3.sha3(\"hello\")'"),console.warn("see https://github.com/ethereum/web3.js/pull/205"),console.warn("if you need to hash hex value, you can do 'sha3(\"0xfff\", true)'"),t=r.toAscii(t)),o(t,{outputLength:256}).toString()}},{"./utils":7,"crypto-js/sha3":33}],7:[function(t,e,n){var r=t("bignumber.js"),o={wei:"1",kwei:"1000",ada:"1000",femtoether:"1000",mwei:"1000000",babbage:"1000000",picoether:"1000000",gwei:"1000000000",shannon:"1000000000",nanoether:"1000000000",nano:"1000000000",szabo:"1000000000000",microether:"1000000000000",micro:"1000000000000",finney:"1000000000000000",milliether:"1000000000000000",milli:"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])?a.inputDefaultBlockNumberFormatter(t.pop()):void 0},u.prototype.toPayload=function(t){var e={};return t.length>this._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},u.prototype.signature=function(){return s(this._name).slice(0,8)},u.prototype.unpackOutput=function(t){if(t){t=t.length>=2?t.slice(2):t;var e=o.decodeParams(this._outputTypes,t);return 1===e.length?e[0]:e}},u.prototype.call=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.extractDefaultBlock(t),o=this.toPayload(t);if(!e){var i=r.eth.call(o,n);return this.unpackOutput(i)}var a=this;r.eth.call(o,n,function(t,n){e(t,a.unpackOutput(n))})},u.prototype.sendTransaction=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.sendTransaction(n,e):r.eth.sendTransaction(n)},u.prototype.estimateGas=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.estimateGas(n,e):r.eth.estimateGas(n)},u.prototype.displayName=function(){return i.extractDisplayName(this._name)},u.prototype.typeName=function(){return i.extractTypeName(this._name)},u.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}},u.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))},u.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),e.estimateGas=this.estimateGas.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=u},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":17}],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),e.setRequestHeader("Content-type","application/json");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),n.setRequestHeader("Content-type","application/json");try{n.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":13,xmlhttprequest:4}],20:[function(t,e,n){var r=t("../utils/utils"),o=function(t){this._iban=t};o.prototype.isValid=function(){return r.isIBAN(this._iban)},o.prototype.isDirect=function(){return 34===this._iban.length},o.prototype.isIndirect=function(){return 20===this._iban.length},o.prototype.checksum=function(){return this._iban.substr(2,2)},o.prototype.institution=function(){return this.isIndirect()?this._iban.substr(7,4):""},o.prototype.client=function(){return this.isIndirect()?this._iban.substr(11):""},o.prototype.address=function(){return this.isDirect()?this._iban.substr(4):""},e.exports=o},{"../utils/utils":7}],21:[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},{}],22:[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":7,"./errors":13,"./requestmanager":27}],23:[function(t,e,n){var r=t("./contract"),o="0xc6d9d2cd449a754c494264e1809c50e34d64562b",i=[{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"name",outputs:[{name:"o_name",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"owner",outputs:[{name:"",type:"address"}],type:"function"},{constant:!0, -inputs:[{name:"_name",type:"bytes32"}],name:"content",outputs:[{name:"",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"addr",outputs:[{name:"",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"reserve",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"subRegistrar",outputs:[{name:"o_subRegistrar",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_newOwner",type:"address"}],name:"transfer",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_registrar",type:"address"}],name:"setSubRegistrar",outputs:[],type:"function"},{constant:!1,inputs:[],name:"Registrar",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_a",type:"address"},{name:"_primary",type:"bool"}],name:"setAddress",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_content",type:"bytes32"}],name:"setContent",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"disown",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"register",outputs:[{name:"",type:"address"}],type:"function"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"}],name:"Changed",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"},{indexed:!0,name:"addr",type:"address"}],name:"PrimaryChanged",type:"event"}];e.exports=r(i).at(o)},{"./contract":11}],24:[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":7,"./property":25}],25:[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":27}],26:[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},{}],27:[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.isPolling=!1))};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,this.provider&&!this.isPolling&&(this.poll(),this.isPolling=!0)},s.prototype.startPolling=function(t,e,n,r){this.polls["poll_"+e]={data:t,id:e,callback:n,uninstall:r}},s.prototype.stopPolling=function(t){delete this.polls["poll_"+t]},s.prototype.reset=function(){for(var t in this.polls)this.polls[t].uninstall();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),0!==Object.keys(this.polls).length){if(!this.provider)return void console.error(a.InvalidProvider());var t=[],e=[];for(var n in this.polls)t.push(this.polls[n].data),e.push(n);if(0!==t.length){var s=r.getInstance().toBatchPayload(t),u=this;this.provider.sendAsync(s,function(t,n){if(!t){if(!o.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){var r=e[n];return u.polls[r]?(t.callback=u.polls[r].callback,t):!1}).filter(function(t){return!!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":7,"./errors":13,"./jsonrpc":21}],28:[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":22}],29:[function(t,e,n){var r=t("../web3"),o=t("./icap"),i=t("./namereg"),a=t("./contract"),s=function(t,e,n,r){var a=new o(e);if(!a.isValid())throw new Error("invalid iban address");if(a.isDirect())return u(t,a.address(),n,r);if(!r){var s=i.addr(a.institution());return c(t,s,n,a.client())}i.addr(a.insitution(),function(e,o){return c(t,o,n,a.client(),r)})},u=function(t,e,n,o){return r.eth.sendTransaction({address:e,from:t,value:n},o)},c=function(t,e,n,r,o){var i=[{constant:!1,inputs:[{name:"name",type:"bytes32"}],name:"deposit",outputs:[],type:"function"}];return a(i).at(e).deposit(r,{from:t,value:n},o)};e.exports=s},{"../web3":9,"./contract":11,"./icap":20,"./namereg":23}],30:[function(t,e,n){var r=t("./method"),o=function(){var t=function(t){var e=t[0];switch(e){case"latest":return t.shift(),this.params=0,"eth_newBlockFilter";case"pending":return t.shift(),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":22}],31:[function(t,e,n){},{}],32:[function(t,e,n){!function(t,r){"object"==typeof n?e.exports=n=r():"function"==typeof define&&define.amd?define([],r):t.CryptoJS=r()}(this,function(){var t=t||function(t,e){var n={},r=n.lib={},o=r.Base=function(){function t(){}return{extend:function(e){t.prototype=this;var n=new t;return e&&n.mixIn(e),n.hasOwnProperty("init")||(n.init=function(){n.$super.init.apply(this,arguments)}),n.init.prototype=n,n.$super=this,n},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),i=r.WordArray=o.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:4*t.length},toString:function(t){return(t||s).stringify(this)},concat:function(t){var e=this.words,n=t.words,r=this.sigBytes,o=t.sigBytes;if(this.clamp(),r%4)for(var i=0;o>i;i++){var a=n[i>>>2]>>>24-i%4*8&255;e[r+i>>>2]|=a<<24-(r+i)%4*8}else for(var i=0;o>i;i+=4)e[r+i>>>2]=n[i>>>2];return this.sigBytes+=o,this},clamp:function(){var e=this.words,n=this.sigBytes;e[n>>>2]&=4294967295<<32-n%4*8,e.length=t.ceil(n/4)},clone:function(){var t=o.clone.call(this);return t.words=this.words.slice(0),t},random:function(e){for(var n,r=[],o=function(e){var e=e,n=987654321,r=4294967295;return function(){n=36969*(65535&n)+(n>>16)&r,e=18e3*(65535&e)+(e>>16)&r;var o=(n<<16)+e&r;return o/=4294967296,o+=.5,o*(t.random()>.5?1:-1)}},a=0;e>a;a+=4){var s=o(4294967296*(n||t.random()));n=987654071*s(),r.push(4294967296*s()|0)}return new i.init(r,e)}}),a=n.enc={},s=a.Hex={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],o=0;n>o;o++){var i=e[o>>>2]>>>24-o%4*8&255;r.push((i>>>4).toString(16)),r.push((15&i).toString(16))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r+=2)n[r>>>3]|=parseInt(t.substr(r,2),16)<<24-r%8*4;return new i.init(n,e/2)}},u=a.Latin1={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],o=0;n>o;o++){var i=e[o>>>2]>>>24-o%4*8&255;r.push(String.fromCharCode(i))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r++)n[r>>>2]|=(255&t.charCodeAt(r))<<24-r%4*8;return new i.init(n,e)}},c=a.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},l=r.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=c.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(e){var n=this._data,r=n.words,o=n.sigBytes,a=this.blockSize,s=4*a,u=o/s;u=e?t.ceil(u):t.max((0|u)-this._minBufferSize,0);var c=u*a,l=t.min(4*c,o);if(c){for(var p=0;c>p;p+=a)this._doProcessBlock(r,p);var f=r.splice(0,c);n.sigBytes-=l}return new i.init(f,l)},clone:function(){var t=o.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),p=(r.Hasher=l.extend({cfg:o.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){l.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){t&&this._append(t);var e=this._doFinalize();return e},blockSize:16,_createHelper:function(t){return function(e,n){return new t.init(n).finalize(e)}},_createHmacHelper:function(t){return function(e,n){return new p.HMAC.init(t,n).finalize(e)}}}),n.algo={});return n}(Math);return t})},{}],33:[function(t,e,n){!function(r,o,i){"object"==typeof n?e.exports=n=o(t("./core"),t("./x64-core")):"function"==typeof define&&define.amd?define(["./core","./x64-core"],o):o(r.CryptoJS)}(this,function(t){return function(e){var n=t,r=n.lib,o=r.WordArray,i=r.Hasher,a=n.x64,s=a.Word,u=n.algo,c=[],l=[],p=[];!function(){for(var t=1,e=0,n=0;24>n;n++){c[t+5*e]=(n+1)*(n+2)/2%64;var r=e%5,o=(2*t+3*e)%5;t=r,e=o}for(var t=0;5>t;t++)for(var e=0;5>e;e++)l[t+5*e]=e+(2*t+3*e)%5*5;for(var i=1,a=0;24>a;a++){for(var u=0,f=0,m=0;7>m;m++){if(1&i){var h=(1<h?f^=1<t;t++)f[t]=s.create()}();var m=u.SHA3=i.extend({cfg:i.cfg.extend({outputLength:512}),_doReset:function(){for(var t=this._state=[],e=0;25>e;e++)t[e]=new s.init;this.blockSize=(1600-2*this.cfg.outputLength)/32},_doProcessBlock:function(t,e){for(var n=this._state,r=this.blockSize/2,o=0;r>o;o++){var i=t[e+2*o],a=t[e+2*o+1];i=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),a=16711935&(a<<8|a>>>24)|4278255360&(a<<24|a>>>8);var s=n[o];s.high^=a,s.low^=i}for(var u=0;24>u;u++){for(var m=0;5>m;m++){for(var h=0,d=0,y=0;5>y;y++){var s=n[m+5*y];h^=s.high,d^=s.low}var g=f[m];g.high=h,g.low=d}for(var m=0;5>m;m++)for(var v=f[(m+4)%5],b=f[(m+1)%5],w=b.high,_=b.low,h=v.high^(w<<1|_>>>31),d=v.low^(_<<1|w>>>31),y=0;5>y;y++){var s=n[m+5*y];s.high^=h,s.low^=d}for(var x=1;25>x;x++){var s=n[x],F=s.high,B=s.low,I=c[x];if(32>I)var h=F<>>32-I,d=B<>>32-I;else var h=B<>>64-I,d=F<>>64-I;var k=f[l[x]];k.high=h,k.low=d}var N=f[0],P=n[0];N.high=P.high,N.low=P.low;for(var m=0;5>m;m++)for(var y=0;5>y;y++){var x=m+5*y,s=n[x],A=f[x],O=f[(m+1)%5+5*y],T=f[(m+2)%5+5*y];s.high=A.high^~O.high&T.high,s.low=A.low^~O.low&T.low}var s=n[0],D=p[u];s.high^=D.high,s.low^=D.low}},_doFinalize:function(){var t=this._data,n=t.words,r=(8*this._nDataBytes,8*t.sigBytes),i=32*this.blockSize;n[r>>>5]|=1<<24-r%32,n[(e.ceil((r+1)/i)*i>>>5)-1]|=128,t.sigBytes=4*n.length,this._process();for(var a=this._state,s=this.cfg.outputLength/8,u=s/8,c=[],l=0;u>l;l++){var p=a[l],f=p.high,m=p.low;f=16711935&(f<<8|f>>>24)|4278255360&(f<<24|f>>>8),m=16711935&(m<<8|m>>>24)|4278255360&(m<<24|m>>>8),c.push(m),c.push(f)}return new o.init(c,s)},clone:function(){for(var t=i.clone.call(this),e=t._state=this._state.slice(0),n=0;25>n;n++)e[n]=e[n].clone();return t}});n.SHA3=i._createHelper(m),n.HmacSHA3=i._createHmacHelper(m)}(Math),t.SHA3})},{"./core":32,"./x64-core":34}],34:[function(t,e,n){!function(r,o){"object"==typeof n?e.exports=n=o(t("./core")):"function"==typeof define&&define.amd?define(["./core"],o):o(r.CryptoJS)}(this,function(t){return function(e){{var n=t,r=n.lib,o=r.Base,i=r.WordArray,a=n.x64={};a.Word=o.extend({init:function(t,e){this.high=t,this.low=e}}),a.WordArray=o.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:8*t.length},toX32:function(){for(var t=this.words,e=t.length,n=[],r=0;e>r;r++){var o=t[r];n.push(o.high),n.push(o.low)}return i.create(n,this.sigBytes)},clone:function(){for(var t=o.clone.call(this),e=t.words=this.words.slice(0),n=e.length,r=0;n>r;r++)e[r]=e[r].clone();return t}})}}(),t})},{"./core":32}],"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"),r.eth.namereg=t("./lib/web3/namereg"),r.eth.sendIBANTransaction=t("./lib/web3/transfer"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/web3":9,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/namereg":23,"./lib/web3/qtsync":26,"./lib/web3/transfer":29}]},{},["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:"string",match:"strict",mode:"bytes",inputFormatter:i.formatInputString,outputFormatter:i.formatOutputString}),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":7,"./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.padRight(o.toHex(t).substr(2),64);return new a(e)},c=function(t){t=o.toHex(t).substr(2);var e=Math.floor((t.length+63)/64),n=o.padRight(t,64*e),r=Math.floor(t.length/2);return new a(s(r).value+n,32)},l=function(t){var e=o.fromAscii(t).substr(2),n=Math.floor((e.length+63)/64);return e=o.padRight(e,64*n),new a(s(t.length).value+e,32)},p=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)))},m=function(t){return"1"===new r(t.substr(0,1),16).toString(2).substr(0,1)},h=function(t){var e=t.staticPart()||"0";return m(e)?new r(e,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(e,16)},d=function(t){var e=t.staticPart()||"0";return new r(e,16)},y=function(t){return h(t).dividedBy(new r(2).pow(128))},g=function(t){return d(t).dividedBy(new r(2).pow(128))},v=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},b=function(t){return"0x"+t.staticPart()},w=function(t){var e=2*new r(t.dynamicPart().slice(0,64),16).toNumber();return"0x"+t.dynamicPart().substr(64,e)},_=function(t){var e=2*new r(t.dynamicPart().slice(0,64),16).toNumber();return o.toAscii(t.dynamicPart().substr(64,e))},x=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputString:l,formatInputBool:p,formatInputReal:f,formatOutputInt:h,formatOutputUInt:d,formatOutputReal:y,formatOutputUReal:g,formatOutputBool:v,formatOutputBytes:b,formatOutputDynamicBytes:w,formatOutputString:_,formatOutputAddress:x}},{"../utils/config":5,"../utils/utils":7,"./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||void 0!==this.offset},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),r=parseInt("0x"+t.substr(2*n,64));return r=Math.floor((r+31)/32),new o(t.substr(2*n,64*(1+r)),0)},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)),0)},e.exports=o},{"../utils/utils":7}],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","femtoether","picoether","nanoether","microether","milliether","nano","micro","milli","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:500,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],6:[function(t,e,n){var r=t("./utils"),o=t("crypto-js/sha3");e.exports=function(t,e){return"0x"!==t.substr(0,2)||e||(console.warn("requirement of using web3.fromAscii before sha3 is deprecated"),console.warn("new usage: 'web3.sha3(\"hello\")'"),console.warn("see https://github.com/ethereum/web3.js/pull/205"),console.warn("if you need to hash hex value, you can do 'sha3(\"0xfff\", true)'"),t=r.toAscii(t)),o(t,{outputLength:256}).toString()}},{"./utils":7,"crypto-js/sha3":34}],7:[function(t,e,n){var r=t("bignumber.js"),o={wei:"1",kwei:"1000",ada:"1000",femtoether:"1000",mwei:"1000000",babbage:"1000000",picoether:"1000000",gwei:"1000000000",shannon:"1000000000",nanoether:"1000000000",nano:"1000000000",szabo:"1000000000000",microether:"1000000000000",micro:"1000000000000",finney:"1000000000000000",milliether:"1000000000000000",milli:"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,e,n){return t+new Array(e-t.length+1).join(n?n:"0")},s=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);e+=String.fromCharCode(o)}return e},u=function(t){for(var e="",n=0;n0&&c(o),r)return o.watch(r)})};l.prototype.watch=function(t){return this.callbacks.push(t),this.filterId&&(u(this,t),c(this)),this},l.prototype.stopWatching=function(){r.getInstance().stopPolling(this.filterId),this.implementation.uninstallFilter(this.filterId,function(){}),this.callbacks=[]},l.prototype.get=function(t){var e=this;if(!i.isFunction(t)){var n=this.implementation.getLogs(this.filterId);return n.map(function(t){return e.formatter?e.formatter(t):t})}return this.implementation.getLogs(this.filterId,function(n,r){n?t(n):t(null,r.map(function(t){return e.formatter?e.formatter(t):t}))}),this},e.exports=l},{"../utils/utils":7,"./formatters":18,"./requestmanager":28}],18:[function(t,e,n){var r=t("../utils/utils"),o=t("../utils/config"),i=function(t){return r.toBigNumber(t)},a=function(t){return"latest"===t||"pending"===t||"earliest"===t},s=function(t){return void 0===t?o.defaultBlock:u(t)},u=function(t){return void 0===t?void 0:a(t)?t:r.toHex(t)},c=function(t){return t.from=t.from||o.defaultAccount,t.code&&(t.data=t.code,delete t.code),["gasPrice","gas","value","nonce"].filter(function(e){return void 0!==t[e]}).forEach(function(e){t[e]=r.fromDecimal(t[e])}),t},l=function(t){return null!==t.blockNumber&&(t.blockNumber=r.toDecimal(t.blockNumber)),null!==t.transactionIndex&&(t.transactionIndex=r.toDecimal(t.transactionIndex)),t.nonce=r.toDecimal(t.nonce),t.gas=r.toDecimal(t.gas),t.gasPrice=r.toBigNumber(t.gasPrice),t.value=r.toBigNumber(t.value),t},p=function(t){return t.gasLimit=r.toDecimal(t.gasLimit),t.gasUsed=r.toDecimal(t.gasUsed),t.size=r.toDecimal(t.size),t.timestamp=r.toDecimal(t.timestamp),null!==t.number&&(t.number=r.toDecimal(t.number)),t.difficulty=r.toBigNumber(t.difficulty),t.totalDifficulty=r.toBigNumber(t.totalDifficulty),r.isArray(t.transactions)&&t.transactions.forEach(function(t){return r.isString(t)?void 0:l(t)}),t},f=function(t){return null!==t.blockNumber&&(t.blockNumber=r.toDecimal(t.blockNumber)),null!==t.transactionIndex&&(t.transactionIndex=r.toDecimal(t.transactionIndex)),null!==t.logIndex&&(t.logIndex=r.toDecimal(t.logIndex)),t},m=function(t){return t.payload=r.toHex(t.payload),t.ttl=r.fromDecimal(t.ttl),t.workToProve=r.fromDecimal(t.workToProve),t.priority=r.fromDecimal(t.priority),r.isArray(t.topics)||(t.topics=t.topics?[t.topics]:[]),t.topics=t.topics.map(function(t){return r.fromAscii(t)}),t},h=function(t){return t.expiry=r.toDecimal(t.expiry),t.sent=r.toDecimal(t.sent),t.ttl=r.toDecimal(t.ttl),t.workProved=r.toDecimal(t.workProved),t.payloadRaw=t.payload,t.payload=r.toAscii(t.payload),r.isJson(t.payload)&&(t.payload=JSON.parse(t.payload)),t.topics||(t.topics=[]),t.topics=t.topics.map(function(t){return r.toAscii(t)}),t};e.exports={inputDefaultBlockNumberFormatter:s,inputBlockNumberFormatter:u,inputTransactionFormatter:c,inputPostFormatter:m,outputBigNumberFormatter:i,outputTransactionFormatter:l,outputBlockFormatter:p,outputLogFormatter:f,outputPostFormatter:h}},{"../utils/config":5,"../utils/utils":7}],19:[function(t,e,n){var r=t("../web3"),o=t("../solidity/coder"),i=t("../utils/utils"),a=t("./formatters"),s=t("../utils/sha3"),u=function(t,e){this._inputTypes=t.inputs.map(function(t){return t.type}),this._outputTypes=t.outputs.map(function(t){return t.type}),this._constant=t.constant,this._name=i.transformToFullName(t),this._address=e};u.prototype.extractCallback=function(t){return i.isFunction(t[t.length-1])?t.pop():void 0},u.prototype.extractDefaultBlock=function(t){return t.length>this._inputTypes.length&&!i.isObject(t[t.length-1])?a.inputDefaultBlockNumberFormatter(t.pop()):void 0},u.prototype.toPayload=function(t){var e={};return t.length>this._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},u.prototype.signature=function(){return s(this._name).slice(0,8)},u.prototype.unpackOutput=function(t){if(t){t=t.length>=2?t.slice(2):t;var e=o.decodeParams(this._outputTypes,t);return 1===e.length?e[0]:e}},u.prototype.call=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.extractDefaultBlock(t),o=this.toPayload(t);if(!e){var i=r.eth.call(o,n);return this.unpackOutput(i)}var a=this;r.eth.call(o,n,function(t,n){e(t,a.unpackOutput(n))})},u.prototype.sendTransaction=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.sendTransaction(n,e):r.eth.sendTransaction(n)},u.prototype.estimateGas=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.estimateGas(n,e):r.eth.estimateGas(n)},u.prototype.displayName=function(){return i.extractDisplayName(this._name)},u.prototype.typeName=function(){return i.extractTypeName(this._name)},u.prototype.request=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t),r=this.unpackOutput.bind(this);return{method:this._constant?"eth_call":"eth_sendTransaction",callback:e,params:[n],format:r}},u.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))},u.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),e.estimateGas=this.estimateGas.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=u},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":18}],20:[function(t,e,n){"use strict";var r="undefined"!=typeof window&&window.XMLHttpRequest?window.XMLHttpRequest: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),e.setRequestHeader("Content-type","application/json");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),n.setRequestHeader("Content-type","application/json");try{n.send(JSON.stringify(t))}catch(i){e(o.InvalidConnection(this.host))}},e.exports=i},{"./errors":14,xmlhttprequest:4}],21:[function(t,e,n){var r=t("../utils/utils"),o=function(t){this._iban=t};o.prototype.isValid=function(){return r.isIBAN(this._iban)},o.prototype.isDirect=function(){return 34===this._iban.length},o.prototype.isIndirect=function(){return 20===this._iban.length},o.prototype.checksum=function(){return this._iban.substr(2,2)},o.prototype.institution=function(){return this.isIndirect()?this._iban.substr(7,4):""},o.prototype.client=function(){return this.isIndirect()?this._iban.substr(11):""},o.prototype.address=function(){return this.isDirect()?this._iban.substr(4):""},e.exports=o},{"../utils/utils":7}],22:[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},{}],23:[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":7,"./errors":14,"./requestmanager":28}],24:[function(t,e,n){var r=t("./contract"),o="0xc6d9d2cd449a754c494264e1809c50e34d64562b",i=[{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"name",outputs:[{name:"o_name",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"owner",outputs:[{name:"",type:"address"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"content",outputs:[{name:"",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"addr",outputs:[{name:"",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"reserve",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"subRegistrar",outputs:[{name:"o_subRegistrar",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_newOwner",type:"address"}],name:"transfer",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_registrar",type:"address"}],name:"setSubRegistrar",outputs:[],type:"function"},{constant:!1,inputs:[],name:"Registrar",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_a",type:"address"},{name:"_primary",type:"bool"}],name:"setAddress",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_content",type:"bytes32"}],name:"setContent",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"disown",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"register",outputs:[{name:"",type:"address"}],type:"function"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"}],name:"Changed",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"},{indexed:!0,name:"addr",type:"address"}],name:"PrimaryChanged",type:"event"}];e.exports=r(i).at(o)},{"./contract":12}],25:[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":7,"./property":26}],26:[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":28}],27:[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},{}],28:[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.isPolling=!1))};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,this.provider&&!this.isPolling&&(this.poll(),this.isPolling=!0)},s.prototype.startPolling=function(t,e,n,r){this.polls["poll_"+e]={data:t,id:e,callback:n,uninstall:r}},s.prototype.stopPolling=function(t){delete this.polls["poll_"+t]},s.prototype.reset=function(){for(var t in this.polls)this.polls[t].uninstall();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),0!==Object.keys(this.polls).length){if(!this.provider)return void console.error(a.InvalidProvider());var t=[],e=[];for(var n in this.polls)t.push(this.polls[n].data),e.push(n);if(0!==t.length){var s=r.getInstance().toBatchPayload(t),u=this;this.provider.sendAsync(s,function(t,n){if(!t){if(!o.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){var r=e[n];return u.polls[r]?(t.callback=u.polls[r].callback,t):!1}).filter(function(t){return!!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":7,"./errors":14,"./jsonrpc":22}],29:[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":18,"./method":23}],30:[function(t,e,n){var r=t("../web3"),o=t("./icap"),i=t("./namereg"),a=t("./contract"),s=function(t,e,n,r){var a=new o(e);if(!a.isValid())throw new Error("invalid iban address");if(a.isDirect())return u(t,a.address(),n,r);if(!r){var s=i.addr(a.institution());return c(t,s,n,a.client())}i.addr(a.insitution(),function(e,o){return c(t,o,n,a.client(),r)})},u=function(t,e,n,o){return r.eth.sendTransaction({address:e,from:t,value:n},o)},c=function(t,e,n,r,o){var i=[{constant:!1,inputs:[{name:"name",type:"bytes32"}],name:"deposit",outputs:[],type:"function"}];return a(i).at(e).deposit(r,{from:t,value:n},o)};e.exports=s},{"../web3":9,"./contract":12,"./icap":21,"./namereg":24}],31:[function(t,e,n){var r=t("./method"),o=function(){var t=function(t){var e=t[0];switch(e){case"latest":return t.shift(),this.params=0,"eth_newBlockFilter";case"pending":return t.shift(),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":23}],32:[function(t,e,n){},{}],33:[function(t,e,n){!function(t,r){"object"==typeof n?e.exports=n=r():"function"==typeof define&&define.amd?define([],r):t.CryptoJS=r()}(this,function(){var t=t||function(t,e){var n={},r=n.lib={},o=r.Base=function(){function t(){}return{extend:function(e){t.prototype=this;var n=new t;return e&&n.mixIn(e),n.hasOwnProperty("init")||(n.init=function(){n.$super.init.apply(this,arguments)}),n.init.prototype=n,n.$super=this,n},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),i=r.WordArray=o.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:4*t.length},toString:function(t){return(t||s).stringify(this)},concat:function(t){var e=this.words,n=t.words,r=this.sigBytes,o=t.sigBytes;if(this.clamp(),r%4)for(var i=0;o>i;i++){var a=n[i>>>2]>>>24-i%4*8&255;e[r+i>>>2]|=a<<24-(r+i)%4*8}else for(var i=0;o>i;i+=4)e[r+i>>>2]=n[i>>>2];return this.sigBytes+=o,this},clamp:function(){var e=this.words,n=this.sigBytes;e[n>>>2]&=4294967295<<32-n%4*8,e.length=t.ceil(n/4)},clone:function(){var t=o.clone.call(this);return t.words=this.words.slice(0),t},random:function(e){for(var n,r=[],o=function(e){var e=e,n=987654321,r=4294967295;return function(){n=36969*(65535&n)+(n>>16)&r,e=18e3*(65535&e)+(e>>16)&r;var o=(n<<16)+e&r;return o/=4294967296,o+=.5,o*(t.random()>.5?1:-1)}},a=0;e>a;a+=4){var s=o(4294967296*(n||t.random()));n=987654071*s(),r.push(4294967296*s()|0)}return new i.init(r,e)}}),a=n.enc={},s=a.Hex={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],o=0;n>o;o++){var i=e[o>>>2]>>>24-o%4*8&255;r.push((i>>>4).toString(16)),r.push((15&i).toString(16))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r+=2)n[r>>>3]|=parseInt(t.substr(r,2),16)<<24-r%8*4;return new i.init(n,e/2)}},u=a.Latin1={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],o=0;n>o;o++){var i=e[o>>>2]>>>24-o%4*8&255;r.push(String.fromCharCode(i))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r++)n[r>>>2]|=(255&t.charCodeAt(r))<<24-r%4*8;return new i.init(n,e)}},c=a.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},l=r.BufferedBlockAlgorithm=o.extend({reset:function(){this._data=new i.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=c.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(e){var n=this._data,r=n.words,o=n.sigBytes,a=this.blockSize,s=4*a,u=o/s;u=e?t.ceil(u):t.max((0|u)-this._minBufferSize,0);var c=u*a,l=t.min(4*c,o);if(c){for(var p=0;c>p;p+=a)this._doProcessBlock(r,p);var f=r.splice(0,c);n.sigBytes-=l}return new i.init(f,l)},clone:function(){var t=o.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),p=(r.Hasher=l.extend({cfg:o.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){l.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){t&&this._append(t);var e=this._doFinalize();return e},blockSize:16,_createHelper:function(t){return function(e,n){return new t.init(n).finalize(e)}},_createHmacHelper:function(t){return function(e,n){return new p.HMAC.init(t,n).finalize(e)}}}),n.algo={});return n}(Math);return t})},{}],34:[function(t,e,n){!function(r,o,i){"object"==typeof n?e.exports=n=o(t("./core"),t("./x64-core")):"function"==typeof define&&define.amd?define(["./core","./x64-core"],o):o(r.CryptoJS)}(this,function(t){return function(e){var n=t,r=n.lib,o=r.WordArray,i=r.Hasher,a=n.x64,s=a.Word,u=n.algo,c=[],l=[],p=[];!function(){for(var t=1,e=0,n=0;24>n;n++){c[t+5*e]=(n+1)*(n+2)/2%64;var r=e%5,o=(2*t+3*e)%5;t=r,e=o}for(var t=0;5>t;t++)for(var e=0;5>e;e++)l[t+5*e]=e+(2*t+3*e)%5*5;for(var i=1,a=0;24>a;a++){for(var u=0,f=0,m=0;7>m;m++){if(1&i){var h=(1<h?f^=1<t;t++)f[t]=s.create()}();var m=u.SHA3=i.extend({cfg:i.cfg.extend({outputLength:512}),_doReset:function(){for(var t=this._state=[],e=0;25>e;e++)t[e]=new s.init;this.blockSize=(1600-2*this.cfg.outputLength)/32},_doProcessBlock:function(t,e){for(var n=this._state,r=this.blockSize/2,o=0;r>o;o++){var i=t[e+2*o],a=t[e+2*o+1];i=16711935&(i<<8|i>>>24)|4278255360&(i<<24|i>>>8),a=16711935&(a<<8|a>>>24)|4278255360&(a<<24|a>>>8);var s=n[o];s.high^=a,s.low^=i}for(var u=0;24>u;u++){for(var m=0;5>m;m++){for(var h=0,d=0,y=0;5>y;y++){var s=n[m+5*y];h^=s.high,d^=s.low}var g=f[m];g.high=h,g.low=d}for(var m=0;5>m;m++)for(var v=f[(m+4)%5],b=f[(m+1)%5],w=b.high,_=b.low,h=v.high^(w<<1|_>>>31),d=v.low^(_<<1|w>>>31),y=0;5>y;y++){var s=n[m+5*y];s.high^=h,s.low^=d}for(var x=1;25>x;x++){var s=n[x],F=s.high,B=s.low,I=c[x];if(32>I)var h=F<>>32-I,d=B<>>32-I;else var h=B<>>64-I,d=F<>>64-I;var k=f[l[x]];k.high=h,k.low=d}var N=f[0],P=n[0];N.high=P.high,N.low=P.low;for(var m=0;5>m;m++)for(var y=0;5>y;y++){var x=m+5*y,s=n[x],O=f[x],T=f[(m+1)%5+5*y],A=f[(m+2)%5+5*y];s.high=O.high^~T.high&A.high,s.low=O.low^~T.low&A.low}var s=n[0],D=p[u];s.high^=D.high,s.low^=D.low}},_doFinalize:function(){var t=this._data,n=t.words,r=(8*this._nDataBytes,8*t.sigBytes),i=32*this.blockSize;n[r>>>5]|=1<<24-r%32,n[(e.ceil((r+1)/i)*i>>>5)-1]|=128,t.sigBytes=4*n.length,this._process();for(var a=this._state,s=this.cfg.outputLength/8,u=s/8,c=[],l=0;u>l;l++){var p=a[l],f=p.high,m=p.low;f=16711935&(f<<8|f>>>24)|4278255360&(f<<24|f>>>8),m=16711935&(m<<8|m>>>24)|4278255360&(m<<24|m>>>8),c.push(m),c.push(f)}return new o.init(c,s)},clone:function(){for(var t=i.clone.call(this),e=t._state=this._state.slice(0),n=0;25>n;n++)e[n]=e[n].clone();return t}});n.SHA3=i._createHelper(m),n.HmacSHA3=i._createHmacHelper(m)}(Math),t.SHA3})},{"./core":33,"./x64-core":35}],35:[function(t,e,n){!function(r,o){"object"==typeof n?e.exports=n=o(t("./core")):"function"==typeof define&&define.amd?define(["./core"],o):o(r.CryptoJS)}(this,function(t){return function(e){{var n=t,r=n.lib,o=r.Base,i=r.WordArray,a=n.x64={};a.Word=o.extend({init:function(t,e){this.high=t,this.low=e}}),a.WordArray=o.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:8*t.length},toX32:function(){for(var t=this.words,e=t.length,n=[],r=0;e>r;r++){var o=t[r];n.push(o.high),n.push(o.low)}return i.create(n,this.sigBytes)},clone:function(){for(var t=o.clone.call(this),e=t.words=this.words.slice(0),n=e.length,r=0;n>r;r++)e[r]=e[r].clone();return t}})}}(),t})},{"./core":33}],"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"),r.eth.namereg=t("./lib/web3/namereg"),r.eth.sendIBANTransaction=t("./lib/web3/transfer"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/web3":9,"./lib/web3/contract":12,"./lib/web3/httpprovider":20,"./lib/web3/namereg":24,"./lib/web3/qtsync":27,"./lib/web3/transfer":30}]},{},["web3"]); \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/web3.js b/libjsqrc/ethereumjs/dist/web3.js index 70b096cf1..402bcd64f 100644 --- a/libjsqrc/ethereumjs/dist/web3.js +++ b/libjsqrc/ethereumjs/dist/web3.js @@ -263,6 +263,13 @@ var coder = new SolidityCoder([ inputFormatter: f.formatInputBytes, outputFormatter: f.formatOutputBytes }), + new SolidityType({ + name: 'string', + match: 'strict', + mode: 'bytes', + inputFormatter: f.formatInputString, + outputFormatter: f.formatOutputString + }), new SolidityType({ name: 'real', match: 'prefix', @@ -328,26 +335,43 @@ var formatInputInt = function (value) { }; /** - * Formats input value to byte representation of string + * Formats input bytes * * @method formatInputBytes * @param {String} * @returns {SolidityParam} */ var formatInputBytes = function (value) { - var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); + var result = utils.padRight(utils.toHex(value).substr(2), 64); return new SolidityParam(result); }; /** - * Formats input value to byte representation of string + * Formats input bytes * - * @method formatInputDynamicBytes + * @method formatDynamicInputBytes * @param {String} * @returns {SolidityParam} */ var formatInputDynamicBytes = function (value) { - var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); + value = utils.toHex(value).substr(2); + var l = Math.floor((value.length + 63) / 64); + var result = utils.padRight(value, l * 64); + var length = Math.floor(value.length / 2); + return new SolidityParam(formatInputInt(length).value + result, 32); +}; + +/** + * Formats input value to byte representation of string + * + * @method formatInputString + * @param {String} + * @returns {SolidityParam} + */ +var formatInputString = function (value) { + var result = utils.fromAscii(value).substr(2); + var l = Math.floor((result.length + 63) / 64); + result = utils.padRight(result, l * 64); return new SolidityParam(formatInputInt(value.length).value + result, 32); }; @@ -450,27 +474,38 @@ var formatOutputBool = function (param) { }; /** - * Should be used to format output string + * Should be used to format output bytes * * @method formatOutputBytes * @param {SolidityParam} left-aligned hex representation of string - * @returns {String} ascii string + * @returns {String} hex string */ var formatOutputBytes = function (param) { - // length might also be important! - return utils.toAscii(param.staticPart()); + return '0x' + param.staticPart(); }; /** - * Should be used to format output string + * Should be used to format output bytes * * @method formatOutputDynamicBytes * @param {SolidityParam} left-aligned hex representation of string - * @returns {String} ascii string + * @returns {String} hex string */ var formatOutputDynamicBytes = function (param) { - // length might also be important! - return utils.toAscii(param.dynamicPart().slice(64)); + var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; + return '0x' + param.dynamicPart().substr(64, length); +}; + +/** + * Should be used to format output string + * + * @method formatOutputString + * @param {SolidityParam} left-aligned hex representation of string + * @returns {String} ascii string + */ +var formatOutputString = function (param) { + var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; + return utils.toAscii(param.dynamicPart().substr(64, length)); }; /** @@ -489,6 +524,7 @@ module.exports = { formatInputInt: formatInputInt, formatInputBytes: formatInputBytes, formatInputDynamicBytes: formatInputDynamicBytes, + formatInputString: formatInputString, formatInputBool: formatInputBool, formatInputReal: formatInputReal, formatOutputInt: formatOutputInt, @@ -498,6 +534,7 @@ module.exports = { formatOutputBool: formatOutputBool, formatOutputBytes: formatOutputBytes, formatOutputDynamicBytes: formatOutputDynamicBytes, + formatOutputString: formatOutputString, formatOutputAddress: formatOutputAddress }; @@ -687,13 +724,14 @@ var getOffset = function (bytes, index) { */ SolidityParam.decodeBytes = function (bytes, index) { index = index || 0; - //TODO add support for strings longer than 32 bytes - //var length = parseInt('0x' + bytes.substr(offset * 64, 64)); var offset = getOffset(bytes, index); - // 2 * , cause we also parse length - return new SolidityParam(bytes.substr(offset * 2, 2 * 64), 0); + var l = parseInt('0x' + bytes.substr(offset * 2, 64)); + l = Math.floor((l + 31) / 32); + + // (1 + l) * , cause we also parse length + return new SolidityParam(bytes.substr(offset * 2, (1 + l) * 64), 0); }; /** @@ -846,7 +884,7 @@ module.exports = function (str, isNew) { }; -},{"./utils":7,"crypto-js/sha3":33}],7:[function(require,module,exports){ +},{"./utils":7,"crypto-js/sha3":34}],7:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -924,6 +962,19 @@ var padLeft = function (string, chars, sign) { return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; }; +/** + * Should be called to pad string to expected length + * + * @method padRight + * @param {String} string to be padded + * @param {Number} characters that result string should have + * @param {String} sign, by default 0 + * @returns {String} right aligned string + */ +var padRight = function (string, chars, sign) { + return string + (new Array(chars - string.length + 1).join(sign ? sign : "0")); +}; + /** * Should be called to get sting from it's hex representation * @@ -940,10 +991,6 @@ var toAscii = function(hex) { } for (; i < l; i+=2) { var code = parseInt(hex.substr(i, 2), 16); - if (code === 0) { - break; - } - str += String.fromCharCode(code); } @@ -1053,7 +1100,7 @@ var fromDecimal = function (value) { * @return {String} */ var toHex = function (val) { - /*jshint maxcomplexity:7 */ + /*jshint maxcomplexity: 8 */ if (isBoolean(val)) return fromDecimal(+val); @@ -1067,9 +1114,11 @@ var toHex = function (val) { // if its a negative number, pass it through fromDecimal if (isString(val)) { if (val.indexOf('-0x') === 0) - return fromDecimal(val); + return fromDecimal(val); else if (!isFinite(val)) return fromAscii(val); + else if(val.indexOf('0x') === 0) + return val; } return fromDecimal(val); @@ -1320,6 +1369,7 @@ var isIBAN = function (iban) { module.exports = { padLeft: padLeft, + padRight: padRight, toHex: toHex, toDecimal: toDecimal, fromDecimal: fromDecimal, @@ -1348,7 +1398,7 @@ module.exports = { },{"bignumber.js":"bignumber.js"}],8:[function(require,module,exports){ module.exports={ - "version": "0.6.0" + "version": "0.7.1" } },{}],9:[function(require,module,exports){ @@ -1434,31 +1484,25 @@ var setupProperties = function (obj, properties) { /// setups web3 object, and it's in-browser executed methods var web3 = {}; web3.providers = {}; +web3.currentProvider = null; web3.version = {}; web3.version.api = version.version; web3.eth = {}; /*jshint maxparams:4 */ -web3.eth.filter = function (fil, eventParams, options, formatter) { - - // if its event, treat it differently - // TODO: simplify and remove - if (fil._isEvent) { - return fil(eventParams, options); - } - - // output logs works for blockFilter and pendingTransaction filters? - return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter); +web3.eth.filter = function (fil, callback) { + return new Filter(fil, watches.eth(), formatters.outputLogFormatter, callback); }; /*jshint maxparams:3 */ web3.shh = {}; -web3.shh.filter = function (fil) { - return new Filter(fil, watches.shh(), formatters.outputPostFormatter); +web3.shh.filter = function (fil, callback) { + return new Filter(fil, watches.shh(), formatters.outputPostFormatter, callback); }; web3.net = {}; web3.db = {}; web3.setProvider = function (provider) { + this.currentProvider = provider; RequestManager.getInstance().setProvider(provider); }; web3.reset = function () { @@ -1531,7 +1575,90 @@ setupMethods(web3.shh, shh.methods); module.exports = web3; -},{"./utils/config":5,"./utils/sha3":6,"./utils/utils":7,"./version.json":8,"./web3/batch":10,"./web3/db":12,"./web3/eth":14,"./web3/filter":16,"./web3/formatters":17,"./web3/method":22,"./web3/net":24,"./web3/property":25,"./web3/requestmanager":27,"./web3/shh":28,"./web3/watches":30}],10:[function(require,module,exports){ +},{"./utils/config":5,"./utils/sha3":6,"./utils/utils":7,"./version.json":8,"./web3/batch":11,"./web3/db":13,"./web3/eth":15,"./web3/filter":17,"./web3/formatters":18,"./web3/method":23,"./web3/net":25,"./web3/property":26,"./web3/requestmanager":28,"./web3/shh":29,"./web3/watches":31}],10:[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 allevents.js + * @author Marek Kotewicz + * @date 2014 + */ + +var sha3 = require('../utils/sha3'); +var SolidityEvent = require('./event'); +var formatters = require('./formatters'); +var utils = require('../utils/utils'); +var Filter = require('./filter'); +var watches = require('./watches'); + +var AllSolidityEvents = function (json, address) { + this._json = json; + this._address = address; +}; + +AllSolidityEvents.prototype.encode = function (options) { + options = options || {}; + var result = {}; + + ['fromBlock', 'toBlock'].filter(function (f) { + return options[f] !== undefined; + }).forEach(function (f) { + result[f] = formatters.inputBlockNumberFormatter(options[f]); + }); + + result.topics = [null, null, null, null, null]; // match all topics + result.address = this._address; + + return result; +}; + +AllSolidityEvents.prototype.decode = function (data) { + data.data = data.data || ''; + data.topics = data.topics || []; + + var eventTopic = data.topics[0].slice(2); + var match = this._json.filter(function (j) { + return eventTopic === sha3(utils.transformToFullName(j)); + })[0]; + + if (!match) { // cannot find matching event? + console.warn('cannot find event for log'); + return data; + } + + var event = new SolidityEvent(match, this._address); + return event.decode(data); +}; + +AllSolidityEvents.prototype.execute = function (options, callback) { + var o = this.encode(options); + var formatter = this.decode.bind(this); + return new Filter(o, watches.eth(), formatter, callback); +}; + +AllSolidityEvents.prototype.attachToContract = function (contract) { + var execute = this.execute.bind(this); + contract.allEvents = execute; +}; + +module.exports = AllSolidityEvents; + + +},{"../utils/sha3":6,"../utils/utils":7,"./event":16,"./filter":17,"./formatters":18,"./watches":31}],11:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1594,7 +1721,7 @@ Batch.prototype.execute = function () { module.exports = Batch; -},{"./requestmanager":27}],11:[function(require,module,exports){ +},{"./requestmanager":28}],12:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1622,6 +1749,7 @@ var utils = require('../utils/utils'); var coder = require('../solidity/coder'); var SolidityEvent = require('./event'); var SolidityFunction = require('./function'); +var AllEvents = require('./allevents'); /** * Should be called to encode constructor params @@ -1667,9 +1795,14 @@ var addFunctionsToContract = function (contract, abi) { * @param {Array} abi */ var addEventsToContract = function (contract, abi) { - abi.filter(function (json) { + var events = abi.filter(function (json) { return json.type === 'event'; - }).map(function (json) { + }); + + var All = new AllEvents(events, contract.address); + All.attachToContract(contract); + + events.map(function (json) { return new SolidityEvent(json, contract.address); }).forEach(function (e) { e.attachToContract(contract); @@ -1776,7 +1909,7 @@ var Contract = function (abi, address) { module.exports = contract; -},{"../solidity/coder":1,"../utils/utils":7,"../web3":9,"./event":15,"./function":18}],12:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/utils":7,"../web3":9,"./allevents":10,"./event":16,"./function":19}],13:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1834,7 +1967,7 @@ module.exports = { methods: methods }; -},{"./method":22}],13:[function(require,module,exports){ +},{"./method":23}],14:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1874,7 +2007,7 @@ module.exports = { }; -},{}],14:[function(require,module,exports){ +},{}],15:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2159,7 +2292,7 @@ module.exports = { }; -},{"../utils/utils":7,"./formatters":17,"./method":22,"./property":25}],15:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":18,"./method":23,"./property":26}],16:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2184,9 +2317,10 @@ module.exports = { var utils = require('../utils/utils'); var coder = require('../solidity/coder'); -var web3 = require('../web3'); var formatters = require('./formatters'); var sha3 = require('../utils/sha3'); +var Filter = require('./filter'); +var watches = require('./watches'); /** * This prototype should be used to create event filters @@ -2332,10 +2466,21 @@ SolidityEvent.prototype.decode = function (data) { * @param {Object} options * @return {Object} filter object */ -SolidityEvent.prototype.execute = function (indexed, options) { +SolidityEvent.prototype.execute = function (indexed, options, callback) { + + if (utils.isFunction(arguments[arguments.length - 1])) { + callback = arguments[arguments.length - 1]; + if(arguments.length === 2) + options = null; + if(arguments.length === 1) { + options = null; + indexed = {}; + } + } + var o = this.encode(indexed, options); var formatter = this.decode.bind(this); - return web3.eth.filter(o, undefined, undefined, formatter); + return new Filter(o, watches.eth(), formatter, callback); }; /** @@ -2356,7 +2501,7 @@ SolidityEvent.prototype.attachToContract = function (contract) { module.exports = SolidityEvent; -},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":17}],16:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"./filter":17,"./formatters":18,"./watches":31}],17:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2486,7 +2631,7 @@ var pollFilter = function(self) { }; -var Filter = function (options, methods, formatter) { +var Filter = function (options, methods, formatter, callback) { var self = this; var implementation = {}; methods.forEach(function (method) { @@ -2494,23 +2639,32 @@ var Filter = function (options, methods, formatter) { }); this.options = getOptions(options); this.implementation = implementation; + this.filterId = null; this.callbacks = []; this.pollFilters = []; this.formatter = formatter; this.implementation.newFilter(this.options, function(error, id){ if(error) { - self.callbacks.forEach(function(callback){ - callback(error); + self.callbacks.forEach(function(cb){ + cb(error); }); } else { self.filterId = id; - // get filter logs at start - self.callbacks.forEach(function(callback){ - getLogsAtStart(self, callback); + + // get filter logs for the already existing watch calls + self.callbacks.forEach(function(cb){ + getLogsAtStart(self, cb); }); - pollFilter(self); + if(self.callbacks.length > 0) + pollFilter(self); + + // start to watch immediately + if(callback) { + return self.watch(callback); + } } }); + }; Filter.prototype.watch = function (callback) { @@ -2556,7 +2710,7 @@ Filter.prototype.get = function (callback) { module.exports = Filter; -},{"../utils/utils":7,"./formatters":17,"./requestmanager":27}],17:[function(require,module,exports){ +},{"../utils/utils":7,"./formatters":18,"./requestmanager":28}],18:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2778,7 +2932,7 @@ module.exports = { }; -},{"../utils/config":5,"../utils/utils":7}],18:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":7}],19:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -2969,8 +3123,9 @@ SolidityFunction.prototype.request = function () { var format = this.unpackOutput.bind(this); return { + method: this._constant ? 'eth_call' : 'eth_sendTransaction', callback: callback, - payload: payload, + params: [payload], format: format }; }; @@ -3014,7 +3169,7 @@ SolidityFunction.prototype.attachToContract = function (contract) { module.exports = SolidityFunction; -},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":17}],19:[function(require,module,exports){ +},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":18}],20:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3041,7 +3196,8 @@ module.exports = SolidityFunction; "use strict"; -var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line +// resolves the problem for electron/atom shell environments, which use node integration, but have no process variable available +var XMLHttpRequest = (typeof window !== 'undefined' && window.XMLHttpRequest) ? window.XMLHttpRequest : require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line var errors = require('./errors'); var HttpProvider = function (host) { @@ -3108,7 +3264,7 @@ HttpProvider.prototype.sendAsync = function (payload, callback) { module.exports = HttpProvider; -},{"./errors":13,"xmlhttprequest":4}],20:[function(require,module,exports){ +},{"./errors":14,"xmlhttprequest":4}],21:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3218,7 +3374,7 @@ ICAP.prototype.address = function () { module.exports = ICAP; -},{"../utils/utils":7}],21:[function(require,module,exports){ +},{"../utils/utils":7}],22:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3311,7 +3467,7 @@ Jsonrpc.prototype.toBatchPayload = function (messages) { module.exports = Jsonrpc; -},{}],22:[function(require,module,exports){ +},{}],23:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3485,7 +3641,7 @@ Method.prototype.send = function () { module.exports = Method; -},{"../utils/utils":7,"./errors":13,"./requestmanager":27}],23:[function(require,module,exports){ +},{"../utils/utils":7,"./errors":14,"./requestmanager":28}],24:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3533,7 +3689,7 @@ var abi = [ module.exports = contract(abi).at(address); -},{"./contract":11}],24:[function(require,module,exports){ +},{"./contract":12}],25:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3583,7 +3739,7 @@ module.exports = { }; -},{"../utils/utils":7,"./property":25}],25:[function(require,module,exports){ +},{"../utils/utils":7,"./property":26}],26:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3701,7 +3857,7 @@ Property.prototype.getAsync = function (callback) { module.exports = Property; -},{"./requestmanager":27}],26:[function(require,module,exports){ +},{"./requestmanager":28}],27:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -3736,7 +3892,7 @@ QtSyncProvider.prototype.send = function (payload) { module.exports = QtSyncProvider; -},{}],27:[function(require,module,exports){ +},{}],28:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4001,7 +4157,7 @@ RequestManager.prototype.poll = function () { module.exports = RequestManager; -},{"../utils/config":5,"../utils/utils":7,"./errors":13,"./jsonrpc":21}],28:[function(require,module,exports){ +},{"../utils/config":5,"../utils/utils":7,"./errors":14,"./jsonrpc":22}],29:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4071,7 +4227,7 @@ module.exports = { }; -},{"./formatters":17,"./method":22}],29:[function(require,module,exports){ +},{"./formatters":18,"./method":23}],30:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4167,7 +4323,7 @@ var deposit = function (from, address, value, client, callback) { module.exports = transfer; -},{"../web3":9,"./contract":11,"./icap":20,"./namereg":23}],30:[function(require,module,exports){ +},{"../web3":9,"./contract":12,"./icap":21,"./namereg":24}],31:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -4283,9 +4439,9 @@ module.exports = { }; -},{"./method":22}],31:[function(require,module,exports){ +},{"./method":23}],32:[function(require,module,exports){ -},{}],32:[function(require,module,exports){ +},{}],33:[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS @@ -5028,7 +5184,7 @@ module.exports = { return CryptoJS; })); -},{}],33:[function(require,module,exports){ +},{}],34:[function(require,module,exports){ ;(function (root, factory, undef) { if (typeof exports === "object") { // CommonJS @@ -5352,7 +5508,7 @@ module.exports = { return CryptoJS.SHA3; })); -},{"./core":32,"./x64-core":34}],34:[function(require,module,exports){ +},{"./core":33,"./x64-core":35}],35:[function(require,module,exports){ ;(function (root, factory) { if (typeof exports === "object") { // CommonJS @@ -5657,7 +5813,7 @@ module.exports = { return CryptoJS; })); -},{"./core":32}],"bignumber.js":[function(require,module,exports){ +},{"./core":33}],"bignumber.js":[function(require,module,exports){ /*! bignumber.js v2.0.7 https://github.com/MikeMcl/bignumber.js/LICENCE */ ;(function (global) { @@ -8342,7 +8498,7 @@ module.exports = { } })(this); -},{"crypto":31}],"web3":[function(require,module,exports){ +},{"crypto":32}],"web3":[function(require,module,exports){ var web3 = require('./lib/web3'); web3.providers.HttpProvider = require('./lib/web3/httpprovider'); web3.providers.QtSyncProvider = require('./lib/web3/qtsync'); @@ -8358,5 +8514,5 @@ if (typeof window !== 'undefined' && typeof window.web3 === 'undefined') { module.exports = web3; -},{"./lib/web3":9,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/namereg":23,"./lib/web3/qtsync":26,"./lib/web3/transfer":29}]},{},["web3"]) +},{"./lib/web3":9,"./lib/web3/contract":12,"./lib/web3/httpprovider":20,"./lib/web3/namereg":24,"./lib/web3/qtsync":27,"./lib/web3/transfer":30}]},{},["web3"]) //# sourceMappingURL=web3.js.map diff --git a/libjsqrc/ethereumjs/dist/web3.js.map b/libjsqrc/ethereumjs/dist/web3.js.map index b000cdd4b..f67aad1c2 100644 --- a/libjsqrc/ethereumjs/dist/web3.js.map +++ b/libjsqrc/ethereumjs/dist/web3.js.map @@ -11,6 +11,7 @@ "lib/utils/utils.js", "lib/version.json", "lib/web3.js", + "lib/web3/allevents.js", "lib/web3/batch.js", "lib/web3/contract.js", "lib/web3/db.js", @@ -40,30 +41,31 @@ "index.js" ], "names": [], - "mappings": "AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClfA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;ACruBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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/SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnNA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9fA;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;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;;AC1LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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/MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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/MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;AC9CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;AC9FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;ACruBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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/SA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;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 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 || this.offset !== undefined;\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), 0);\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), 0);\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 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: 'string',\n match: 'strict',\n mode: 'bytes',\n inputFormatter: f.formatInputString,\n outputFormatter: f.formatOutputString\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 bytes\n *\n * @method formatInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputBytes = function (value) {\n var result = utils.padRight(utils.toHex(value).substr(2), 64);\n return new SolidityParam(result);\n};\n\n/**\n * Formats input bytes\n *\n * @method formatDynamicInputBytes\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputDynamicBytes = function (value) {\n value = utils.toHex(value).substr(2);\n var l = Math.floor((value.length + 63) / 64);\n var result = utils.padRight(value, l * 64);\n var length = Math.floor(value.length / 2);\n return new SolidityParam(formatInputInt(length).value + result, 32);\n};\n\n/**\n * Formats input value to byte representation of string\n *\n * @method formatInputString\n * @param {String}\n * @returns {SolidityParam}\n */\nvar formatInputString = function (value) {\n var result = utils.fromAscii(value).substr(2);\n var l = Math.floor((result.length + 63) / 64);\n result = utils.padRight(result, l * 64);\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 bytes\n *\n * @method formatOutputBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} hex string\n */\nvar formatOutputBytes = function (param) {\n return '0x' + param.staticPart();\n};\n\n/**\n * Should be used to format output bytes\n *\n * @method formatOutputDynamicBytes\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} hex string\n */\nvar formatOutputDynamicBytes = function (param) {\n var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2;\n return '0x' + param.dynamicPart().substr(64, length);\n};\n\n/**\n * Should be used to format output string\n *\n * @method formatOutputString\n * @param {SolidityParam} left-aligned hex representation of string\n * @returns {String} ascii string\n */\nvar formatOutputString = function (param) {\n var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2;\n return utils.toAscii(param.dynamicPart().substr(64, length));\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 formatInputString: formatInputString,\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 formatOutputString: formatOutputString,\n formatOutputAddress: formatOutputAddress\n};\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** \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 || this.offset !== undefined;\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\n var offset = getOffset(bytes, index);\n\n var l = parseInt('0x' + bytes.substr(offset * 2, 64));\n l = Math.floor((l + 31) / 32);\n\n // (1 + l) * , cause we also parse length\n return new SolidityParam(bytes.substr(offset * 2, (1 + l) * 64), 0);\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), 0);\n};\n\nmodule.exports = SolidityParam;\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 'femtoether',\n 'picoether',\n 'nanoether',\n 'microether',\n 'milliether',\n 'nano',\n 'micro',\n 'milli',\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/2,\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 sha3.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('./utils');\nvar sha3 = require('crypto-js/sha3');\n\nmodule.exports = function (str, isNew) {\n if (str.substr(0, 2) === '0x' && !isNew) {\n console.warn('requirement of using web3.fromAscii before sha3 is deprecated');\n console.warn('new usage: \\'web3.sha3(\"hello\")\\'');\n console.warn('see https://github.com/ethereum/web3.js/pull/205');\n console.warn('if you need to hash hex value, you can do \\'sha3(\"0xfff\", true)\\'');\n str = utils.toAscii(str);\n }\n\n return sha3(str, {\n outputLength: 256\n }).toString();\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 'femtoether': '1000',\n 'mwei': '1000000',\n 'babbage': '1000000',\n 'picoether': '1000000',\n 'gwei': '1000000000',\n 'shannon': '1000000000',\n 'nanoether': '1000000000',\n 'nano': '1000000000',\n 'szabo': '1000000000000',\n 'microether': '1000000000000',\n 'micro': '1000000000000',\n 'finney': '1000000000000000',\n 'milliether': '1000000000000000',\n 'milli': '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 * SI Short SI Full Effigy Other\n * - kwei femtoether ada\n * - mwei picoether babbage\n * - gwei nanoether shannon nano\n * - -- microether szabo micro\n * - -- milliether finney milli\n * - ether -- --\n * - kether einstein grand \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 * SI Short SI Full Effigy Other\n * - kwei femtoether ada\n * - mwei picoether babbage \n * - gwei nanoether shannon nano\n * - -- microether szabo micro\n * - -- milliether finney milli\n * - ether -- --\n * - kether einstein grand \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\n/**\n * This method should be called to check if string is valid ethereum IBAN number\n * Supports direct and indirect IBANs\n *\n * @method isIBAN\n * @param {String}\n * @return {Boolean}\n */\nvar isIBAN = function (iban) {\n return /^XE[0-9]{2}(ETH[0-9A-Z]{13}|[0-9A-Z]{30})$/.test(iban);\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 isIBAN: isIBAN\n};\n\n", - "module.exports={\n \"version\": \"0.6.0\"\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 Property = require('./web3/property');\nvar Batch = require('./web3/batch');\nvar sha3 = require('./utils/sha3');\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 // output logs works for blockFilter and pendingTransaction filters?\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.isIBAN = utils.isIBAN;\nweb3.sha3 = sha3;\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\n// EXTEND\nweb3._extend = function(extension){\n /*jshint maxcomplexity: 6 */\n\n if(extension.property && !web3[extension.property])\n web3[extension.property] = {};\n\n setupMethods(web3[extension.property] || web3, extension.methods || []);\n setupProperties(web3[extension.property] || web3, extension.properties || []);\n};\nweb3._extend.formatters = formatters;\nweb3._extend.utils = utils;\nweb3._extend.Method = require('./web3/method');\nweb3._extend.Property = require('./web3/property');\n\n\n/// setups all api methods\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 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 'femtoether': '1000',\n 'mwei': '1000000',\n 'babbage': '1000000',\n 'picoether': '1000000',\n 'gwei': '1000000000',\n 'shannon': '1000000000',\n 'nanoether': '1000000000',\n 'nano': '1000000000',\n 'szabo': '1000000000000',\n 'microether': '1000000000000',\n 'micro': '1000000000000',\n 'finney': '1000000000000000',\n 'milliether': '1000000000000000',\n 'milli': '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 pad string to expected length\n *\n * @method padRight\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 padRight = function (string, chars, sign) {\n return string + (new Array(chars - string.length + 1).join(sign ? sign : \"0\"));\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 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: 8 */\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 else if(val.indexOf('0x') === 0)\n return 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 * SI Short SI Full Effigy Other\n * - kwei femtoether ada\n * - mwei picoether babbage\n * - gwei nanoether shannon nano\n * - -- microether szabo micro\n * - -- milliether finney milli\n * - ether -- --\n * - kether einstein grand \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 * SI Short SI Full Effigy Other\n * - kwei femtoether ada\n * - mwei picoether babbage \n * - gwei nanoether shannon nano\n * - -- microether szabo micro\n * - -- milliether finney milli\n * - ether -- --\n * - kether einstein grand \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\n/**\n * This method should be called to check if string is valid ethereum IBAN number\n * Supports direct and indirect IBANs\n *\n * @method isIBAN\n * @param {String}\n * @return {Boolean}\n */\nvar isIBAN = function (iban) {\n return /^XE[0-9]{2}(ETH[0-9A-Z]{13}|[0-9A-Z]{30})$/.test(iban);\n};\n\nmodule.exports = {\n padLeft: padLeft,\n padRight: padRight,\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 isIBAN: isIBAN\n};\n\n", + "module.exports={\n \"version\": \"0.7.1\"\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 Property = require('./web3/property');\nvar Batch = require('./web3/batch');\nvar sha3 = require('./utils/sha3');\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.currentProvider = null;\nweb3.version = {};\nweb3.version.api = version.version;\nweb3.eth = {};\n\n/*jshint maxparams:4 */\nweb3.eth.filter = function (fil, callback) {\n return new Filter(fil, watches.eth(), formatters.outputLogFormatter, callback);\n};\n/*jshint maxparams:3 */\n\nweb3.shh = {};\nweb3.shh.filter = function (fil, callback) {\n return new Filter(fil, watches.shh(), formatters.outputPostFormatter, callback);\n};\nweb3.net = {};\nweb3.db = {};\nweb3.setProvider = function (provider) {\n this.currentProvider = 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.isIBAN = utils.isIBAN;\nweb3.sha3 = sha3;\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\n// EXTEND\nweb3._extend = function(extension){\n /*jshint maxcomplexity: 6 */\n\n if(extension.property && !web3[extension.property])\n web3[extension.property] = {};\n\n setupMethods(web3[extension.property] || web3, extension.methods || []);\n setupProperties(web3[extension.property] || web3, extension.properties || []);\n};\nweb3._extend.formatters = formatters;\nweb3._extend.utils = utils;\nweb3._extend.Method = require('./web3/method');\nweb3._extend.Property = require('./web3/property');\n\n\n/// setups all api methods\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 allevents.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar sha3 = require('../utils/sha3');\nvar SolidityEvent = require('./event');\nvar formatters = require('./formatters');\nvar utils = require('../utils/utils');\nvar Filter = require('./filter');\nvar watches = require('./watches');\n\nvar AllSolidityEvents = function (json, address) {\n this._json = json;\n this._address = address;\n};\n\nAllSolidityEvents.prototype.encode = function (options) {\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 = [null, null, null, null, null]; // match all topics\n result.address = this._address;\n\n return result;\n};\n\nAllSolidityEvents.prototype.decode = function (data) {\n data.data = data.data || '';\n data.topics = data.topics || [];\n\n var eventTopic = data.topics[0].slice(2);\n var match = this._json.filter(function (j) {\n return eventTopic === sha3(utils.transformToFullName(j));\n })[0];\n\n if (!match) { // cannot find matching event?\n console.warn('cannot find event for log');\n return data;\n }\n\n var event = new SolidityEvent(match, this._address);\n return event.decode(data);\n};\n\nAllSolidityEvents.prototype.execute = function (options, callback) {\n var o = this.encode(options);\n var formatter = this.decode.bind(this);\n return new Filter(o, watches.eth(), formatter, callback);\n};\n\nAllSolidityEvents.prototype.attachToContract = function (contract) {\n var execute = this.execute.bind(this);\n contract.allEvents = execute;\n};\n\nmodule.exports = AllSolidityEvents;\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/** \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');\nvar AllEvents = require('./allevents');\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 var events = abi.filter(function (json) {\n return json.type === 'event';\n });\n\n var All = new AllEvents(events, contract.address);\n All.attachToContract(contract);\n \n events.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 sendRawTransaction = new Method({\n name: 'sendRawTransaction',\n call: 'eth_sendRawTransaction',\n params: 1,\n inputFormatter: []\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 sendRawTransaction,\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');\nvar sha3 = require('../utils/sha3');\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 sha3(this._name);\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\n/**\nAdds the callback and sets up the methods, to iterate over the results.\n\n@method getLogsAtStart\n@param {Object} self\n@param {funciton} \n*/\nvar getLogsAtStart = function(self, callback){\n // call getFilterLogs for the first watch callback start\n if (!utils.isString(self.options)) {\n self.get(function (err, messages) {\n // don't send all the responses to all the watches again... just to self one\n if (err) {\n callback(err);\n }\n\n messages.forEach(function (message) {\n callback(null, message);\n });\n });\n }\n};\n\n/**\nAdds the callback and sets up the methods, to iterate over the results.\n\n@method pollFilter\n@param {Object} self\n*/\nvar pollFilter = function(self) {\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 RequestManager.getInstance().startPolling({\n method: self.implementation.poll.call,\n params: [self.filterId],\n }, self.filterId, onMessage, self.stopWatching.bind(self));\n\n};\n\nvar Filter = function (options, methods, formatter) {\n var self = this;\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.pollFilters = [];\n this.formatter = formatter;\n this.implementation.newFilter(this.options, function(error, id){\n if(error) {\n self.callbacks.forEach(function(callback){\n callback(error);\n });\n } else {\n self.filterId = id;\n // get filter logs at start\n self.callbacks.forEach(function(callback){\n getLogsAtStart(self, callback);\n });\n pollFilter(self);\n }\n });\n};\n\nFilter.prototype.watch = function (callback) {\n this.callbacks.push(callback);\n\n if(this.filterId) {\n getLogsAtStart(this, callback);\n pollFilter(this);\n }\n\n return this;\n};\n\nFilter.prototype.stopWatching = function () {\n RequestManager.getInstance().stopPolling(this.filterId);\n // remove filter async\n this.implementation.uninstallFilter(this.filterId, function(){});\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 return this;\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 event.js\n * @author Marek Kotewicz \n * @date 2014\n */\n\nvar utils = require('../utils/utils');\nvar coder = require('../solidity/coder');\nvar formatters = require('./formatters');\nvar sha3 = require('../utils/sha3');\nvar Filter = require('./filter');\nvar watches = require('./watches');\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 sha3(this._name);\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, callback) {\n\n if (utils.isFunction(arguments[arguments.length - 1])) {\n callback = arguments[arguments.length - 1];\n if(arguments.length === 2)\n options = null;\n if(arguments.length === 1) {\n options = null;\n indexed = {};\n }\n }\n \n var o = this.encode(indexed, options);\n var formatter = this.decode.bind(this);\n return new Filter(o, watches.eth(), formatter, callback);\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\n/**\nAdds the callback and sets up the methods, to iterate over the results.\n\n@method getLogsAtStart\n@param {Object} self\n@param {funciton} \n*/\nvar getLogsAtStart = function(self, callback){\n // call getFilterLogs for the first watch callback start\n if (!utils.isString(self.options)) {\n self.get(function (err, messages) {\n // don't send all the responses to all the watches again... just to self one\n if (err) {\n callback(err);\n }\n\n messages.forEach(function (message) {\n callback(null, message);\n });\n });\n }\n};\n\n/**\nAdds the callback and sets up the methods, to iterate over the results.\n\n@method pollFilter\n@param {Object} self\n*/\nvar pollFilter = function(self) {\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 RequestManager.getInstance().startPolling({\n method: self.implementation.poll.call,\n params: [self.filterId],\n }, self.filterId, onMessage, self.stopWatching.bind(self));\n\n};\n\nvar Filter = function (options, methods, formatter, callback) {\n var self = this;\n var implementation = {};\n methods.forEach(function (method) {\n method.attachToObject(implementation);\n });\n this.options = getOptions(options);\n this.implementation = implementation;\n this.filterId = null;\n this.callbacks = [];\n this.pollFilters = [];\n this.formatter = formatter;\n this.implementation.newFilter(this.options, function(error, id){\n if(error) {\n self.callbacks.forEach(function(cb){\n cb(error);\n });\n } else {\n self.filterId = id;\n\n // get filter logs for the already existing watch calls\n self.callbacks.forEach(function(cb){\n getLogsAtStart(self, cb);\n });\n if(self.callbacks.length > 0)\n pollFilter(self);\n\n // start to watch immediately\n if(callback) {\n return self.watch(callback);\n }\n }\n });\n\n};\n\nFilter.prototype.watch = function (callback) {\n this.callbacks.push(callback);\n\n if(this.filterId) {\n getLogsAtStart(this, callback);\n pollFilter(this);\n }\n\n return this;\n};\n\nFilter.prototype.stopWatching = function () {\n RequestManager.getInstance().stopPolling(this.filterId);\n // remove filter async\n this.implementation.uninstallFilter(this.filterId, function(){});\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 return this;\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 if(tx.blockNumber !== null)\n tx.blockNumber = utils.toDecimal(tx.blockNumber);\n if(tx.transactionIndex !== null)\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 if(block.number !== null)\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.blockNumber !== null)\n log.blockNumber = utils.toDecimal(log.blockNumber);\n if(log.transactionIndex !== null)\n log.transactionIndex = utils.toDecimal(log.transactionIndex);\n if(log.logIndex !== null)\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');\nvar formatters = require('./formatters');\nvar sha3 = require('../utils/sha3');\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\nSolidityFunction.prototype.extractDefaultBlock = function (args) {\n if (args.length > this._inputTypes.length && !utils.isObject(args[args.length -1])) {\n return formatters.inputDefaultBlockNumberFormatter(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 sha3(this._name).slice(0, 8);\n};\n\n\nSolidityFunction.prototype.unpackOutput = function (output) {\n if (!output) {\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).filter(function (a) {return a !== undefined; });\n var callback = this.extractCallback(args);\n var defaultBlock = this.extractDefaultBlock(args);\n var payload = this.toPayload(args);\n\n\n if (!callback) {\n var output = web3.eth.call(payload, defaultBlock);\n return this.unpackOutput(output);\n } \n \n var self = this;\n web3.eth.call(payload, defaultBlock, 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).filter(function (a) {return a !== undefined; });\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n\n if (!callback) {\n return web3.eth.sendTransaction(payload);\n }\n\n web3.eth.sendTransaction(payload, callback);\n};\n\n/**\n * Should be used to estimateGas of solidity function\n *\n * @method estimateGas\n * @param {Object} options\n */\nSolidityFunction.prototype.estimateGas = 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 return web3.eth.estimateGas(payload);\n }\n\n web3.eth.estimateGas(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 execute.estimateGas = this.estimateGas.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 request.setRequestHeader('Content-type','application/json');\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 request.setRequestHeader('Content-type','application/json');\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/**\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');\nvar formatters = require('./formatters');\nvar sha3 = require('../utils/sha3');\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\nSolidityFunction.prototype.extractDefaultBlock = function (args) {\n if (args.length > this._inputTypes.length && !utils.isObject(args[args.length -1])) {\n return formatters.inputDefaultBlockNumberFormatter(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 sha3(this._name).slice(0, 8);\n};\n\n\nSolidityFunction.prototype.unpackOutput = function (output) {\n if (!output) {\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).filter(function (a) {return a !== undefined; });\n var callback = this.extractCallback(args);\n var defaultBlock = this.extractDefaultBlock(args);\n var payload = this.toPayload(args);\n\n\n if (!callback) {\n var output = web3.eth.call(payload, defaultBlock);\n return this.unpackOutput(output);\n } \n \n var self = this;\n web3.eth.call(payload, defaultBlock, 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).filter(function (a) {return a !== undefined; });\n var callback = this.extractCallback(args);\n var payload = this.toPayload(args);\n\n if (!callback) {\n return web3.eth.sendTransaction(payload);\n }\n\n web3.eth.sendTransaction(payload, callback);\n};\n\n/**\n * Should be used to estimateGas of solidity function\n *\n * @method estimateGas\n * @param {Object} options\n */\nSolidityFunction.prototype.estimateGas = 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 return web3.eth.estimateGas(payload);\n }\n\n web3.eth.estimateGas(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 method: this._constant ? 'eth_call' : 'eth_sendTransaction',\n callback: callback,\n params: [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 execute.estimateGas = this.estimateGas.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\n// resolves the problem for electron/atom shell environments, which use node integration, but have no process variable available\nvar XMLHttpRequest = (typeof window !== 'undefined' && window.XMLHttpRequest) ? window.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 request.setRequestHeader('Content-type','application/json');\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 request.setRequestHeader('Content-type','application/json');\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/** \n * @file icap.js\n * @author Marek Kotewicz \n * @date 2015\n */\n\nvar utils = require('../utils/utils');\n\n/**\n * This prototype should be used to extract necessary information from iban address\n *\n * @param {String} iban\n */\nvar ICAP = function (iban) {\n this._iban = iban;\n};\n\n/**\n * Should be called to check if icap is correct\n *\n * @method isValid\n * @returns {Boolean} true if it is, otherwise false\n */\nICAP.prototype.isValid = function () {\n return utils.isIBAN(this._iban);\n};\n\n/**\n * Should be called to check if iban number is direct\n *\n * @method isDirect\n * @returns {Boolean} true if it is, otherwise false\n */\nICAP.prototype.isDirect = function () {\n return this._iban.length === 34;\n};\n\n/**\n * Should be called to check if iban number if indirect\n *\n * @method isIndirect\n * @returns {Boolean} true if it is, otherwise false\n */\nICAP.prototype.isIndirect = function () {\n return this._iban.length === 20;\n};\n\n/**\n * Should be called to get iban checksum\n * Uses the mod-97-10 checksumming protocol (ISO/IEC 7064:2003)\n *\n * @method checksum\n * @returns {String} checksum\n */\nICAP.prototype.checksum = function () {\n return this._iban.substr(2, 2);\n};\n\n/**\n * Should be called to get institution identifier\n * eg. XREG\n *\n * @method institution\n * @returns {String} institution identifier\n */\nICAP.prototype.institution = function () {\n return this.isIndirect() ? this._iban.substr(7, 4) : '';\n};\n\n/**\n * Should be called to get client identifier within institution\n * eg. GAVOFYORK\n *\n * @method client\n * @returns {String} client identifier\n */\nICAP.prototype.client = function () {\n return this.isIndirect() ? this._iban.substr(11) : '';\n};\n\n/**\n * Should be called to get client direct address\n *\n * @method address\n * @returns {String} client direct address\n */\nICAP.prototype.address = function () {\n return this.isDirect() ? this._iban.substr(4) : '';\n};\n\nmodule.exports = ICAP;\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};\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", diff --git a/libjsqrc/ethereumjs/dist/web3.min.js b/libjsqrc/ethereumjs/dist/web3.min.js index a73cde830..3d9c300e8 100644 --- a/libjsqrc/ethereumjs/dist/web3.min.js +++ b/libjsqrc/ethereumjs/dist/web3.min.js @@ -1,2 +1,4 @@ -require=function t(e,n,r){function i(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(o)return o(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 i(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;ao;o+=64)n.push(this._outputFormatter(new a(t.dynamicPart().substr(o+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 i=n._requireType(t),o=i.sliceParam(e,r,t);return i.formatOutput(o,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:o.formatInputBool,outputFormatter:o.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:o.formatInputDynamicBytes,outputFormatter:o.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:o.formatInputBytes,outputFormatter:o.formatOutputBytes}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:o.formatInputReal,outputFormatter:o.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:o.formatInputReal,outputFormatter:o.formatOutputUReal})]);e.exports=l},{"../utils/utils":7,"./formatters":2,"./param":3,"bignumber.js":"bignumber.js"}],2:[function(t,e,n){var r=t("bignumber.js"),i=t("../utils/utils"),o=t("../utils/config"),a=t("./param"),s=function(t){var e=2*o.ETH_PADDING;r.config(o.ETH_BIGNUMBER_ROUNDING_MODE);var n=i.padLeft(i.toTwosComplement(t).round().toString(16),e);return new a(n)},u=function(t){var e=i.fromAscii(t,o.ETH_PADDING).substr(2);return new a(e)},c=function(t){var e=i.fromAscii(t,o.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)},h=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)},m=function(t){var e=t.staticPart()||"0";return new r(e,16)},d=function(t){return h(t).dividedBy(new r(2).pow(128))},g=function(t){return m(t).dividedBy(new r(2).pow(128))},y=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},v=function(t){return i.toAscii(t.staticPart())},b=function(t){return i.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:h,formatOutputUInt:m,formatOutputReal:d,formatOutputUReal:g,formatOutputBool:y,formatOutputBytes:v,formatOutputDynamicBytes:b,formatOutputAddress:w}},{"../utils/config":5,"../utils/utils":7,"./param":3,"bignumber.js":"bignumber.js"}],3:[function(t,e,n){var r=t("../utils/utils"),i=function(t,e){this.value=t||"",this.offset=e};i.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},i.prototype.withOffset=function(t){return new i(this.value,t)},i.prototype.combine=function(t){return new i(this.value+t.value)},i.prototype.isDynamic=function(){return this.value.length>64||void 0!==this.offset},i.prototype.offsetAsBytes=function(){return this.isDynamic()?r.padLeft(r.toTwosComplement(this.offset).toString(16),64):""},i.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},i.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},i.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},i.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()},""))},i.decodeParam=function(t,e){return e=e||0,new i(t.substr(64*e,64))};var o=function(t,e){return parseInt("0x"+t.substr(64*e,64))};i.decodeBytes=function(t,e){e=e||0;var n=o(t,e);return new i(t.substr(2*n,128),0)},i.decodeArray=function(t,e){e=e||0;var n=o(t,e),r=parseInt("0x"+t.substr(2*n,64));return new i(t.substr(2*n,64*(r+1)),0)},e.exports=i},{"../utils/utils":7}],4:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],5:[function(t,e,n){var r=t("bignumber.js"),i=["wei","kwei","Mwei","Gwei","szabo","finney","femtoether","picoether","nanoether","microether","milliether","nano","micro","milli","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:i,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:500,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],6:[function(t,e,n){var r=t("./utils"),i=t("crypto-js/sha3");e.exports=function(t,e){return"0x"!==t.substr(0,2)||e||(console.warn("requirement of using web3.fromAscii before sha3 is deprecated"),console.warn("new usage: 'web3.sha3(\"hello\")'"),console.warn("see https://github.com/ethereum/web3.js/pull/205"),console.warn("if you need to hash hex value, you can do 'sha3(\"0xfff\", true)'"),t=r.toAscii(t)),i(t,{outputLength:256}).toString()}},{"./utils":7,"crypto-js/sha3":33}],7:[function(t,e,n){var r=t("bignumber.js"),i={wei:"1",kwei:"1000",ada:"1000",femtoether:"1000",mwei:"1000000",babbage:"1000000",picoether:"1000000",gwei:"1000000000",shannon:"1000000000",nanoether:"1000000000",nano:"1000000000",szabo:"1000000000000",microether:"1000000000000",micro:"1000000000000",finney:"1000000000000000",milliether:"1000000000000000",milli:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},o=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 i=parseInt(t.substr(n,2),16);if(0===i)break;e+=String.fromCharCode(i)}return e},s=function(t){for(var e="",n=0;nthis._inputTypes.length&&!o.isObject(t[t.length-1])?a.inputDefaultBlockNumberFormatter(t.pop()):void 0},u.prototype.toPayload=function(t){var e={};return t.length>this._inputTypes.length&&o.isObject(t[t.length-1])&&(e=t[t.length-1]),e.to=this._address,e.data="0x"+this.signature()+i.encodeParams(this._inputTypes,t),e},u.prototype.signature=function(){return s(this._name).slice(0,8)},u.prototype.unpackOutput=function(t){if(t){t=t.length>=2?t.slice(2):t;var e=i.decodeParams(this._outputTypes,t);return 1===e.length?e[0]:e}},u.prototype.call=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.extractDefaultBlock(t),i=this.toPayload(t);if(!e){var o=r.eth.call(i,n);return this.unpackOutput(o)}var a=this;r.eth.call(i,n,function(t,n){e(t,a.unpackOutput(n))})},u.prototype.sendTransaction=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.sendTransaction(n,e):r.eth.sendTransaction(n)},u.prototype.estimateGas=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.estimateGas(n,e):r.eth.estimateGas(n)},u.prototype.displayName=function(){return o.extractDisplayName(this._name)},u.prototype.typeName=function(){return o.extractTypeName(this._name)},u.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}},u.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))},u.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),e.estimateGas=this.estimateGas.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=u},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":17}],19:[function(t,e,n){"use strict";var r=t("xmlhttprequest").XMLHttpRequest,i=t("./errors"),o=function(t){this.host=t||"http://localhost:8545"};o.prototype.send=function(t){var e=new r;e.open("POST",this.host,!1),e.setRequestHeader("Content-type","application/json");try{e.send(JSON.stringify(t))}catch(n){throw i.InvalidConnection(this.host)}var o=e.responseText;try{o=JSON.parse(o)}catch(a){throw i.InvalidResponse(o)}return o},o.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(o){r=i.InvalidResponse(t)}e(r,t)}},n.open("POST",this.host,!0),n.setRequestHeader("Content-type","application/json");try{n.send(JSON.stringify(t))}catch(o){e(i.InvalidConnection(this.host))}},e.exports=o},{"./errors":13,xmlhttprequest:4}],20:[function(t,e,n){var r=t("../utils/utils"),i=function(t){this._iban=t};i.prototype.isValid=function(){return r.isIBAN(this._iban)},i.prototype.isDirect=function(){return 34===this._iban.length},i.prototype.isIndirect=function(){return 20===this._iban.length},i.prototype.checksum=function(){return this._iban.substr(2,2)},i.prototype.institution=function(){return this.isIndirect()?this._iban.substr(7,4):""},i.prototype.client=function(){return this.isIndirect()?this._iban.substr(11):""},i.prototype.address=function(){return this.isDirect()?this._iban.substr(4):""},e.exports=i},{"../utils/utils":7}],21:[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},{}],22:[function(t,e,n){var r=t("./requestmanager"),i=t("../utils/utils"),o=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 i.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return i.isFunction(t[t.length-1])?t.pop():void 0},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw o.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":7,"./errors":13,"./requestmanager":27}],23:[function(t,e,n){var r=t("./contract"),i="0xc6d9d2cd449a754c494264e1809c50e34d64562b",o=[{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"name",outputs:[{name:"o_name",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"owner",outputs:[{name:"",type:"address"}],type:"function"},{constant:!0, -inputs:[{name:"_name",type:"bytes32"}],name:"content",outputs:[{name:"",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"addr",outputs:[{name:"",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"reserve",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"subRegistrar",outputs:[{name:"o_subRegistrar",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_newOwner",type:"address"}],name:"transfer",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_registrar",type:"address"}],name:"setSubRegistrar",outputs:[],type:"function"},{constant:!1,inputs:[],name:"Registrar",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_a",type:"address"},{name:"_primary",type:"bool"}],name:"setAddress",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_content",type:"bytes32"}],name:"setContent",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"disown",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"register",outputs:[{name:"",type:"address"}],type:"function"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"}],name:"Changed",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"},{indexed:!0,name:"addr",type:"address"}],name:"PrimaryChanged",type:"event"}];e.exports=r(o).at(i)},{"./contract":11}],24:[function(t,e,n){var r=t("../utils/utils"),i=t("./property"),o=[],a=[new i({name:"listening",getter:"net_listening"}),new i({name:"peerCount",getter:"net_peerCount",outputFormatter:r.toDecimal})];e.exports={methods:o,properties:a}},{"../utils/utils":7,"./property":25}],25:[function(t,e,n){var r=t("./requestmanager"),i=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};i.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},i.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},i.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 i=function(t,e){return t+e.charAt(0).toUpperCase()+e.slice(1)};t[i("get",r)]=this.getAsync.bind(this)},i.prototype.get=function(){return this.formatOutput(r.getInstance().send({method:this.getter}))},i.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=i},{"./requestmanager":27}],26:[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},{}],27:[function(t,e,n){var r=t("./jsonrpc"),i=t("../utils/utils"),o=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.isPolling=!1))};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):i.isArray(n)?void e(t,n):e(a.InvalidResponse(n))})},s.prototype.setProvider=function(t){this.provider=t,this.provider&&!this.isPolling&&(this.poll(),this.isPolling=!0)},s.prototype.startPolling=function(t,e,n,r){this.polls["poll_"+e]={data:t,id:e,callback:n,uninstall:r}},s.prototype.stopPolling=function(t){delete this.polls["poll_"+t]},s.prototype.reset=function(){for(var t in this.polls)this.polls[t].uninstall();this.polls={},this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),o.ETH_POLLING_TIMEOUT),0!==Object.keys(this.polls).length){if(!this.provider)return void console.error(a.InvalidProvider());var t=[],e=[];for(var n in this.polls)t.push(this.polls[n].data),e.push(n);if(0!==t.length){var s=r.getInstance().toBatchPayload(t),u=this;this.provider.sendAsync(s,function(t,n){if(!t){if(!i.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){var r=e[n];return u.polls[r]?(t.callback=u.polls[r].callback,t):!1}).filter(function(t){return!!t}).filter(function(t){var e=r.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return i.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}}},e.exports=s},{"../utils/config":5,"../utils/utils":7,"./errors":13,"./jsonrpc":21}],28:[function(t,e,n){var r=t("./method"),i=t("./formatters"),o=new r({name:"post",call:"shh_post",params:1,inputFormatter:[i.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=[o,a,s,u,c];e.exports={methods:l}},{"./formatters":17,"./method":22}],29:[function(t,e,n){var r=t("../web3"),i=t("./icap"),o=t("./namereg"),a=t("./contract"),s=function(t,e,n,r){var a=new i(e);if(!a.isValid())throw new Error("invalid iban address");if(a.isDirect())return u(t,a.address(),n,r);if(!r){var s=o.addr(a.institution());return c(t,s,n,a.client())}o.addr(a.insitution(),function(e,i){return c(t,i,n,a.client(),r)})},u=function(t,e,n,i){return r.eth.sendTransaction({address:e,from:t,value:n},i)},c=function(t,e,n,r,i){var o=[{constant:!1,inputs:[{name:"name",type:"bytes32"}],name:"deposit",outputs:[],type:"function"}];return a(o).at(e).deposit(r,{from:t,value:n},i)};e.exports=s},{"../web3":9,"./contract":11,"./icap":20,"./namereg":23}],30:[function(t,e,n){var r=t("./method"),i=function(){var t=function(t){var e=t[0];switch(e){case"latest":return t.shift(),this.params=0,"eth_newBlockFilter";case"pending":return t.shift(),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}),i=new r({name:"getLogs",call:"eth_getFilterLogs",params:1}),o=new r({name:"poll",call:"eth_getFilterChanges",params:1});return[e,n,i,o]},o=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}),i=new r({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,n,i]};e.exports={eth:i,shh:o}},{"./method":22}],31:[function(t,e,n){},{}],32:[function(t,e,n){!function(t,r){"object"==typeof n?e.exports=n=r():"function"==typeof define&&define.amd?define([],r):t.CryptoJS=r()}(this,function(){var t=t||function(t,e){var n={},r=n.lib={},i=r.Base=function(){function t(){}return{extend:function(e){t.prototype=this;var n=new t;return e&&n.mixIn(e),n.hasOwnProperty("init")||(n.init=function(){n.$super.init.apply(this,arguments)}),n.init.prototype=n,n.$super=this,n},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),o=r.WordArray=i.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:4*t.length},toString:function(t){return(t||s).stringify(this)},concat:function(t){var e=this.words,n=t.words,r=this.sigBytes,i=t.sigBytes;if(this.clamp(),r%4)for(var o=0;i>o;o++){var a=n[o>>>2]>>>24-o%4*8&255;e[r+o>>>2]|=a<<24-(r+o)%4*8}else for(var o=0;i>o;o+=4)e[r+o>>>2]=n[o>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,n=this.sigBytes;e[n>>>2]&=4294967295<<32-n%4*8,e.length=t.ceil(n/4)},clone:function(){var t=i.clone.call(this);return t.words=this.words.slice(0),t},random:function(e){for(var n,r=[],i=function(e){var e=e,n=987654321,r=4294967295;return function(){n=36969*(65535&n)+(n>>16)&r,e=18e3*(65535&e)+(e>>16)&r;var i=(n<<16)+e&r;return i/=4294967296,i+=.5,i*(t.random()>.5?1:-1)}},a=0;e>a;a+=4){var s=i(4294967296*(n||t.random()));n=987654071*s(),r.push(4294967296*s()|0)}return new o.init(r,e)}}),a=n.enc={},s=a.Hex={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],i=0;n>i;i++){var o=e[i>>>2]>>>24-i%4*8&255;r.push((o>>>4).toString(16)),r.push((15&o).toString(16))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r+=2)n[r>>>3]|=parseInt(t.substr(r,2),16)<<24-r%8*4;return new o.init(n,e/2)}},u=a.Latin1={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],i=0;n>i;i++){var o=e[i>>>2]>>>24-i%4*8&255;r.push(String.fromCharCode(o))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r++)n[r>>>2]|=(255&t.charCodeAt(r))<<24-r%4*8;return new o.init(n,e)}},c=a.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},l=r.BufferedBlockAlgorithm=i.extend({reset:function(){this._data=new o.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=c.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(e){var n=this._data,r=n.words,i=n.sigBytes,a=this.blockSize,s=4*a,u=i/s;u=e?t.ceil(u):t.max((0|u)-this._minBufferSize,0);var c=u*a,l=t.min(4*c,i);if(c){for(var f=0;c>f;f+=a)this._doProcessBlock(r,f);var p=r.splice(0,c);n.sigBytes-=l}return new o.init(p,l)},clone:function(){var t=i.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),f=(r.Hasher=l.extend({cfg:i.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){l.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){t&&this._append(t);var e=this._doFinalize();return e},blockSize:16,_createHelper:function(t){return function(e,n){return new t.init(n).finalize(e)}},_createHmacHelper:function(t){return function(e,n){return new f.HMAC.init(t,n).finalize(e)}}}),n.algo={});return n}(Math);return t})},{}],33:[function(t,e,n){!function(r,i,o){"object"==typeof n?e.exports=n=i(t("./core"),t("./x64-core")):"function"==typeof define&&define.amd?define(["./core","./x64-core"],i):i(r.CryptoJS)}(this,function(t){return function(e){var n=t,r=n.lib,i=r.WordArray,o=r.Hasher,a=n.x64,s=a.Word,u=n.algo,c=[],l=[],f=[];!function(){for(var t=1,e=0,n=0;24>n;n++){c[t+5*e]=(n+1)*(n+2)/2%64;var r=e%5,i=(2*t+3*e)%5;t=r,e=i}for(var t=0;5>t;t++)for(var e=0;5>e;e++)l[t+5*e]=e+(2*t+3*e)%5*5;for(var o=1,a=0;24>a;a++){for(var u=0,p=0,h=0;7>h;h++){if(1&o){var m=(1<m?p^=1<t;t++)p[t]=s.create()}();var h=u.SHA3=o.extend({cfg:o.cfg.extend({outputLength:512}),_doReset:function(){for(var t=this._state=[],e=0;25>e;e++)t[e]=new s.init;this.blockSize=(1600-2*this.cfg.outputLength)/32},_doProcessBlock:function(t,e){for(var n=this._state,r=this.blockSize/2,i=0;r>i;i++){var o=t[e+2*i],a=t[e+2*i+1];o=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),a=16711935&(a<<8|a>>>24)|4278255360&(a<<24|a>>>8);var s=n[i];s.high^=a,s.low^=o}for(var u=0;24>u;u++){for(var h=0;5>h;h++){for(var m=0,d=0,g=0;5>g;g++){var s=n[h+5*g];m^=s.high,d^=s.low}var y=p[h];y.high=m,y.low=d}for(var h=0;5>h;h++)for(var v=p[(h+4)%5],b=p[(h+1)%5],w=b.high,_=b.low,m=v.high^(w<<1|_>>>31),d=v.low^(_<<1|w>>>31),g=0;5>g;g++){var s=n[h+5*g];s.high^=m,s.low^=d}for(var x=1;25>x;x++){var s=n[x],F=s.high,I=s.low,B=c[x];if(32>B)var m=F<>>32-B,d=I<>>32-B;else var m=I<>>64-B,d=F<>>64-B;var N=p[l[x]];N.high=m,N.low=d}var O=p[0],A=n[0];O.high=A.high,O.low=A.low;for(var h=0;5>h;h++)for(var g=0;5>g;g++){var x=h+5*g,s=n[x],k=p[x],P=p[(h+1)%5+5*g],T=p[(h+2)%5+5*g];s.high=k.high^~P.high&T.high,s.low=k.low^~P.low&T.low}var s=n[0],D=f[u];s.high^=D.high,s.low^=D.low}},_doFinalize:function(){var t=this._data,n=t.words,r=(8*this._nDataBytes,8*t.sigBytes),o=32*this.blockSize;n[r>>>5]|=1<<24-r%32,n[(e.ceil((r+1)/o)*o>>>5)-1]|=128,t.sigBytes=4*n.length,this._process();for(var a=this._state,s=this.cfg.outputLength/8,u=s/8,c=[],l=0;u>l;l++){var f=a[l],p=f.high,h=f.low;p=16711935&(p<<8|p>>>24)|4278255360&(p<<24|p>>>8),h=16711935&(h<<8|h>>>24)|4278255360&(h<<24|h>>>8),c.push(h),c.push(p)}return new i.init(c,s)},clone:function(){for(var t=o.clone.call(this),e=t._state=this._state.slice(0),n=0;25>n;n++)e[n]=e[n].clone();return t}});n.SHA3=o._createHelper(h),n.HmacSHA3=o._createHmacHelper(h)}(Math),t.SHA3})},{"./core":32,"./x64-core":34}],34:[function(t,e,n){!function(r,i){"object"==typeof n?e.exports=n=i(t("./core")):"function"==typeof define&&define.amd?define(["./core"],i):i(r.CryptoJS)}(this,function(t){return function(e){{var n=t,r=n.lib,i=r.Base,o=r.WordArray,a=n.x64={};a.Word=i.extend({init:function(t,e){this.high=t,this.low=e}}),a.WordArray=i.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:8*t.length},toX32:function(){for(var t=this.words,e=t.length,n=[],r=0;e>r;r++){var i=t[r];n.push(i.high),n.push(i.low)}return o.create(n,this.sigBytes)},clone:function(){for(var t=i.clone.call(this),e=t.words=this.words.slice(0),n=e.length,r=0;n>r;r++)e[r]=e[r].clone();return t}})}}(),t})},{"./core":32}],"bignumber.js":[function(t,e,n){!function(n){"use strict";function r(t){function e(t,r){var i,o,a,s,u,c,l=this;if(!(l instanceof e))return z&&D(26,"constructor call without new",t),new e(t,r);if(null!=r&&W(r,2,64,C,"base")){if(r=0|r,c=t+"",10==r)return l=new e(t instanceof e?t:c),S(l,j+l.e+1,L);if((s="number"==typeof t)&&0*t!=0||!new RegExp("^-?"+(i="["+x.slice(0,r)+"]+")+"(?:\\."+i+")?$",37>r?"i":"").test(c))return d(l,c,s,r);s?(l.s=0>1/t?(c=c.slice(1),-1):1,z&&c.replace(/^0\.0*|\./,"").length>15&&D(C,_,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(C=0);if((s="number"==typeof t)&&0*t==0){if(l.s=0>1/t?(t=-t,-1):1,t===~~t){for(o=0,a=t;a>=10;a/=10,o++);return l.e=o,l.c=[t],void(C=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((o=c.indexOf("."))>-1&&(c=c.replace(".","")),(a=c.search(/e/i))>0?(0>o&&(o=a),o+=+c.slice(a+1),c=c.substring(0,a)):0>o&&(o=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&&z&&u>15&&D(C,_,l.s*t),o=o-a-1,o>G)l.c=l.e=null;else if(M>o)l.c=[l.e=0];else{if(l.e=o,l.c=[],a=(o+1)%I,0>o&&(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];C=0}function n(t,n,r,i){var a,s,u,l,p,h,m,d=t.indexOf("."),g=j,y=L;for(37>r&&(t=t.toLowerCase()),d>=0&&(u=V,V=0,t=t.replace(".",""),m=new e(r),p=m.pow(t.length-d),V=u,m.c=c(f(o(p.c),p.e),10,n),m.e=m.c.length),h=c(t,r,n),s=u=h.length;0==h[--u];h.pop());if(!h[0])return"0";if(0>d?--s:(p.c=h,p.e=s,p.s=i,p=E(p,m,g,y,n),h=p.c,l=p.r,s=p.e),a=s+g+1,d=h[a],u=n/2,l=l||0>a||null!=h[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&h[a-1]||y==(p.s<0?8:7)),1>a||!h[0])t=l?f("1",-g):"0";else{if(h.length=a,l)for(--n;++h[--a]>n;)h[a]=0,a||(++s,h.unshift(1));for(u=h.length;!h[--u];);for(d=0,t="";u>=d;t+=x.charAt(h[d++]));t=f(t,s)}return t}function h(t,n,r,i){var a,s,u,c,p;if(r=null!=r&&W(r,0,8,i,w)?0|r:L,!t.c)return t.toString();if(a=t.c[0],u=t.e,null==n)p=o(t.c),p=19==i||24==i&&q>=u?l(p,u):f(p,u);else if(t=S(new e(t),n,r),s=t.e,p=o(t.c),c=p.length,19==i||24==i&&(s>=n||q>=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 k(t,n){var r,i,o=0;for(u(t[0])&&(t=t[0]),r=new e(t[0]);++ot||t>n||t!=p(t))&&D(r,(i||"decimal places")+(e>t||t>n?" out of range":" not an integer"),t),!0}function T(t,e,n){for(var r=1,i=e.length;!e[--i];e.pop());for(i=e[0];i>=10;i/=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",C=0,r}function S(t,e,n,r){var i,o,a,s,u,c,l,f=t.c,p=N;if(f){t:{for(i=1,s=f[0];s>=10;s/=10,i++);if(o=e-i,0>o)o+=I,a=e,u=f[c=0],l=u/p[i-a-1]%10|0;else if(c=y((o+1)/I),c>=f.length){if(!r)break t;for(;f.length<=c;f.push(0));u=l=0,i=1,o%=I,a=o-I+1}else{for(u=s=f[c],i=1;s>=10;s/=10,i++);o%=I,a=o-I+i,l=0>a?0:u/p[i-a-1]%10|0}if(r=r||0>e||null!=f[c+1]||(0>a?u:u%p[i-a-1]),r=4>n?(l||r)&&(0==n||n==(t.s<0?3:2)):l>5||5==l&&(4==n||r||6==n&&(o>0?a>0?u/p[i-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==o?(f.length=c,s=1,c--):(f.length=c+1,s=p[I-o],f[c]=a>0?v(u/p[i-a]%p[a])*s:0),r)for(;;){if(0==c){for(o=1,a=f[0];a>=10;a/=10,o++);for(a=f[0]+=s,s=1;a>=10;a/=10,s++);o!=s&&(t.e++,f[0]==F&&(f[0]=1));break}if(f[c]+=s,f[c]!=F)break;f[c--]=0,s=1}for(o=f.length;0===f[--o];f.pop());}t.e>G?t.c=t.e=null:t.en?null!=(t=i[n++]):void 0};return a(e="DECIMAL_PLACES")&&W(t,0,A,2,e)&&(j=0|t),r[e]=j,a(e="ROUNDING_MODE")&&W(t,0,8,2,e)&&(L=0|t),r[e]=L,a(e="EXPONENTIAL_AT")&&(u(t)?W(t[0],-A,0,2,e)&&W(t[1],0,A,2,e)&&(q=0|t[0],U=0|t[1]):W(t,-A,A,2,e)&&(q=-(U=0|(0>t?-t:t)))),r[e]=[q,U],a(e="RANGE")&&(u(t)?W(t[0],-A,-1,2,e)&&W(t[1],1,A,2,e)&&(M=0|t[0],G=0|t[1]):W(t,-A,A,2,e)&&(0|t?M=-(G=0|(0>t?-t:t)):z&&D(2,e+" cannot be zero",t))),r[e]=[M,G],a(e="ERRORS")&&(t===!!t||1===t||0===t?(C=0,W=(z=!!t)?P:s):z&&D(2,e+b,t)),r[e]=z,a(e="CRYPTO")&&(t===!!t||1===t||0===t?(J=!(!t||!m||"object"!=typeof m),t&&!J&&z&&D(2,"crypto unavailable",m)):z&&D(2,e+b,t)),r[e]=J,a(e="MODULO_MODE")&&W(t,0,9,2,e)&&($=0|t),r[e]=$,a(e="POW_PRECISION")&&W(t,0,A,2,e)&&(V=0|t),r[e]=V,a(e="FORMAT")&&("object"==typeof t?X=t:z&&D(2,e+" not an object",t)),r[e]=X,r},e.max=function(){return k(arguments,R.lt)},e.min=function(){return k(arguments,R.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,i,o,a,s,u=0,c=[],l=new e(H);if(t=null!=t&&W(t,0,A,14)?0|t:j,a=y(t/I),J)if(m&&m.getRandomValues){for(r=m.getRandomValues(new Uint32Array(a*=2));a>u;)s=131072*r[u]+(r[u+1]>>>11),s>=9e15?(i=m.getRandomValues(new Uint32Array(2)),r[u]=i[0],r[u+1]=i[1]):(c.push(s%1e14),u+=2);u=a/2}else if(m&&m.randomBytes){for(r=m.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?m.randomBytes(7).copy(r,u):(c.push(s%1e14),u+=7);u=a/7}else z&&D(14,"crypto unavailable",m);if(!u)for(;a>u;)s=n(),9e15>s&&(c[u++]=s%1e14);for(a=c[--u],t%=I,a&&t&&(s=N[I-t],c[u]=v(a/s)*s);0===c[u];c.pop(),u--);if(0>u)c=[o=0];else{for(o=-1;0===c[0];c.shift(),o-=I);for(u=1,s=c[0];s>=10;s/=10,u++);I>u&&(o-=I-u)}return l.e=o,l.c=c,l}}(),E=function(){function t(t,e,n){var r,i,o,a,s=0,u=t.length,c=e%O,l=e/O|0;for(t=t.slice();u--;)o=t[u]%O,a=t[u]/O|0,r=l*o+a*c,i=c*o+r%O*O+s,s=(i/n|0)+(r/O|0)+l*a,t[u]=i%n;return s&&t.unshift(s),t}function n(t,e,n,r){var i,o;if(n!=r)o=n>r?1:-1;else for(i=o=0;n>i;i++)if(t[i]!=e[i]){o=t[i]>e[i]?1:-1;break}return o}function r(t,e,n,r){for(var i=0;n--;)t[n]-=i,i=t[n]1;t.shift());}return function(o,a,s,u,c){var l,f,p,h,m,d,g,y,b,w,_,x,B,N,O,A,k,P=o.s==a.s?1:-1,T=o.c,D=a.c;if(!(T&&T[0]&&D&&D[0]))return new e(o.s&&a.s&&(T?!D||T[0]!=D[0]:D)?T&&0==T[0]||!D?0*P:P/0:0/0);for(y=new e(P),b=y.c=[],f=o.e-a.e,P=s+f+1,c||(c=F,f=i(o.e/I)-i(a.e/I),P=P/I|0),p=0;D[p]==(T[p]||0);p++);if(D[p]>(T[p]||0)&&f--,0>P)b.push(1),h=!0;else{for(N=T.length,A=D.length,p=0,P+=2,m=v(c/(D[0]+1)),m>1&&(D=t(D,m,c),T=t(T,m,c),A=D.length,N=T.length),B=A,w=T.slice(0,A),_=w.length;A>_;w[_++]=0);k=D.slice(),k.unshift(0),O=D[0],D[1]>=c/2&&O++;do{if(m=0,l=n(D,w,A,_),0>l){if(x=w[0],A!=_&&(x=x*c+(w[1]||0)),m=v(x/O),m>1)for(m>=c&&(m=c-1),d=t(D,m,c),g=d.length,_=w.length;1==n(d,w,g,_);)m--,r(d,g>A?k:D,g,c),g=d.length,l=1;else 0==m&&(l=m=1),d=D.slice(),g=d.length;if(_>g&&d.unshift(0),r(w,d,_,c),_=w.length,-1==l)for(;n(D,w,A,_)<1;)m++,r(w,_>A?k:D,_,c),_=w.length}else 0===l&&(m++,w=[0]);b[p++]=m,w[0]?w[_++]=T[B]||0:(w=[T[B]],_=1)}while((B++=10;P/=10,p++);S(y,s+(y.e=p+f*I-1)+1,u,h)}else y.e=f,y.r=+h;return y}}(),d=function(){var t=/^(-?)0([xbo])/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,i=/^-?(Infinity|NaN)$/,o=/^\s*\+|^\s+|\s+$/g;return function(a,s,u,c){var l,f=u?s:s.replace(o,"");if(i.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);z&&D(C,"not a"+(c?" base "+c:"")+" number",s),a.s=null}a.c=a.e=null,C=0}}(),R.absoluteValue=R.abs=function(){var t=new e(this);return t.s<0&&(t.s=1),t},R.ceil=function(){return S(new e(this),this.e+1,2)},R.comparedTo=R.cmp=function(t,n){return C=1,a(this,new e(t,n))},R.decimalPlaces=R.dp=function(){var t,e,n=this.c;if(!n)return null;if(t=((e=n.length-1)-i(this.e/I))*I,e=n[e])for(;e%10==0;e/=10,t--);return 0>t&&(t=0),t},R.dividedBy=R.div=function(t,n){return C=3,E(this,new e(t,n),j,L)},R.dividedToIntegerBy=R.divToInt=function(t,n){return C=4,E(this,new e(t,n),0,1)},R.equals=R.eq=function(t,n){return C=5,0===a(this,new e(t,n))},R.floor=function(){return S(new e(this),this.e+1,3)},R.greaterThan=R.gt=function(t,n){return C=6,a(this,new e(t,n))>0},R.greaterThanOrEqualTo=R.gte=function(t,n){return C=7,1===(n=a(this,new e(t,n)))||0===n},R.isFinite=function(){return!!this.c},R.isInteger=R.isInt=function(){return!!this.c&&i(this.e/I)>this.c.length-2},R.isNaN=function(){return!this.s},R.isNegative=R.isNeg=function(){return this.s<0},R.isZero=function(){return!!this.c&&0==this.c[0]},R.lessThan=R.lt=function(t,n){return C=8,a(this,new e(t,n))<0},R.lessThanOrEqualTo=R.lte=function(t,n){return C=9,-1===(n=a(this,new e(t,n)))||0===n},R.minus=R.sub=function(t,n){var r,o,a,s,u=this,c=u.s;if(C=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,h=t.c;if(!l||!f){if(!p||!h)return p?(t.s=-n,t):new e(h?u:0/0);if(!p[0]||!h[0])return h[0]?(t.s=-n,t):new e(p[0]?u:3==L?-0:0)}if(l=i(l),f=i(f),p=p.slice(),c=l-f){for((s=0>c)?(c=-c,a=p):(f=l,a=h),a.reverse(),n=c;n--;a.push(0));a.reverse()}else for(o=(s=(c=p.length)<(n=h.length))?c:n,c=n=0;o>n;n++)if(p[n]!=h[n]){s=p[n]0)for(;n--;p[r++]=0);for(n=F-1;o>c;){if(p[--o]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)/F|0,c[n]%=F;return a&&(c.unshift(a),++u),T(t,c,u)},R.precision=R.sd=function(t){var e,n,r=this,i=r.c;if(null!=t&&t!==!!t&&1!==t&&0!==t&&(z&&D(13,"argument"+b,t),t!=!!t&&(t=null)),!i)return null;if(n=i.length-1,e=n*I+1,n=i[n]){for(;n%10==0;n/=10,e--);for(n=i[0];n>=10;n/=10,e++);}return t&&r.e+1>e&&(e=r.e+1),e},R.round=function(t,n){var r=new e(this);return(null==t||W(t,0,A,15))&&S(r,~~t+this.e+1,null!=n&&W(n,0,8,15,w)?0|n:L),r},R.shift=function(t){var n=this;return W(t,-B,B,16,"argument")?n.times("1e"+p(t)):new e(n.c&&n.c[0]&&(-B>t||t>B)?n.s*(0>t?0:1/0):n)},R.squareRoot=R.sqrt=function(){var t,n,r,a,s,u=this,c=u.c,l=u.s,f=u.e,p=j+4,h=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=o(c),(n.length+f)%2==0&&(n+="0"),l=Math.sqrt(n),f=i((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=h.times(s.plus(E(u,s,p,1))),o(s.c).slice(0,l)===(n=o(r.c)).slice(0,l)){if(r.el&&(g=w,w=_,_=g,a=l,l=h,h=a),a=l+h,g=[];a--;g.push(0));for(y=F,v=O,a=h;--a>=0;){for(r=0,m=_[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*m,f=m*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?++o:g.shift(),T(t,g,o)},R.toDigits=function(t,n){var r=new e(this);return t=null!=t&&W(t,1,A,18,"precision")?0|t:null,n=null!=n&&W(n,0,8,18,w)?0|n:L,t?S(r,t,n):r},R.toExponential=function(t,e){return h(this,null!=t&&W(t,0,A,19)?~~t+1:null,e,19)},R.toFixed=function(t,e){return h(this,null!=t&&W(t,0,A,20)?~~t+this.e+1:null,e,20)},R.toFormat=function(t,e){var n=h(this,null!=t&&W(t,0,A,21)?~~t+this.e+1:null,e,21);if(this.c){var r,i=n.split("."),o=+X.groupSize,a=+X.secondaryGroupSize,s=X.groupSeparator,u=i[0],c=i[1],l=this.s<0,f=l?u.slice(1):u,p=f.length;if(a&&(r=o,o=a,a=r,p-=r),o>0&&p>0){for(r=p%o||o,u=f.substr(0,r);p>r;r+=o)u+=s+f.substr(r,o);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},R.toFraction=function(t){var n,r,i,a,s,u,c,l,f,p=z,h=this,m=h.c,d=new e(H),g=r=new e(H),y=c=new e(H);if(null!=t&&(z=!1,u=new e(t),z=p,(!(p=u.isInt())||u.lt(H))&&(z&&D(22,"max denominator "+(p?"out of range":"not an integer"),t),t=!p&&u.c&&S(u,u.e+1,1).gte(H)?u:null)),!m)return h.toString();for(f=o(m),a=d.e=f.length-h.e-1,d.c[0]=N[(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),i=r.plus(l.times(y)),1!=i.cmp(t);)r=y,y=i,g=c.plus(l.times(i=g)),c=i,d=u.minus(l.times(i=d)),u=i;return i=E(t.minus(r),y,0,1),c=c.plus(i.times(g)),r=r.plus(i.times(y)),c.s=g.s=h.s,a*=2,n=E(g,y,a,L).minus(h).abs().cmp(E(c,r,a,L).minus(h).abs())<1?[g.toString(),y.toString()]:[c.toString(),r.toString()],G=s,n},R.toNumber=function(){var t=this;return+t||(t.s?0*t.s:0/0)},R.toPower=R.pow=function(t){var n,r,i=v(0>t?-t:+t),o=this;if(!W(t,-B,B,23,"exponent")&&(!isFinite(t)||i>B&&(t/=0)||parseFloat(t)!=t&&!(t=0/0)))return new e(Math.pow(+o,t));for(n=V?y(V/I+2):0,r=new e(H);;){if(i%2){if(r=r.times(o),!r.c)break;n&&r.c.length>n&&(r.c.length=n)}if(i=v(i/2),!i)break;o=o.times(o),n&&o.c&&o.c.length>n&&(o.c.length=n)}return 0>t&&(r=H.div(r)),n?S(r,V,L):r},R.toPrecision=function(t,e){return h(this,null!=t&&W(t,1,A,24,"precision")?0|t:null,e,24)},R.toString=function(t){var e,r=this,i=r.s,a=r.e;return null===a?i?(e="Infinity",0>i&&(e="-"+e)):e="NaN":(e=o(r.c),e=null!=t&&W(t,2,64,25,"base")?n(f(e,a),0|t,10,i):q>=a||a>=U?l(e,a):f(e,a),0>i&&r.c[0]&&(e="-"+e)),e},R.truncated=R.trunc=function(){return S(new e(this),this.e+1,1)},R.valueOf=R.toJSON=function(){return this.toString()},null!=t&&e.config(t),e}function i(t){var e=0|t;return t>0||t===e?e:e-1}function o(t){for(var e,n,r=1,i=t.length,o=t[0]+"";i>r;){for(e=t[r++]+"",n=I-e.length;n--;e="0"+e);o+=e}for(i=o.length;48===o.charCodeAt(--i););return o.slice(0,i+1||1)}function a(t,e){var n,r,i=t.c,o=e.c,a=t.s,s=e.s,u=t.e,c=e.e;if(!a||!s)return null;if(n=i&&!i[0],r=o&&!o[0],n||r)return n?r?0:-s:a;if(a!=s)return a;if(n=0>a,r=u==c,!i||!o)return r?0:!i^n?1:-1;if(!r)return u>c^n?1:-1;for(s=(u=i.length)<(c=o.length)?u:c,a=0;s>a;a++)if(i[a]!=o[a])return i[a]>o[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,i,o=[0],a=0,s=t.length;s>a;){for(i=o.length;i--;o[i]*=e);for(o[r=0]+=x.indexOf(t.charAt(a++));rn-1&&(null==o[r+1]&&(o[r+1]=0),o[r+1]+=o[r]/n|0,o[r]%=n)}return o.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 h,m,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",x="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",F=1e14,I=14,B=9007199254740991,N=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],O=1e7,A=1e9;if(h=r(),"function"==typeof define&&define.amd)define(function(){return h});else if("undefined"!=typeof e&&e.exports){if(e.exports=h,!m)try{m=t("crypto")}catch(k){}}else n.BigNumber=h}(this)},{crypto:31}],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.eth.namereg=t("./lib/web3/namereg"),r.eth.sendIBANTransaction=t("./lib/web3/transfer"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/web3":9,"./lib/web3/contract":11,"./lib/web3/httpprovider":19,"./lib/web3/namereg":23,"./lib/web3/qtsync":26,"./lib/web3/transfer":29}]},{},["web3"]); \ No newline at end of file +require=function t(e,n,r){function i(a,s){if(!n[a]){if(!e[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(o)return o(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 i(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var o="function"==typeof require&&require,a=0;ao;o+=64)n.push(this._outputFormatter(new a(t.dynamicPart().substr(o+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 i=n._requireType(t),o=i.sliceParam(e,r,t);return i.formatOutput(o,s(t))})};var l=new c([new u({name:"address",match:"strict",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputAddress}),new u({name:"bool",match:"strict",mode:"value",inputFormatter:o.formatInputBool,outputFormatter:o.formatOutputBool}),new u({name:"int",match:"prefix",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputInt}),new u({name:"uint",match:"prefix",mode:"value",inputFormatter:o.formatInputInt,outputFormatter:o.formatOutputUInt}),new u({name:"bytes",match:"strict",mode:"bytes",inputFormatter:o.formatInputDynamicBytes,outputFormatter:o.formatOutputDynamicBytes}),new u({name:"bytes",match:"prefix",mode:"value",inputFormatter:o.formatInputBytes,outputFormatter:o.formatOutputBytes}),new u({name:"string",match:"strict",mode:"bytes",inputFormatter:o.formatInputString,outputFormatter:o.formatOutputString}),new u({name:"real",match:"prefix",mode:"value",inputFormatter:o.formatInputReal,outputFormatter:o.formatOutputReal}),new u({name:"ureal",match:"prefix",mode:"value",inputFormatter:o.formatInputReal,outputFormatter:o.formatOutputUReal})]);e.exports=l},{"../utils/utils":7,"./formatters":2,"./param":3,"bignumber.js":"bignumber.js"}],2:[function(t,e,n){var r=t("bignumber.js"),i=t("../utils/utils"),o=t("../utils/config"),a=t("./param"),s=function(t){var e=2*o.ETH_PADDING;r.config(o.ETH_BIGNUMBER_ROUNDING_MODE);var n=i.padLeft(i.toTwosComplement(t).round().toString(16),e);return new a(n)},u=function(t){var e=i.padRight(i.toHex(t).substr(2),64);return new a(e)},c=function(t){t=i.toHex(t).substr(2);var e=Math.floor((t.length+63)/64),n=i.padRight(t,64*e),r=Math.floor(t.length/2);return new a(s(r).value+n,32)},l=function(t){var e=i.fromAscii(t).substr(2),n=Math.floor((e.length+63)/64);return e=i.padRight(e,64*n),new a(s(t.length).value+e,32)},f=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)))},h=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 h(e)?new r(e,16).minus(new r("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",16)).minus(1):new r(e,16)},d=function(t){var e=t.staticPart()||"0";return new r(e,16)},g=function(t){return m(t).dividedBy(new r(2).pow(128))},y=function(t){return d(t).dividedBy(new r(2).pow(128))},v=function(t){return"0000000000000000000000000000000000000000000000000000000000000001"===t.staticPart()?!0:!1},w=function(t){return"0x"+t.staticPart()},b=function(t){var e=2*new r(t.dynamicPart().slice(0,64),16).toNumber();return"0x"+t.dynamicPart().substr(64,e)},_=function(t){var e=2*new r(t.dynamicPart().slice(0,64),16).toNumber();return i.toAscii(t.dynamicPart().substr(64,e))},x=function(t){var e=t.staticPart();return"0x"+e.slice(e.length-40,e.length)};e.exports={formatInputInt:s,formatInputBytes:u,formatInputDynamicBytes:c,formatInputString:l,formatInputBool:f,formatInputReal:p,formatOutputInt:m,formatOutputUInt:d,formatOutputReal:g,formatOutputUReal:y,formatOutputBool:v,formatOutputBytes:w,formatOutputDynamicBytes:b,formatOutputString:_,formatOutputAddress:x}},{"../utils/config":5,"../utils/utils":7,"./param":3,"bignumber.js":"bignumber.js"}],3:[function(t,e,n){var r=t("../utils/utils"),i=function(t,e){this.value=t||"",this.offset=e};i.prototype.dynamicPartLength=function(){return this.dynamicPart().length/2},i.prototype.withOffset=function(t){return new i(this.value,t)},i.prototype.combine=function(t){return new i(this.value+t.value)},i.prototype.isDynamic=function(){return this.value.length>64||void 0!==this.offset},i.prototype.offsetAsBytes=function(){return this.isDynamic()?r.padLeft(r.toTwosComplement(this.offset).toString(16),64):""},i.prototype.staticPart=function(){return this.isDynamic()?this.offsetAsBytes():this.value},i.prototype.dynamicPart=function(){return this.isDynamic()?this.value:""},i.prototype.encode=function(){return this.staticPart()+this.dynamicPart()},i.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()},""))},i.decodeParam=function(t,e){return e=e||0,new i(t.substr(64*e,64))};var o=function(t,e){return parseInt("0x"+t.substr(64*e,64))};i.decodeBytes=function(t,e){e=e||0;var n=o(t,e),r=parseInt("0x"+t.substr(2*n,64));return r=Math.floor((r+31)/32),new i(t.substr(2*n,64*(1+r)),0)},i.decodeArray=function(t,e){e=e||0;var n=o(t,e),r=parseInt("0x"+t.substr(2*n,64));return new i(t.substr(2*n,64*(r+1)),0)},e.exports=i},{"../utils/utils":7}],4:[function(t,e,n){"use strict";n.XMLHttpRequest="undefined"==typeof XMLHttpRequest?{}:XMLHttpRequest},{}],5:[function(t,e,n){var r=t("bignumber.js"),i=["wei","kwei","Mwei","Gwei","szabo","finney","femtoether","picoether","nanoether","microether","milliether","nano","micro","milli","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e.exports={ETH_PADDING:32,ETH_SIGNATURE_LENGTH:4,ETH_UNITS:i,ETH_BIGNUMBER_ROUNDING_MODE:{ROUNDING_MODE:r.ROUND_DOWN},ETH_POLLING_TIMEOUT:500,defaultBlock:"latest",defaultAccount:void 0}},{"bignumber.js":"bignumber.js"}],6:[function(t,e,n){var r=t("./utils"),i=t("crypto-js/sha3");e.exports=function(t,e){return"0x"!==t.substr(0,2)||e||(console.warn("requirement of using web3.fromAscii before sha3 is deprecated"),console.warn("new usage: 'web3.sha3(\"hello\")'"),console.warn("see https://github.com/ethereum/web3.js/pull/205"),console.warn("if you need to hash hex value, you can do 'sha3(\"0xfff\", true)'"),t=r.toAscii(t)),i(t,{outputLength:256}).toString()}},{"./utils":7,"crypto-js/sha3":34}],7:[function(t,e,n){var r=t("bignumber.js"),i={wei:"1",kwei:"1000",ada:"1000",femtoether:"1000",mwei:"1000000",babbage:"1000000",picoether:"1000000",gwei:"1000000000",shannon:"1000000000",nanoether:"1000000000",nano:"1000000000",szabo:"1000000000000",microether:"1000000000000",micro:"1000000000000",finney:"1000000000000000",milliether:"1000000000000000",milli:"1000000000000000",ether:"1000000000000000000",kether:"1000000000000000000000",grand:"1000000000000000000000",einstein:"1000000000000000000000",mether:"1000000000000000000000000",gether:"1000000000000000000000000000",tether:"1000000000000000000000000000000"},o=function(t,e,n){return new Array(e-t.length+1).join(n?n:"0")+t},a=function(t,e,n){return t+new Array(e-t.length+1).join(n?n:"0")},s=function(t){var e="",n=0,r=t.length;for("0x"===t.substring(0,2)&&(n=2);r>n;n+=2){var i=parseInt(t.substr(n,2),16);e+=String.fromCharCode(i)}return e},u=function(t){for(var e="",n=0;n0&&c(i),r)return i.watch(r)})};l.prototype.watch=function(t){return this.callbacks.push(t),this.filterId&&(u(this,t),c(this)),this},l.prototype.stopWatching=function(){r.getInstance().stopPolling(this.filterId),this.implementation.uninstallFilter(this.filterId,function(){}),this.callbacks=[]},l.prototype.get=function(t){var e=this;if(!o.isFunction(t)){var n=this.implementation.getLogs(this.filterId);return n.map(function(t){return e.formatter?e.formatter(t):t})}return this.implementation.getLogs(this.filterId,function(n,r){n?t(n):t(null,r.map(function(t){return e.formatter?e.formatter(t):t}))}),this},e.exports=l},{"../utils/utils":7,"./formatters":18,"./requestmanager":28}],18:[function(t,e,n){var r=t("../utils/utils"),i=t("../utils/config"),o=function(t){return r.toBigNumber(t)},a=function(t){return"latest"===t||"pending"===t||"earliest"===t},s=function(t){return void 0===t?i.defaultBlock:u(t)},u=function(t){return void 0===t?void 0:a(t)?t:r.toHex(t)},c=function(t){return t.from=t.from||i.defaultAccount,t.code&&(t.data=t.code,delete t.code),["gasPrice","gas","value","nonce"].filter(function(e){return void 0!==t[e]}).forEach(function(e){t[e]=r.fromDecimal(t[e])}),t},l=function(t){return null!==t.blockNumber&&(t.blockNumber=r.toDecimal(t.blockNumber)),null!==t.transactionIndex&&(t.transactionIndex=r.toDecimal(t.transactionIndex)),t.nonce=r.toDecimal(t.nonce),t.gas=r.toDecimal(t.gas),t.gasPrice=r.toBigNumber(t.gasPrice),t.value=r.toBigNumber(t.value),t},f=function(t){return t.gasLimit=r.toDecimal(t.gasLimit),t.gasUsed=r.toDecimal(t.gasUsed),t.size=r.toDecimal(t.size),t.timestamp=r.toDecimal(t.timestamp),null!==t.number&&(t.number=r.toDecimal(t.number)),t.difficulty=r.toBigNumber(t.difficulty),t.totalDifficulty=r.toBigNumber(t.totalDifficulty),r.isArray(t.transactions)&&t.transactions.forEach(function(t){return r.isString(t)?void 0:l(t)}),t},p=function(t){return null!==t.blockNumber&&(t.blockNumber=r.toDecimal(t.blockNumber)),null!==t.transactionIndex&&(t.transactionIndex=r.toDecimal(t.transactionIndex)),null!==t.logIndex&&(t.logIndex=r.toDecimal(t.logIndex)),t},h=function(t){return t.payload=r.toHex(t.payload),t.ttl=r.fromDecimal(t.ttl),t.workToProve=r.fromDecimal(t.workToProve),t.priority=r.fromDecimal(t.priority),r.isArray(t.topics)||(t.topics=t.topics?[t.topics]:[]),t.topics=t.topics.map(function(t){return r.fromAscii(t)}),t},m=function(t){return t.expiry=r.toDecimal(t.expiry),t.sent=r.toDecimal(t.sent),t.ttl=r.toDecimal(t.ttl),t.workProved=r.toDecimal(t.workProved),t.payloadRaw=t.payload,t.payload=r.toAscii(t.payload),r.isJson(t.payload)&&(t.payload=JSON.parse(t.payload)),t.topics||(t.topics=[]),t.topics=t.topics.map(function(t){return r.toAscii(t)}),t};e.exports={inputDefaultBlockNumberFormatter:s,inputBlockNumberFormatter:u,inputTransactionFormatter:c,inputPostFormatter:h,outputBigNumberFormatter:o,outputTransactionFormatter:l,outputBlockFormatter:f,outputLogFormatter:p,outputPostFormatter:m}},{"../utils/config":5,"../utils/utils":7}],19:[function(t,e,n){var r=t("../web3"),i=t("../solidity/coder"),o=t("../utils/utils"),a=t("./formatters"),s=t("../utils/sha3"),u=function(t,e){this._inputTypes=t.inputs.map(function(t){return t.type}),this._outputTypes=t.outputs.map(function(t){return t.type}),this._constant=t.constant,this._name=o.transformToFullName(t),this._address=e};u.prototype.extractCallback=function(t){return o.isFunction(t[t.length-1])?t.pop():void 0},u.prototype.extractDefaultBlock=function(t){return t.length>this._inputTypes.length&&!o.isObject(t[t.length-1])?a.inputDefaultBlockNumberFormatter(t.pop()):void 0},u.prototype.toPayload=function(t){var e={};return t.length>this._inputTypes.length&&o.isObject(t[t.length-1])&&(e=t[t.length-1]),e.to=this._address,e.data="0x"+this.signature()+i.encodeParams(this._inputTypes,t),e},u.prototype.signature=function(){return s(this._name).slice(0,8)},u.prototype.unpackOutput=function(t){if(t){t=t.length>=2?t.slice(2):t;var e=i.decodeParams(this._outputTypes,t);return 1===e.length?e[0]:e}},u.prototype.call=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.extractDefaultBlock(t),i=this.toPayload(t);if(!e){var o=r.eth.call(i,n);return this.unpackOutput(o)}var a=this;r.eth.call(i,n,function(t,n){e(t,a.unpackOutput(n))})},u.prototype.sendTransaction=function(){var t=Array.prototype.slice.call(arguments).filter(function(t){return void 0!==t}),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.sendTransaction(n,e):r.eth.sendTransaction(n)},u.prototype.estimateGas=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t);return e?void r.eth.estimateGas(n,e):r.eth.estimateGas(n)},u.prototype.displayName=function(){return o.extractDisplayName(this._name)},u.prototype.typeName=function(){return o.extractTypeName(this._name)},u.prototype.request=function(){var t=Array.prototype.slice.call(arguments),e=this.extractCallback(t),n=this.toPayload(t),r=this.unpackOutput.bind(this);return{method:this._constant?"eth_call":"eth_sendTransaction",callback:e,params:[n],format:r}},u.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))},u.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),e.estimateGas=this.estimateGas.bind(this);var n=this.displayName();t[n]||(t[n]=e),t[n][this.typeName()]=e},e.exports=u},{"../solidity/coder":1,"../utils/sha3":6,"../utils/utils":7,"../web3":9,"./formatters":18}],20:[function(t,e,n){"use strict";var r="undefined"!=typeof window&&window.XMLHttpRequest?window.XMLHttpRequest:t("xmlhttprequest").XMLHttpRequest,i=t("./errors"),o=function(t){this.host=t||"http://localhost:8545"};o.prototype.send=function(t){var e=new r;e.open("POST",this.host,!1),e.setRequestHeader("Content-type","application/json");try{e.send(JSON.stringify(t))}catch(n){throw i.InvalidConnection(this.host)}var o=e.responseText;try{o=JSON.parse(o)}catch(a){throw i.InvalidResponse(o)}return o},o.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(o){r=i.InvalidResponse(t)}e(r,t)}},n.open("POST",this.host,!0),n.setRequestHeader("Content-type","application/json");try{n.send(JSON.stringify(t))}catch(o){e(i.InvalidConnection(this.host))}},e.exports=o},{"./errors":14,xmlhttprequest:4}],21:[function(t,e,n){var r=t("../utils/utils"),i=function(t){this._iban=t};i.prototype.isValid=function(){return r.isIBAN(this._iban)},i.prototype.isDirect=function(){return 34===this._iban.length},i.prototype.isIndirect=function(){return 20===this._iban.length},i.prototype.checksum=function(){return this._iban.substr(2,2)},i.prototype.institution=function(){return this.isIndirect()?this._iban.substr(7,4):""},i.prototype.client=function(){return this.isIndirect()?this._iban.substr(11):""},i.prototype.address=function(){return this.isDirect()?this._iban.substr(4):""},e.exports=i},{"../utils/utils":7}],22:[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},{}],23:[function(t,e,n){var r=t("./requestmanager"),i=t("../utils/utils"),o=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 i.isFunction(this.call)?this.call(t):this.call},a.prototype.extractCallback=function(t){return i.isFunction(t[t.length-1])?t.pop():void 0},a.prototype.validateArgs=function(t){if(t.length!==this.params)throw o.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":7,"./errors":14,"./requestmanager":28}],24:[function(t,e,n){var r=t("./contract"),i="0xc6d9d2cd449a754c494264e1809c50e34d64562b",o=[{constant:!0,inputs:[{name:"_owner",type:"address"}],name:"name",outputs:[{name:"o_name",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"owner",outputs:[{name:"",type:"address"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"content",outputs:[{name:"",type:"bytes32"}],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"addr",outputs:[{name:"",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"reserve",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"subRegistrar",outputs:[{name:"o_subRegistrar",type:"address"}],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_newOwner",type:"address"}],name:"transfer",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_registrar",type:"address"}],name:"setSubRegistrar",outputs:[],type:"function"},{constant:!1,inputs:[],name:"Registrar",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_a",type:"address"},{name:"_primary",type:"bool"}],name:"setAddress",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"},{name:"_content",type:"bytes32"}],name:"setContent",outputs:[],type:"function"},{constant:!1,inputs:[{name:"_name",type:"bytes32"}],name:"disown",outputs:[],type:"function"},{constant:!0,inputs:[{name:"_name",type:"bytes32"}],name:"register",outputs:[{name:"",type:"address"}],type:"function"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"}],name:"Changed",type:"event"},{anonymous:!1,inputs:[{indexed:!0,name:"name",type:"bytes32"},{indexed:!0,name:"addr",type:"address"}],name:"PrimaryChanged",type:"event"}];e.exports=r(o).at(i)},{"./contract":12}],25:[function(t,e,n){var r=t("../utils/utils"),i=t("./property"),o=[],a=[new i({name:"listening",getter:"net_listening"}),new i({name:"peerCount",getter:"net_peerCount",outputFormatter:r.toDecimal})];e.exports={methods:o,properties:a}},{"../utils/utils":7,"./property":26}],26:[function(t,e,n){var r=t("./requestmanager"),i=function(t){this.name=t.name,this.getter=t.getter,this.setter=t.setter,this.outputFormatter=t.outputFormatter,this.inputFormatter=t.inputFormatter};i.prototype.formatInput=function(t){return this.inputFormatter?this.inputFormatter(t):t},i.prototype.formatOutput=function(t){return this.outputFormatter&&null!==t?this.outputFormatter(t):t},i.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 i=function(t,e){return t+e.charAt(0).toUpperCase()+e.slice(1)};t[i("get",r)]=this.getAsync.bind(this)},i.prototype.get=function(){return this.formatOutput(r.getInstance().send({method:this.getter}))},i.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=i},{"./requestmanager":28}],27:[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},{}],28:[function(t,e,n){var r=t("./jsonrpc"),i=t("../utils/utils"),o=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.isPolling=!1))};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):i.isArray(n)?void e(t,n):e(a.InvalidResponse(n))})},s.prototype.setProvider=function(t){this.provider=t,this.provider&&!this.isPolling&&(this.poll(),this.isPolling=!0)},s.prototype.startPolling=function(t,e,n,r){this.polls["poll_"+e]={data:t,id:e,callback:n,uninstall:r}},s.prototype.stopPolling=function(t){delete this.polls["poll_"+t]},s.prototype.reset=function(){for(var t in this.polls)this.polls[t].uninstall();this.polls={},this.timeout&&(clearTimeout(this.timeout),this.timeout=null),this.poll()},s.prototype.poll=function(){if(this.timeout=setTimeout(this.poll.bind(this),o.ETH_POLLING_TIMEOUT),0!==Object.keys(this.polls).length){if(!this.provider)return void console.error(a.InvalidProvider());var t=[],e=[];for(var n in this.polls)t.push(this.polls[n].data),e.push(n);if(0!==t.length){var s=r.getInstance().toBatchPayload(t),u=this;this.provider.sendAsync(s,function(t,n){if(!t){if(!i.isArray(n))throw a.InvalidResponse(n);n.map(function(t,n){var r=e[n];return u.polls[r]?(t.callback=u.polls[r].callback,t):!1}).filter(function(t){return!!t}).filter(function(t){var e=r.getInstance().isValidResponse(t);return e||t.callback(a.InvalidResponse(t)),e}).filter(function(t){return i.isArray(t.result)&&t.result.length>0}).forEach(function(t){t.callback(null,t.result)})}})}}},e.exports=s},{"../utils/config":5,"../utils/utils":7,"./errors":14,"./jsonrpc":22}],29:[function(t,e,n){var r=t("./method"),i=t("./formatters"),o=new r({name:"post",call:"shh_post",params:1,inputFormatter:[i.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=[o,a,s,u,c];e.exports={methods:l}},{"./formatters":18,"./method":23}],30:[function(t,e,n){var r=t("../web3"),i=t("./icap"),o=t("./namereg"),a=t("./contract"),s=function(t,e,n,r){var a=new i(e);if(!a.isValid())throw new Error("invalid iban address");if(a.isDirect())return u(t,a.address(),n,r);if(!r){var s=o.addr(a.institution());return c(t,s,n,a.client())}o.addr(a.insitution(),function(e,i){return c(t,i,n,a.client(),r)})},u=function(t,e,n,i){return r.eth.sendTransaction({address:e,from:t,value:n},i)},c=function(t,e,n,r,i){var o=[{constant:!1,inputs:[{name:"name",type:"bytes32"}],name:"deposit",outputs:[],type:"function"}];return a(o).at(e).deposit(r,{from:t,value:n},i)};e.exports=s},{"../web3":9,"./contract":12,"./icap":21,"./namereg":24}],31:[function(t,e,n){var r=t("./method"),i=function(){var t=function(t){var e=t[0];switch(e){case"latest":return t.shift(),this.params=0,"eth_newBlockFilter";case"pending":return t.shift(),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}),i=new r({name:"getLogs",call:"eth_getFilterLogs",params:1}),o=new r({name:"poll",call:"eth_getFilterChanges",params:1});return[e,n,i,o]},o=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}),i=new r({name:"poll",call:"shh_getFilterChanges",params:1});return[t,e,n,i]};e.exports={eth:i,shh:o}},{"./method":23}],32:[function(t,e,n){},{}],33:[function(t,e,n){!function(t,r){"object"==typeof n?e.exports=n=r():"function"==typeof define&&define.amd?define([],r):t.CryptoJS=r()}(this,function(){var t=t||function(t,e){var n={},r=n.lib={},i=r.Base=function(){function t(){}return{extend:function(e){t.prototype=this;var n=new t;return e&&n.mixIn(e),n.hasOwnProperty("init")||(n.init=function(){n.$super.init.apply(this,arguments)}),n.init.prototype=n,n.$super=this,n},create:function(){var t=this.extend();return t.init.apply(t,arguments),t},init:function(){},mixIn:function(t){for(var e in t)t.hasOwnProperty(e)&&(this[e]=t[e]);t.hasOwnProperty("toString")&&(this.toString=t.toString)},clone:function(){return this.init.prototype.extend(this)}}}(),o=r.WordArray=i.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:4*t.length},toString:function(t){return(t||s).stringify(this)},concat:function(t){var e=this.words,n=t.words,r=this.sigBytes,i=t.sigBytes;if(this.clamp(),r%4)for(var o=0;i>o;o++){var a=n[o>>>2]>>>24-o%4*8&255;e[r+o>>>2]|=a<<24-(r+o)%4*8}else for(var o=0;i>o;o+=4)e[r+o>>>2]=n[o>>>2];return this.sigBytes+=i,this},clamp:function(){var e=this.words,n=this.sigBytes;e[n>>>2]&=4294967295<<32-n%4*8,e.length=t.ceil(n/4)},clone:function(){var t=i.clone.call(this);return t.words=this.words.slice(0),t},random:function(e){for(var n,r=[],i=function(e){var e=e,n=987654321,r=4294967295;return function(){n=36969*(65535&n)+(n>>16)&r,e=18e3*(65535&e)+(e>>16)&r;var i=(n<<16)+e&r;return i/=4294967296,i+=.5,i*(t.random()>.5?1:-1)}},a=0;e>a;a+=4){var s=i(4294967296*(n||t.random()));n=987654071*s(),r.push(4294967296*s()|0)}return new o.init(r,e)}}),a=n.enc={},s=a.Hex={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],i=0;n>i;i++){var o=e[i>>>2]>>>24-i%4*8&255;r.push((o>>>4).toString(16)),r.push((15&o).toString(16))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r+=2)n[r>>>3]|=parseInt(t.substr(r,2),16)<<24-r%8*4;return new o.init(n,e/2)}},u=a.Latin1={stringify:function(t){for(var e=t.words,n=t.sigBytes,r=[],i=0;n>i;i++){var o=e[i>>>2]>>>24-i%4*8&255;r.push(String.fromCharCode(o))}return r.join("")},parse:function(t){for(var e=t.length,n=[],r=0;e>r;r++)n[r>>>2]|=(255&t.charCodeAt(r))<<24-r%4*8;return new o.init(n,e)}},c=a.Utf8={stringify:function(t){try{return decodeURIComponent(escape(u.stringify(t)))}catch(e){throw new Error("Malformed UTF-8 data")}},parse:function(t){return u.parse(unescape(encodeURIComponent(t)))}},l=r.BufferedBlockAlgorithm=i.extend({reset:function(){this._data=new o.init,this._nDataBytes=0},_append:function(t){"string"==typeof t&&(t=c.parse(t)),this._data.concat(t),this._nDataBytes+=t.sigBytes},_process:function(e){var n=this._data,r=n.words,i=n.sigBytes,a=this.blockSize,s=4*a,u=i/s;u=e?t.ceil(u):t.max((0|u)-this._minBufferSize,0);var c=u*a,l=t.min(4*c,i);if(c){for(var f=0;c>f;f+=a)this._doProcessBlock(r,f);var p=r.splice(0,c);n.sigBytes-=l}return new o.init(p,l)},clone:function(){var t=i.clone.call(this);return t._data=this._data.clone(),t},_minBufferSize:0}),f=(r.Hasher=l.extend({cfg:i.extend(),init:function(t){this.cfg=this.cfg.extend(t),this.reset()},reset:function(){l.reset.call(this),this._doReset()},update:function(t){return this._append(t),this._process(),this},finalize:function(t){t&&this._append(t);var e=this._doFinalize();return e},blockSize:16,_createHelper:function(t){return function(e,n){return new t.init(n).finalize(e)}},_createHmacHelper:function(t){return function(e,n){return new f.HMAC.init(t,n).finalize(e)}}}),n.algo={});return n}(Math);return t})},{}],34:[function(t,e,n){!function(r,i,o){"object"==typeof n?e.exports=n=i(t("./core"),t("./x64-core")):"function"==typeof define&&define.amd?define(["./core","./x64-core"],i):i(r.CryptoJS)}(this,function(t){return function(e){var n=t,r=n.lib,i=r.WordArray,o=r.Hasher,a=n.x64,s=a.Word,u=n.algo,c=[],l=[],f=[];!function(){for(var t=1,e=0,n=0;24>n;n++){c[t+5*e]=(n+1)*(n+2)/2%64;var r=e%5,i=(2*t+3*e)%5;t=r,e=i}for(var t=0;5>t;t++)for(var e=0;5>e;e++)l[t+5*e]=e+(2*t+3*e)%5*5;for(var o=1,a=0;24>a;a++){for(var u=0,p=0,h=0;7>h;h++){if(1&o){var m=(1<m?p^=1<t;t++)p[t]=s.create()}();var h=u.SHA3=o.extend({cfg:o.cfg.extend({outputLength:512}),_doReset:function(){for(var t=this._state=[],e=0;25>e;e++)t[e]=new s.init;this.blockSize=(1600-2*this.cfg.outputLength)/32},_doProcessBlock:function(t,e){for(var n=this._state,r=this.blockSize/2,i=0;r>i;i++){var o=t[e+2*i],a=t[e+2*i+1];o=16711935&(o<<8|o>>>24)|4278255360&(o<<24|o>>>8),a=16711935&(a<<8|a>>>24)|4278255360&(a<<24|a>>>8);var s=n[i];s.high^=a,s.low^=o}for(var u=0;24>u;u++){for(var h=0;5>h;h++){for(var m=0,d=0,g=0;5>g;g++){var s=n[h+5*g];m^=s.high,d^=s.low}var y=p[h];y.high=m,y.low=d}for(var h=0;5>h;h++)for(var v=p[(h+4)%5],w=p[(h+1)%5],b=w.high,_=w.low,m=v.high^(b<<1|_>>>31),d=v.low^(_<<1|b>>>31),g=0;5>g;g++){var s=n[h+5*g];s.high^=m,s.low^=d}for(var x=1;25>x;x++){var s=n[x],F=s.high,I=s.low,B=c[x];if(32>B)var m=F<>>32-B,d=I<>>32-B;else var m=I<>>64-B,d=F<>>64-B;var N=p[l[x]];N.high=m,N.low=d}var O=p[0],k=n[0];O.high=k.high,O.low=k.low;for(var h=0;5>h;h++)for(var g=0;5>g;g++){var x=h+5*g,s=n[x],A=p[x],P=p[(h+1)%5+5*g],T=p[(h+2)%5+5*g];s.high=A.high^~P.high&T.high,s.low=A.low^~P.low&T.low}var s=n[0],D=f[u];s.high^=D.high,s.low^=D.low}},_doFinalize:function(){var t=this._data,n=t.words,r=(8*this._nDataBytes,8*t.sigBytes),o=32*this.blockSize;n[r>>>5]|=1<<24-r%32,n[(e.ceil((r+1)/o)*o>>>5)-1]|=128,t.sigBytes=4*n.length,this._process();for(var a=this._state,s=this.cfg.outputLength/8,u=s/8,c=[],l=0;u>l;l++){var f=a[l],p=f.high,h=f.low;p=16711935&(p<<8|p>>>24)|4278255360&(p<<24|p>>>8),h=16711935&(h<<8|h>>>24)|4278255360&(h<<24|h>>>8),c.push(h),c.push(p)}return new i.init(c,s)},clone:function(){for(var t=o.clone.call(this),e=t._state=this._state.slice(0),n=0;25>n;n++)e[n]=e[n].clone();return t}});n.SHA3=o._createHelper(h),n.HmacSHA3=o._createHmacHelper(h)}(Math),t.SHA3})},{"./core":33,"./x64-core":35}],35:[function(t,e,n){!function(r,i){"object"==typeof n?e.exports=n=i(t("./core")):"function"==typeof define&&define.amd?define(["./core"],i):i(r.CryptoJS)}(this,function(t){return function(e){{var n=t,r=n.lib,i=r.Base,o=r.WordArray,a=n.x64={};a.Word=i.extend({init:function(t,e){this.high=t,this.low=e}}),a.WordArray=i.extend({init:function(t,n){t=this.words=t||[],this.sigBytes=n!=e?n:8*t.length},toX32:function(){for(var t=this.words,e=t.length,n=[],r=0;e>r;r++){var i=t[r];n.push(i.high),n.push(i.low)}return o.create(n,this.sigBytes)},clone:function(){for(var t=i.clone.call(this),e=t.words=this.words.slice(0),n=e.length,r=0;n>r;r++)e[r]=e[r].clone();return t}})}}(),t})},{"./core":33}],"bignumber.js":[function(t,e,n){!function(n){"use strict";function r(t){function e(t,r){var i,o,a,s,u,c,l=this;if(!(l instanceof e))return z&&D(26,"constructor call without new",t),new e(t,r);if(null!=r&&W(r,2,64,C,"base")){if(r=0|r,c=t+"",10==r)return l=new e(t instanceof e?t:c),S(l,j+l.e+1,L);if((s="number"==typeof t)&&0*t!=0||!new RegExp("^-?"+(i="["+x.slice(0,r)+"]+")+"(?:\\."+i+")?$",37>r?"i":"").test(c))return d(l,c,s,r);s?(l.s=0>1/t?(c=c.slice(1),-1):1,z&&c.replace(/^0\.0*|\./,"").length>15&&D(C,_,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(C=0);if((s="number"==typeof t)&&0*t==0){if(l.s=0>1/t?(t=-t,-1):1,t===~~t){for(o=0,a=t;a>=10;a/=10,o++);return l.e=o,l.c=[t],void(C=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((o=c.indexOf("."))>-1&&(c=c.replace(".","")),(a=c.search(/e/i))>0?(0>o&&(o=a),o+=+c.slice(a+1),c=c.substring(0,a)):0>o&&(o=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&&z&&u>15&&D(C,_,l.s*t),o=o-a-1,o>G)l.c=l.e=null;else if(M>o)l.c=[l.e=0];else{if(l.e=o,l.c=[],a=(o+1)%I,0>o&&(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];C=0}function n(t,n,r,i){var a,s,u,l,p,h,m,d=t.indexOf("."),g=j,y=L;for(37>r&&(t=t.toLowerCase()),d>=0&&(u=V,V=0,t=t.replace(".",""),m=new e(r),p=m.pow(t.length-d),V=u,m.c=c(f(o(p.c),p.e),10,n),m.e=m.c.length),h=c(t,r,n),s=u=h.length;0==h[--u];h.pop());if(!h[0])return"0";if(0>d?--s:(p.c=h,p.e=s,p.s=i,p=R(p,m,g,y,n),h=p.c,l=p.r,s=p.e),a=s+g+1,d=h[a],u=n/2,l=l||0>a||null!=h[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&h[a-1]||y==(p.s<0?8:7)),1>a||!h[0])t=l?f("1",-g):"0";else{if(h.length=a,l)for(--n;++h[--a]>n;)h[a]=0,a||(++s,h.unshift(1));for(u=h.length;!h[--u];);for(d=0,t="";u>=d;t+=x.charAt(h[d++]));t=f(t,s)}return t}function h(t,n,r,i){var a,s,u,c,p;if(r=null!=r&&W(r,0,8,i,b)?0|r:L,!t.c)return t.toString();if(a=t.c[0],u=t.e,null==n)p=o(t.c),p=19==i||24==i&&q>=u?l(p,u):f(p,u);else if(t=S(new e(t),n,r),s=t.e,p=o(t.c),c=p.length,19==i||24==i&&(s>=n||q>=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 A(t,n){var r,i,o=0;for(u(t[0])&&(t=t[0]),r=new e(t[0]);++ot||t>n||t!=p(t))&&D(r,(i||"decimal places")+(e>t||t>n?" out of range":" not an integer"),t),!0}function T(t,e,n){for(var r=1,i=e.length;!e[--i];e.pop());for(i=e[0];i>=10;i/=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",C=0,r}function S(t,e,n,r){var i,o,a,s,u,c,l,f=t.c,p=N;if(f){t:{for(i=1,s=f[0];s>=10;s/=10,i++);if(o=e-i,0>o)o+=I,a=e,u=f[c=0],l=u/p[i-a-1]%10|0;else if(c=y((o+1)/I),c>=f.length){if(!r)break t;for(;f.length<=c;f.push(0));u=l=0,i=1,o%=I,a=o-I+1}else{for(u=s=f[c],i=1;s>=10;s/=10,i++);o%=I,a=o-I+i,l=0>a?0:u/p[i-a-1]%10|0}if(r=r||0>e||null!=f[c+1]||(0>a?u:u%p[i-a-1]),r=4>n?(l||r)&&(0==n||n==(t.s<0?3:2)):l>5||5==l&&(4==n||r||6==n&&(o>0?a>0?u/p[i-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==o?(f.length=c,s=1,c--):(f.length=c+1,s=p[I-o],f[c]=a>0?v(u/p[i-a]%p[a])*s:0),r)for(;;){if(0==c){for(o=1,a=f[0];a>=10;a/=10,o++);for(a=f[0]+=s,s=1;a>=10;a/=10,s++);o!=s&&(t.e++,f[0]==F&&(f[0]=1));break}if(f[c]+=s,f[c]!=F)break;f[c--]=0,s=1}for(o=f.length;0===f[--o];f.pop());}t.e>G?t.c=t.e=null:t.en?null!=(t=i[n++]):void 0};return a(e="DECIMAL_PLACES")&&W(t,0,k,2,e)&&(j=0|t),r[e]=j,a(e="ROUNDING_MODE")&&W(t,0,8,2,e)&&(L=0|t),r[e]=L,a(e="EXPONENTIAL_AT")&&(u(t)?W(t[0],-k,0,2,e)&&W(t[1],0,k,2,e)&&(q=0|t[0],U=0|t[1]):W(t,-k,k,2,e)&&(q=-(U=0|(0>t?-t:t)))),r[e]=[q,U],a(e="RANGE")&&(u(t)?W(t[0],-k,-1,2,e)&&W(t[1],1,k,2,e)&&(M=0|t[0],G=0|t[1]):W(t,-k,k,2,e)&&(0|t?M=-(G=0|(0>t?-t:t)):z&&D(2,e+" cannot be zero",t))),r[e]=[M,G],a(e="ERRORS")&&(t===!!t||1===t||0===t?(C=0,W=(z=!!t)?P:s):z&&D(2,e+w,t)),r[e]=z,a(e="CRYPTO")&&(t===!!t||1===t||0===t?(J=!(!t||!m||"object"!=typeof m),t&&!J&&z&&D(2,"crypto unavailable",m)):z&&D(2,e+w,t)),r[e]=J,a(e="MODULO_MODE")&&W(t,0,9,2,e)&&($=0|t),r[e]=$,a(e="POW_PRECISION")&&W(t,0,k,2,e)&&(V=0|t),r[e]=V,a(e="FORMAT")&&("object"==typeof t?X=t:z&&D(2,e+" not an object",t)),r[e]=X,r},e.max=function(){return A(arguments,E.lt)},e.min=function(){return A(arguments,E.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,i,o,a,s,u=0,c=[],l=new e(H);if(t=null!=t&&W(t,0,k,14)?0|t:j,a=y(t/I),J)if(m&&m.getRandomValues){for(r=m.getRandomValues(new Uint32Array(a*=2));a>u;)s=131072*r[u]+(r[u+1]>>>11),s>=9e15?(i=m.getRandomValues(new Uint32Array(2)),r[u]=i[0],r[u+1]=i[1]):(c.push(s%1e14),u+=2);u=a/2}else if(m&&m.randomBytes){for(r=m.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?m.randomBytes(7).copy(r,u):(c.push(s%1e14),u+=7);u=a/7}else z&&D(14,"crypto unavailable",m);if(!u)for(;a>u;)s=n(),9e15>s&&(c[u++]=s%1e14);for(a=c[--u],t%=I,a&&t&&(s=N[I-t],c[u]=v(a/s)*s);0===c[u];c.pop(),u--);if(0>u)c=[o=0];else{for(o=-1;0===c[0];c.shift(),o-=I);for(u=1,s=c[0];s>=10;s/=10,u++);I>u&&(o-=I-u)}return l.e=o,l.c=c,l}}(),R=function(){function t(t,e,n){var r,i,o,a,s=0,u=t.length,c=e%O,l=e/O|0;for(t=t.slice();u--;)o=t[u]%O,a=t[u]/O|0,r=l*o+a*c,i=c*o+r%O*O+s,s=(i/n|0)+(r/O|0)+l*a,t[u]=i%n;return s&&t.unshift(s),t}function n(t,e,n,r){var i,o;if(n!=r)o=n>r?1:-1;else for(i=o=0;n>i;i++)if(t[i]!=e[i]){o=t[i]>e[i]?1:-1;break}return o}function r(t,e,n,r){for(var i=0;n--;)t[n]-=i,i=t[n]1;t.shift());}return function(o,a,s,u,c){var l,f,p,h,m,d,g,y,w,b,_,x,B,N,O,k,A,P=o.s==a.s?1:-1,T=o.c,D=a.c;if(!(T&&T[0]&&D&&D[0]))return new e(o.s&&a.s&&(T?!D||T[0]!=D[0]:D)?T&&0==T[0]||!D?0*P:P/0:0/0);for(y=new e(P),w=y.c=[],f=o.e-a.e,P=s+f+1,c||(c=F,f=i(o.e/I)-i(a.e/I),P=P/I|0),p=0;D[p]==(T[p]||0);p++);if(D[p]>(T[p]||0)&&f--,0>P)w.push(1),h=!0;else{for(N=T.length,k=D.length,p=0,P+=2,m=v(c/(D[0]+1)),m>1&&(D=t(D,m,c),T=t(T,m,c),k=D.length,N=T.length),B=k,b=T.slice(0,k),_=b.length;k>_;b[_++]=0);A=D.slice(),A.unshift(0),O=D[0],D[1]>=c/2&&O++;do{if(m=0,l=n(D,b,k,_),0>l){if(x=b[0],k!=_&&(x=x*c+(b[1]||0)),m=v(x/O),m>1)for(m>=c&&(m=c-1),d=t(D,m,c),g=d.length,_=b.length;1==n(d,b,g,_);)m--,r(d,g>k?A:D,g,c),g=d.length,l=1;else 0==m&&(l=m=1),d=D.slice(),g=d.length;if(_>g&&d.unshift(0),r(b,d,_,c),_=b.length,-1==l)for(;n(D,b,k,_)<1;)m++,r(b,_>k?A:D,_,c),_=b.length}else 0===l&&(m++,b=[0]);w[p++]=m,b[0]?b[_++]=T[B]||0:(b=[T[B]],_=1)}while((B++=10;P/=10,p++);S(y,s+(y.e=p+f*I-1)+1,u,h)}else y.e=f,y.r=+h;return y}}(),d=function(){var t=/^(-?)0([xbo])/i,n=/^([^.]+)\.$/,r=/^\.([^.]+)$/,i=/^-?(Infinity|NaN)$/,o=/^\s*\+|^\s+|\s+$/g;return function(a,s,u,c){var l,f=u?s:s.replace(o,"");if(i.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);z&&D(C,"not a"+(c?" base "+c:"")+" number",s),a.s=null}a.c=a.e=null,C=0}}(),E.absoluteValue=E.abs=function(){var t=new e(this);return t.s<0&&(t.s=1),t},E.ceil=function(){return S(new e(this),this.e+1,2)},E.comparedTo=E.cmp=function(t,n){return C=1,a(this,new e(t,n))},E.decimalPlaces=E.dp=function(){var t,e,n=this.c;if(!n)return null;if(t=((e=n.length-1)-i(this.e/I))*I,e=n[e])for(;e%10==0;e/=10,t--);return 0>t&&(t=0),t},E.dividedBy=E.div=function(t,n){return C=3,R(this,new e(t,n),j,L)},E.dividedToIntegerBy=E.divToInt=function(t,n){return C=4,R(this,new e(t,n),0,1)},E.equals=E.eq=function(t,n){return C=5,0===a(this,new e(t,n))},E.floor=function(){return S(new e(this),this.e+1,3)},E.greaterThan=E.gt=function(t,n){return C=6,a(this,new e(t,n))>0},E.greaterThanOrEqualTo=E.gte=function(t,n){return C=7,1===(n=a(this,new e(t,n)))||0===n},E.isFinite=function(){return!!this.c},E.isInteger=E.isInt=function(){return!!this.c&&i(this.e/I)>this.c.length-2},E.isNaN=function(){return!this.s},E.isNegative=E.isNeg=function(){return this.s<0},E.isZero=function(){return!!this.c&&0==this.c[0]},E.lessThan=E.lt=function(t,n){return C=8,a(this,new e(t,n))<0},E.lessThanOrEqualTo=E.lte=function(t,n){return C=9,-1===(n=a(this,new e(t,n)))||0===n},E.minus=E.sub=function(t,n){var r,o,a,s,u=this,c=u.s;if(C=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,h=t.c;if(!l||!f){if(!p||!h)return p?(t.s=-n,t):new e(h?u:0/0);if(!p[0]||!h[0])return h[0]?(t.s=-n,t):new e(p[0]?u:3==L?-0:0)}if(l=i(l),f=i(f),p=p.slice(),c=l-f){for((s=0>c)?(c=-c,a=p):(f=l,a=h),a.reverse(),n=c;n--;a.push(0));a.reverse()}else for(o=(s=(c=p.length)<(n=h.length))?c:n,c=n=0;o>n;n++)if(p[n]!=h[n]){s=p[n]0)for(;n--;p[r++]=0);for(n=F-1;o>c;){if(p[--o]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)/F|0,c[n]%=F;return a&&(c.unshift(a),++u),T(t,c,u)},E.precision=E.sd=function(t){var e,n,r=this,i=r.c;if(null!=t&&t!==!!t&&1!==t&&0!==t&&(z&&D(13,"argument"+w,t),t!=!!t&&(t=null)),!i)return null;if(n=i.length-1,e=n*I+1,n=i[n]){for(;n%10==0;n/=10,e--);for(n=i[0];n>=10;n/=10,e++);}return t&&r.e+1>e&&(e=r.e+1),e},E.round=function(t,n){var r=new e(this);return(null==t||W(t,0,k,15))&&S(r,~~t+this.e+1,null!=n&&W(n,0,8,15,b)?0|n:L),r},E.shift=function(t){var n=this;return W(t,-B,B,16,"argument")?n.times("1e"+p(t)):new e(n.c&&n.c[0]&&(-B>t||t>B)?n.s*(0>t?0:1/0):n)},E.squareRoot=E.sqrt=function(){var t,n,r,a,s,u=this,c=u.c,l=u.s,f=u.e,p=j+4,h=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=o(c),(n.length+f)%2==0&&(n+="0"),l=Math.sqrt(n),f=i((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=h.times(s.plus(R(u,s,p,1))),o(s.c).slice(0,l)===(n=o(r.c)).slice(0,l)){if(r.el&&(g=b,b=_,_=g,a=l,l=h,h=a),a=l+h,g=[];a--;g.push(0));for(y=F,v=O,a=h;--a>=0;){for(r=0,m=_[a]%v,d=_[a]/v|0,u=l,s=a+u;s>a;)f=b[--u]%v,p=b[u]/v|0,c=d*f+p*m,f=m*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?++o:g.shift(),T(t,g,o)},E.toDigits=function(t,n){var r=new e(this);return t=null!=t&&W(t,1,k,18,"precision")?0|t:null,n=null!=n&&W(n,0,8,18,b)?0|n:L,t?S(r,t,n):r},E.toExponential=function(t,e){return h(this,null!=t&&W(t,0,k,19)?~~t+1:null,e,19)},E.toFixed=function(t,e){return h(this,null!=t&&W(t,0,k,20)?~~t+this.e+1:null,e,20)},E.toFormat=function(t,e){var n=h(this,null!=t&&W(t,0,k,21)?~~t+this.e+1:null,e,21);if(this.c){var r,i=n.split("."),o=+X.groupSize,a=+X.secondaryGroupSize,s=X.groupSeparator,u=i[0],c=i[1],l=this.s<0,f=l?u.slice(1):u,p=f.length;if(a&&(r=o,o=a,a=r,p-=r),o>0&&p>0){for(r=p%o||o,u=f.substr(0,r);p>r;r+=o)u+=s+f.substr(r,o);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},E.toFraction=function(t){var n,r,i,a,s,u,c,l,f,p=z,h=this,m=h.c,d=new e(H),g=r=new e(H),y=c=new e(H);if(null!=t&&(z=!1,u=new e(t),z=p,(!(p=u.isInt())||u.lt(H))&&(z&&D(22,"max denominator "+(p?"out of range":"not an integer"),t),t=!p&&u.c&&S(u,u.e+1,1).gte(H)?u:null)),!m)return h.toString();for(f=o(m),a=d.e=f.length-h.e-1,d.c[0]=N[(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=R(u,d,0,1),i=r.plus(l.times(y)),1!=i.cmp(t);)r=y,y=i,g=c.plus(l.times(i=g)),c=i,d=u.minus(l.times(i=d)),u=i;return i=R(t.minus(r),y,0,1),c=c.plus(i.times(g)),r=r.plus(i.times(y)),c.s=g.s=h.s,a*=2,n=R(g,y,a,L).minus(h).abs().cmp(R(c,r,a,L).minus(h).abs())<1?[g.toString(),y.toString()]:[c.toString(),r.toString()],G=s,n},E.toNumber=function(){var t=this;return+t||(t.s?0*t.s:0/0)},E.toPower=E.pow=function(t){var n,r,i=v(0>t?-t:+t),o=this;if(!W(t,-B,B,23,"exponent")&&(!isFinite(t)||i>B&&(t/=0)||parseFloat(t)!=t&&!(t=0/0)))return new e(Math.pow(+o,t));for(n=V?y(V/I+2):0,r=new e(H);;){if(i%2){if(r=r.times(o),!r.c)break;n&&r.c.length>n&&(r.c.length=n)}if(i=v(i/2),!i)break;o=o.times(o),n&&o.c&&o.c.length>n&&(o.c.length=n)}return 0>t&&(r=H.div(r)),n?S(r,V,L):r},E.toPrecision=function(t,e){return h(this,null!=t&&W(t,1,k,24,"precision")?0|t:null,e,24)},E.toString=function(t){var e,r=this,i=r.s,a=r.e;return null===a?i?(e="Infinity",0>i&&(e="-"+e)):e="NaN":(e=o(r.c),e=null!=t&&W(t,2,64,25,"base")?n(f(e,a),0|t,10,i):q>=a||a>=U?l(e,a):f(e,a),0>i&&r.c[0]&&(e="-"+e)),e},E.truncated=E.trunc=function(){return S(new e(this),this.e+1,1)},E.valueOf=E.toJSON=function(){return this.toString()},null!=t&&e.config(t),e}function i(t){var e=0|t;return t>0||t===e?e:e-1}function o(t){for(var e,n,r=1,i=t.length,o=t[0]+"";i>r;){for(e=t[r++]+"",n=I-e.length;n--;e="0"+e);o+=e}for(i=o.length;48===o.charCodeAt(--i););return o.slice(0,i+1||1)}function a(t,e){var n,r,i=t.c,o=e.c,a=t.s,s=e.s,u=t.e,c=e.e;if(!a||!s)return null;if(n=i&&!i[0],r=o&&!o[0],n||r)return n?r?0:-s:a; + +if(a!=s)return a;if(n=0>a,r=u==c,!i||!o)return r?0:!i^n?1:-1;if(!r)return u>c^n?1:-1;for(s=(u=i.length)<(c=o.length)?u:c,a=0;s>a;a++)if(i[a]!=o[a])return i[a]>o[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,i,o=[0],a=0,s=t.length;s>a;){for(i=o.length;i--;o[i]*=e);for(o[r=0]+=x.indexOf(t.charAt(a++));rn-1&&(null==o[r+1]&&(o[r+1]=0),o[r+1]+=o[r]/n|0,o[r]%=n)}return o.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 h,m,d,g=/^-?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i,y=Math.ceil,v=Math.floor,w=" not a boolean or binary digit",b="rounding mode",_="number type has more than 15 significant digits",x="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_",F=1e14,I=14,B=9007199254740991,N=[1,10,100,1e3,1e4,1e5,1e6,1e7,1e8,1e9,1e10,1e11,1e12,1e13],O=1e7,k=1e9;if(h=r(),"function"==typeof define&&define.amd)define(function(){return h});else if("undefined"!=typeof e&&e.exports){if(e.exports=h,!m)try{m=t("crypto")}catch(A){}}else n.BigNumber=h}(this)},{crypto:32}],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.eth.namereg=t("./lib/web3/namereg"),r.eth.sendIBANTransaction=t("./lib/web3/transfer"),"undefined"!=typeof window&&"undefined"==typeof window.web3&&(window.web3=r),e.exports=r},{"./lib/web3":9,"./lib/web3/contract":12,"./lib/web3/httpprovider":20,"./lib/web3/namereg":24,"./lib/web3/qtsync":27,"./lib/web3/transfer":30}]},{},["web3"]); \ No newline at end of file diff --git a/libjsqrc/ethereumjs/example/contract_array.html b/libjsqrc/ethereumjs/example/contract_array.html new file mode 100644 index 000000000..421e42baf --- /dev/null +++ b/libjsqrc/ethereumjs/example/contract_array.html @@ -0,0 +1,83 @@ + + + + + + + + +

contract

+
+
+
+ +
+ +
+ + + diff --git a/libjsqrc/ethereumjs/gulpfile.js b/libjsqrc/ethereumjs/gulpfile.js index 360c5242b..1291e3028 100644 --- a/libjsqrc/ethereumjs/gulpfile.js +++ b/libjsqrc/ethereumjs/gulpfile.js @@ -17,7 +17,7 @@ var bower = require('bower'); var streamify = require('gulp-streamify'); var replace = require('gulp-replace'); -var DEST = './dist/'; +var DEST = path.join(__dirname, 'dist/'); var src = 'index'; var dst = 'web3'; var lightDst = 'web3-light'; @@ -29,7 +29,7 @@ var browserifyOptions = { bundleExternal: true }; -gulp.task('versionReplace', function(){ +gulp.task('version', function(){ gulp.src(['./package.json']) .pipe(replace(/\"version\"\: \"(.{5})\"/, '"version": "'+ version.version + '"')) .pipe(gulp.dest('./')); @@ -41,24 +41,24 @@ gulp.task('versionReplace', function(){ .pipe(gulp.dest('./')); }); -gulp.task('bower', function(cb){ +gulp.task('bower', ['version'], function(cb){ bower.commands.install().on('end', function (installed){ console.log(installed); cb(); }); }); -gulp.task('clean', ['lint'], function(cb) { - del([ DEST ], cb); -}); - -gulp.task('lint', function(){ +gulp.task('lint', ['bower'], function(){ return gulp.src(['./*.js', './lib/*.js']) .pipe(jshint()) .pipe(jshint.reporter('default')); }); -gulp.task('buildLight', ['clean'], function () { +gulp.task('clean', ['lint'], function(cb) { + del([ DEST ], cb); +}); + +gulp.task('light', ['clean'], function () { return browserify(browserifyOptions) .require('./' + src + '.js', {expose: 'web3'}) .ignore('bignumber.js') @@ -73,7 +73,7 @@ gulp.task('buildLight', ['clean'], function () { .pipe(gulp.dest( DEST )); }); -gulp.task('buildStandalone', ['clean'], function () { +gulp.task('standalone', ['clean'], function () { return browserify(browserifyOptions) .require('./' + src + '.js', {expose: 'web3'}) .require('bignumber.js') // expose it to dapp users @@ -92,10 +92,5 @@ gulp.task('watch', function() { gulp.watch(['./lib/*.js'], ['lint', 'build']); }); -gulp.task('light', ['versionReplace','bower', 'lint', 'buildLight']); -gulp.task('standalone', ['versionReplace','bower', 'lint', 'buildStandalone']); -gulp.task('default', ['light', 'standalone']); - - -gulp.task('version', ['versionReplace']); +gulp.task('default', ['version', 'bower', 'lint', 'clean', 'light', 'standalone']); diff --git a/libjsqrc/ethereumjs/karma.conf.js b/libjsqrc/ethereumjs/karma.conf.js deleted file mode 100644 index 9375315f7..000000000 --- a/libjsqrc/ethereumjs/karma.conf.js +++ /dev/null @@ -1,95 +0,0 @@ -// Karma configuration -// Generated on Thu Feb 19 2015 19:57:47 GMT+0100 (W. Europe Standard Time) - -module.exports = function (config) { - config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) - basePath: '', - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits - singleRun: true, logLevel: config.LOG_INFO, - //singleRun: true, logLevel: config.LOG_DEBUG, - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter - frameworks: ['browserify', 'mocha'], - - - // list of files / patterns to load in the browser - files: [ - 'test/*.js' - ], - - - // list of files to exclude - exclude: [ - ], - - client: { - mocha: { - //ui: 'tdd' - timeout: 5000 // especially for the post requests - } - }, - browserify: { - bundleDelay: 750, - debug: true - // transform: [], - // //extensions: ['.js'] - }, - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor - preprocessors: { - 'test/*.js': ['browserify'] - }, - - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['dots'], - - - // web server port - port: 9876, - - - // enable / disable colors in the output (reporters and logs) - colors: true, - - - // enable / disable watching file and executing tests whenever any file changes - autoWatch: true, - - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher - // // Chrome - // // PhantomJS - browsers: ['Chrome', 'Safari', 'Firefox'], - browserNoActivityTimeout: 10000, - browserDisconnectTimeout: 5000, - - customLaunchers: { - chromeWithoutSecurity: { - base: 'Chrome', - flags: ['--disable-web-security'] - }, - - IE9: { - base: 'IE', - 'x-ua-compatible': 'IE=EmulateIE9' - }, - IE8: { - base: 'IE', - 'x-ua-compatible': 'IE=EmulateIE8' - } - } - }); -}; diff --git a/libjsqrc/ethereumjs/lib/solidity/coder.js b/libjsqrc/ethereumjs/lib/solidity/coder.js index b46a38b0b..59b001fdd 100644 --- a/libjsqrc/ethereumjs/lib/solidity/coder.js +++ b/libjsqrc/ethereumjs/lib/solidity/coder.js @@ -262,6 +262,13 @@ var coder = new SolidityCoder([ inputFormatter: f.formatInputBytes, outputFormatter: f.formatOutputBytes }), + new SolidityType({ + name: 'string', + match: 'strict', + mode: 'bytes', + inputFormatter: f.formatInputString, + outputFormatter: f.formatOutputString + }), new SolidityType({ name: 'real', match: 'prefix', diff --git a/libjsqrc/ethereumjs/lib/solidity/formatters.js b/libjsqrc/ethereumjs/lib/solidity/formatters.js index 3db936528..de388cfd9 100644 --- a/libjsqrc/ethereumjs/lib/solidity/formatters.js +++ b/libjsqrc/ethereumjs/lib/solidity/formatters.js @@ -43,26 +43,43 @@ var formatInputInt = function (value) { }; /** - * Formats input value to byte representation of string + * Formats input bytes * * @method formatInputBytes * @param {String} * @returns {SolidityParam} */ var formatInputBytes = function (value) { - var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); + var result = utils.padRight(utils.toHex(value).substr(2), 64); return new SolidityParam(result); }; /** - * Formats input value to byte representation of string + * Formats input bytes * - * @method formatInputDynamicBytes + * @method formatDynamicInputBytes * @param {String} * @returns {SolidityParam} */ var formatInputDynamicBytes = function (value) { - var result = utils.fromAscii(value, c.ETH_PADDING).substr(2); + value = utils.toHex(value).substr(2); + var l = Math.floor((value.length + 63) / 64); + var result = utils.padRight(value, l * 64); + var length = Math.floor(value.length / 2); + return new SolidityParam(formatInputInt(length).value + result, 32); +}; + +/** + * Formats input value to byte representation of string + * + * @method formatInputString + * @param {String} + * @returns {SolidityParam} + */ +var formatInputString = function (value) { + var result = utils.fromAscii(value).substr(2); + var l = Math.floor((result.length + 63) / 64); + result = utils.padRight(result, l * 64); return new SolidityParam(formatInputInt(value.length).value + result, 32); }; @@ -165,27 +182,38 @@ var formatOutputBool = function (param) { }; /** - * Should be used to format output string + * Should be used to format output bytes * * @method formatOutputBytes * @param {SolidityParam} left-aligned hex representation of string - * @returns {String} ascii string + * @returns {String} hex string */ var formatOutputBytes = function (param) { - // length might also be important! - return utils.toAscii(param.staticPart()); + return '0x' + param.staticPart(); }; /** - * Should be used to format output string + * Should be used to format output bytes * * @method formatOutputDynamicBytes * @param {SolidityParam} left-aligned hex representation of string - * @returns {String} ascii string + * @returns {String} hex string */ var formatOutputDynamicBytes = function (param) { - // length might also be important! - return utils.toAscii(param.dynamicPart().slice(64)); + var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; + return '0x' + param.dynamicPart().substr(64, length); +}; + +/** + * Should be used to format output string + * + * @method formatOutputString + * @param {SolidityParam} left-aligned hex representation of string + * @returns {String} ascii string + */ +var formatOutputString = function (param) { + var length = (new BigNumber(param.dynamicPart().slice(0, 64), 16)).toNumber() * 2; + return utils.toAscii(param.dynamicPart().substr(64, length)); }; /** @@ -204,6 +232,7 @@ module.exports = { formatInputInt: formatInputInt, formatInputBytes: formatInputBytes, formatInputDynamicBytes: formatInputDynamicBytes, + formatInputString: formatInputString, formatInputBool: formatInputBool, formatInputReal: formatInputReal, formatOutputInt: formatOutputInt, @@ -213,6 +242,7 @@ module.exports = { formatOutputBool: formatOutputBool, formatOutputBytes: formatOutputBytes, formatOutputDynamicBytes: formatOutputDynamicBytes, + formatOutputString: formatOutputString, formatOutputAddress: formatOutputAddress }; diff --git a/libjsqrc/ethereumjs/lib/solidity/param.js b/libjsqrc/ethereumjs/lib/solidity/param.js index 25fa3f4f8..2a78a9b66 100644 --- a/libjsqrc/ethereumjs/lib/solidity/param.js +++ b/libjsqrc/ethereumjs/lib/solidity/param.js @@ -182,13 +182,14 @@ var getOffset = function (bytes, index) { */ SolidityParam.decodeBytes = function (bytes, index) { index = index || 0; - //TODO add support for strings longer than 32 bytes - //var length = parseInt('0x' + bytes.substr(offset * 64, 64)); var offset = getOffset(bytes, index); - // 2 * , cause we also parse length - return new SolidityParam(bytes.substr(offset * 2, 2 * 64), 0); + var l = parseInt('0x' + bytes.substr(offset * 2, 64)); + l = Math.floor((l + 31) / 32); + + // (1 + l) * , cause we also parse length + return new SolidityParam(bytes.substr(offset * 2, (1 + l) * 64), 0); }; /** diff --git a/libjsqrc/ethereumjs/lib/utils/utils.js b/libjsqrc/ethereumjs/lib/utils/utils.js index 42363ab88..7d6057713 100644 --- a/libjsqrc/ethereumjs/lib/utils/utils.js +++ b/libjsqrc/ethereumjs/lib/utils/utils.js @@ -75,6 +75,19 @@ var padLeft = function (string, chars, sign) { return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; }; +/** + * Should be called to pad string to expected length + * + * @method padRight + * @param {String} string to be padded + * @param {Number} characters that result string should have + * @param {String} sign, by default 0 + * @returns {String} right aligned string + */ +var padRight = function (string, chars, sign) { + return string + (new Array(chars - string.length + 1).join(sign ? sign : "0")); +}; + /** * Should be called to get sting from it's hex representation * @@ -91,10 +104,6 @@ var toAscii = function(hex) { } for (; i < l; i+=2) { var code = parseInt(hex.substr(i, 2), 16); - if (code === 0) { - break; - } - str += String.fromCharCode(code); } @@ -204,7 +213,7 @@ var fromDecimal = function (value) { * @return {String} */ var toHex = function (val) { - /*jshint maxcomplexity:7 */ + /*jshint maxcomplexity: 8 */ if (isBoolean(val)) return fromDecimal(+val); @@ -218,9 +227,11 @@ var toHex = function (val) { // if its a negative number, pass it through fromDecimal if (isString(val)) { if (val.indexOf('-0x') === 0) - return fromDecimal(val); + return fromDecimal(val); else if (!isFinite(val)) return fromAscii(val); + else if(val.indexOf('0x') === 0) + return val; } return fromDecimal(val); @@ -471,6 +482,7 @@ var isIBAN = function (iban) { module.exports = { padLeft: padLeft, + padRight: padRight, toHex: toHex, toDecimal: toDecimal, fromDecimal: fromDecimal, diff --git a/libjsqrc/ethereumjs/lib/version.json b/libjsqrc/ethereumjs/lib/version.json index 424d60960..4fe134016 100644 --- a/libjsqrc/ethereumjs/lib/version.json +++ b/libjsqrc/ethereumjs/lib/version.json @@ -1,3 +1,3 @@ { - "version": "0.6.0" + "version": "0.7.1" } diff --git a/libjsqrc/ethereumjs/lib/web3.js b/libjsqrc/ethereumjs/lib/web3.js index 66eea6ee1..8f684d132 100644 --- a/libjsqrc/ethereumjs/lib/web3.js +++ b/libjsqrc/ethereumjs/lib/web3.js @@ -80,31 +80,25 @@ var setupProperties = function (obj, properties) { /// setups web3 object, and it's in-browser executed methods var web3 = {}; web3.providers = {}; +web3.currentProvider = null; web3.version = {}; web3.version.api = version.version; web3.eth = {}; /*jshint maxparams:4 */ -web3.eth.filter = function (fil, eventParams, options, formatter) { - - // if its event, treat it differently - // TODO: simplify and remove - if (fil._isEvent) { - return fil(eventParams, options); - } - - // output logs works for blockFilter and pendingTransaction filters? - return new Filter(fil, watches.eth(), formatter || formatters.outputLogFormatter); +web3.eth.filter = function (fil, callback) { + return new Filter(fil, watches.eth(), formatters.outputLogFormatter, callback); }; /*jshint maxparams:3 */ web3.shh = {}; -web3.shh.filter = function (fil) { - return new Filter(fil, watches.shh(), formatters.outputPostFormatter); +web3.shh.filter = function (fil, callback) { + return new Filter(fil, watches.shh(), formatters.outputPostFormatter, callback); }; web3.net = {}; web3.db = {}; web3.setProvider = function (provider) { + this.currentProvider = provider; RequestManager.getInstance().setProvider(provider); }; web3.reset = function () { diff --git a/libjsqrc/ethereumjs/lib/web3/allevents.js b/libjsqrc/ethereumjs/lib/web3/allevents.js new file mode 100644 index 000000000..190643034 --- /dev/null +++ b/libjsqrc/ethereumjs/lib/web3/allevents.js @@ -0,0 +1,81 @@ +/* + 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 allevents.js + * @author Marek Kotewicz + * @date 2014 + */ + +var sha3 = require('../utils/sha3'); +var SolidityEvent = require('./event'); +var formatters = require('./formatters'); +var utils = require('../utils/utils'); +var Filter = require('./filter'); +var watches = require('./watches'); + +var AllSolidityEvents = function (json, address) { + this._json = json; + this._address = address; +}; + +AllSolidityEvents.prototype.encode = function (options) { + options = options || {}; + var result = {}; + + ['fromBlock', 'toBlock'].filter(function (f) { + return options[f] !== undefined; + }).forEach(function (f) { + result[f] = formatters.inputBlockNumberFormatter(options[f]); + }); + + result.topics = [null, null, null, null, null]; // match all topics + result.address = this._address; + + return result; +}; + +AllSolidityEvents.prototype.decode = function (data) { + data.data = data.data || ''; + data.topics = data.topics || []; + + var eventTopic = data.topics[0].slice(2); + var match = this._json.filter(function (j) { + return eventTopic === sha3(utils.transformToFullName(j)); + })[0]; + + if (!match) { // cannot find matching event? + console.warn('cannot find event for log'); + return data; + } + + var event = new SolidityEvent(match, this._address); + return event.decode(data); +}; + +AllSolidityEvents.prototype.execute = function (options, callback) { + var o = this.encode(options); + var formatter = this.decode.bind(this); + return new Filter(o, watches.eth(), formatter, callback); +}; + +AllSolidityEvents.prototype.attachToContract = function (contract) { + var execute = this.execute.bind(this); + contract.allEvents = execute; +}; + +module.exports = AllSolidityEvents; + diff --git a/libjsqrc/ethereumjs/lib/web3/contract.js b/libjsqrc/ethereumjs/lib/web3/contract.js index 9666f9eaa..433e7ecba 100644 --- a/libjsqrc/ethereumjs/lib/web3/contract.js +++ b/libjsqrc/ethereumjs/lib/web3/contract.js @@ -25,6 +25,7 @@ var utils = require('../utils/utils'); var coder = require('../solidity/coder'); var SolidityEvent = require('./event'); var SolidityFunction = require('./function'); +var AllEvents = require('./allevents'); /** * Should be called to encode constructor params @@ -70,9 +71,14 @@ var addFunctionsToContract = function (contract, abi) { * @param {Array} abi */ var addEventsToContract = function (contract, abi) { - abi.filter(function (json) { + var events = abi.filter(function (json) { return json.type === 'event'; - }).map(function (json) { + }); + + var All = new AllEvents(events, contract.address); + All.attachToContract(contract); + + events.map(function (json) { return new SolidityEvent(json, contract.address); }).forEach(function (e) { e.attachToContract(contract); diff --git a/libjsqrc/ethereumjs/lib/web3/event.js b/libjsqrc/ethereumjs/lib/web3/event.js index 7295cf63d..f2b40e3ea 100644 --- a/libjsqrc/ethereumjs/lib/web3/event.js +++ b/libjsqrc/ethereumjs/lib/web3/event.js @@ -22,9 +22,10 @@ var utils = require('../utils/utils'); var coder = require('../solidity/coder'); -var web3 = require('../web3'); var formatters = require('./formatters'); var sha3 = require('../utils/sha3'); +var Filter = require('./filter'); +var watches = require('./watches'); /** * This prototype should be used to create event filters @@ -170,10 +171,21 @@ SolidityEvent.prototype.decode = function (data) { * @param {Object} options * @return {Object} filter object */ -SolidityEvent.prototype.execute = function (indexed, options) { +SolidityEvent.prototype.execute = function (indexed, options, callback) { + + if (utils.isFunction(arguments[arguments.length - 1])) { + callback = arguments[arguments.length - 1]; + if(arguments.length === 2) + options = null; + if(arguments.length === 1) { + options = null; + indexed = {}; + } + } + var o = this.encode(indexed, options); var formatter = this.decode.bind(this); - return web3.eth.filter(o, undefined, undefined, formatter); + return new Filter(o, watches.eth(), formatter, callback); }; /** diff --git a/libjsqrc/ethereumjs/lib/web3/filter.js b/libjsqrc/ethereumjs/lib/web3/filter.js index bb760c3dc..0361aa0b8 100644 --- a/libjsqrc/ethereumjs/lib/web3/filter.js +++ b/libjsqrc/ethereumjs/lib/web3/filter.js @@ -127,7 +127,7 @@ var pollFilter = function(self) { }; -var Filter = function (options, methods, formatter) { +var Filter = function (options, methods, formatter, callback) { var self = this; var implementation = {}; methods.forEach(function (method) { @@ -135,23 +135,32 @@ var Filter = function (options, methods, formatter) { }); this.options = getOptions(options); this.implementation = implementation; + this.filterId = null; this.callbacks = []; this.pollFilters = []; this.formatter = formatter; this.implementation.newFilter(this.options, function(error, id){ if(error) { - self.callbacks.forEach(function(callback){ - callback(error); + self.callbacks.forEach(function(cb){ + cb(error); }); } else { self.filterId = id; - // get filter logs at start - self.callbacks.forEach(function(callback){ - getLogsAtStart(self, callback); + + // get filter logs for the already existing watch calls + self.callbacks.forEach(function(cb){ + getLogsAtStart(self, cb); }); - pollFilter(self); + if(self.callbacks.length > 0) + pollFilter(self); + + // start to watch immediately + if(callback) { + return self.watch(callback); + } } }); + }; Filter.prototype.watch = function (callback) { diff --git a/libjsqrc/ethereumjs/lib/web3/function.js b/libjsqrc/ethereumjs/lib/web3/function.js index c510adf15..918d367f9 100644 --- a/libjsqrc/ethereumjs/lib/web3/function.js +++ b/libjsqrc/ethereumjs/lib/web3/function.js @@ -188,8 +188,9 @@ SolidityFunction.prototype.request = function () { var format = this.unpackOutput.bind(this); return { + method: this._constant ? 'eth_call' : 'eth_sendTransaction', callback: callback, - payload: payload, + params: [payload], format: format }; }; diff --git a/libjsqrc/ethereumjs/lib/web3/httpprovider.js b/libjsqrc/ethereumjs/lib/web3/httpprovider.js index d3ac9cc34..6bdf32a85 100644 --- a/libjsqrc/ethereumjs/lib/web3/httpprovider.js +++ b/libjsqrc/ethereumjs/lib/web3/httpprovider.js @@ -24,7 +24,8 @@ "use strict"; -var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line +// resolves the problem for electron/atom shell environments, which use node integration, but have no process variable available +var XMLHttpRequest = (typeof window !== 'undefined' && window.XMLHttpRequest) ? window.XMLHttpRequest : require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line var errors = require('./errors'); var HttpProvider = function (host) { diff --git a/libjsqrc/ethereumjs/package-init.js b/libjsqrc/ethereumjs/package-init.js index 90313013b..efc2da65b 100644 --- a/libjsqrc/ethereumjs/package-init.js +++ b/libjsqrc/ethereumjs/package-init.js @@ -1,8 +1,17 @@ /* jshint ignore:start */ -if(typeof web3 === 'undefined') { - web3 = require('web3'); - BigNumber = require('bignumber.js'); + +// Browser environment +if(typeof window !== 'undefined') { + web3 = (typeof window.web3 !== 'undefined') ? window.web3 : require('web3'); + BigNumber = (typeof window.BigNumber !== 'undefined') ? window.BigNumber : require('bignumber.js'); +} + + +// Node environment +if(typeof global !== 'undefined') { + web3 = (typeof global.web3 !== 'undefined') ? global.web3 : require('web3'); + BigNumber = (typeof global.BigNumber !== 'undefined') ? global.BigNumber : require('bignumber.js'); } /* jshint ignore:end */ \ No newline at end of file diff --git a/libjsqrc/ethereumjs/package.js b/libjsqrc/ethereumjs/package.js index 66c3ddb5d..e46e9cbc6 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.6.0', + version: '0.7.1', 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. @@ -14,7 +14,7 @@ Package.onUse(function(api) { // api.use('3stack:bignumber@2.0.0', 'client'); - api.export(['web3', 'BigNumber'], 'client'); + api.export(['web3', 'BigNumber'], ['client', 'server']); api.addFiles('dist/web3.js', 'client'); api.addFiles('package-init.js', 'client'); diff --git a/libjsqrc/ethereumjs/package.json b/libjsqrc/ethereumjs/package.json index f051c61cd..52b1be15d 100644 --- a/libjsqrc/ethereumjs/package.json +++ b/libjsqrc/ethereumjs/package.json @@ -1,7 +1,7 @@ { "name": "web3", "namespace": "ethereum", - "version": "0.6.0", + "version": "0.7.1", "description": "Ethereum JavaScript API, middleware to talk to a ethereum node over RPC", "main": "./index.js", "directories": { @@ -16,37 +16,30 @@ "xmlhttprequest": "./lib/utils/browser-xhr.js" }, "devDependencies": { - "bower": ">=1.3.0", + "bower": ">=1.4.1", "browserify": ">=10.0", - "chai": "^2.1.1", + "chai": "^3.0.0", "coveralls": "^2.11.2", - "del": ">=0.1.1", + "del": ">=1.2.0", "exorcist": "^0.4.0", - "gulp": ">=3.4.0", + "gulp": ">=3.9.0", "gulp-jshint": ">=1.5.0", "gulp-rename": ">=1.2.0", "gulp-replace": "^0.5.3", "gulp-streamify": "0.0.5", - "gulp-uglify": ">=1.0.0", + "gulp-uglify": ">=1.2.0", "istanbul": "^0.3.5", "jshint": ">=2.5.0", - "karma": "^0.12.31", - "karma-browserify": "^4.0.0", - "karma-chrome-launcher": "^0.1.7", - "karma-firefox-launcher": "^0.1.4", - "karma-mocha": "^0.1.10", - "karma-safari-launcher": "^0.1.1", "mocha": ">=2.1.0", - "sandboxed-module": "^2.0.0", - "vinyl-source-stream": "^1.0.0" + "sandboxed-module": "^2.0.2", + "vinyl-source-stream": "^1.1.0" }, "scripts": { "build": "gulp", "watch": "gulp watch", "lint": "jshint *.js lib", "test": "mocha", - "test-coveralls": "istanbul cover _mocha -- -R spec && cat coverage/lcov.info | coveralls --verbose", - "karma": "./node_modules/karma/bin/karma start --singleRun=true --browsers=\"Firefox\"" + "test-coveralls": "istanbul cover _mocha -- -R spec && cat coverage/lcov.info | coveralls --verbose" }, "repository": { "type": "git", diff --git a/libjsqrc/ethereumjs/test/batch.js b/libjsqrc/ethereumjs/test/batch.js index f368a5d74..5a06f0e7b 100644 --- a/libjsqrc/ethereumjs/test/batch.js +++ b/libjsqrc/ethereumjs/test/batch.js @@ -28,6 +28,16 @@ describe('lib/web3/batch', function () { done(); }; + provider.injectValidation(function (payload) { + var first = payload[0]; + var second = payload[1]; + + assert.equal(first.method, 'eth_getBalance'); + assert.deepEqual(first.params, ['0x0000000000000000000000000000000000000000', 'latest']); + assert.equal(second.method, 'eth_getBalance'); + assert.deepEqual(second.params, ['0x0000000000000000000000000000000000000005', 'latest']); + }); + var batch = web3.createBatch(); batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000000', 'latest', callback)); batch.add(web3.eth.getBalance.request('0x0000000000000000000000000000000000000005', 'latest', callback2)); @@ -55,7 +65,7 @@ describe('lib/web3/batch', function () { }]; - var address = '0x0000000000000000000000000000000000000000'; + var address = '0x1000000000000000000000000000000000000001'; var result = '0x126'; var result2 = '0x0000000000000000000000000000000000000000000000000000000000000123'; @@ -71,6 +81,19 @@ describe('lib/web3/batch', function () { done(); }; + provider.injectValidation(function (payload) { + var first = payload[0]; + var second = payload[1]; + + assert.equal(first.method, 'eth_getBalance'); + assert.deepEqual(first.params, ['0x0000000000000000000000000000000000000000', 'latest']); + assert.equal(second.method, 'eth_call'); + assert.deepEqual(second.params, [{ + 'to': '0x1000000000000000000000000000000000000001', + 'data': '0xe3d670d70000000000000000000000001000000000000000000000000000000000000001' + }]); + }); + 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)); diff --git a/libjsqrc/ethereumjs/test/coder.decodeParam.js b/libjsqrc/ethereumjs/test/coder.decodeParam.js index 959e96cf2..5555b7800 100644 --- a/libjsqrc/ethereumjs/test/coder.decodeParam.js +++ b/libjsqrc/ethereumjs/test/coder.decodeParam.js @@ -20,10 +20,53 @@ describe('lib/solidity/coder', function () { test({ type: 'int256', expected: new bn(1), value: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ type: 'int256', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int256', expected: new bn(-1), value: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); - test({ type: 'bytes32', expected: 'gavofyork', value: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'bytes', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000020' + + test({ type: 'int8', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); + test({ type: 'int32', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); + test({ type: 'int64', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); + test({ type: 'int128', expected: new bn(16), value: '0000000000000000000000000000000000000000000000000000000000000010'}); + test({ type: 'bytes32', expected: '0x6761766f66796f726b0000000000000000000000000000000000000000000000', + value: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ type: 'bytes', expected: '0x6761766f66796f726b', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ type: 'bytes32', expected: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + value: '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'bytes', expected: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000020' + + '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'bytes', expected: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'bytes', expected: '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000060' + + '131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'string', expected: 'gavofyork', value: '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ type: 'string', expected: '\xc3\xa4\x00\x00\xc3\xa4', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000006' + + 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); + test({ type: 'string', expected: '\xc3', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + + 'c300000000000000000000000000000000000000000000000000000000000000'}); + test({ type: 'bytes', expected: '0xc3a40000c3a4', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000006' + + 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); + test({ type: 'bytes32', expected: '0xc3a40000c3a40000000000000000000000000000000000000000000000000000', + value: 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); test({ type: 'int[]', expected: [], value: '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000000'}); test({ type: 'int[]', expected: [new bn(3)], value: '0000000000000000000000000000000000000000000000000000000000000020' + @@ -49,6 +92,11 @@ describe('lib/solidity/coder', function () { test({ type: 'ureal', expected: new bn(8.5), value: '0000000000000000000000000000000880000000000000000000000000000000'}); test({ type: 'address', expected: '0x407d73d8a49eeb85d32cf465507dd71d507100c1', value: '000000000000000000000000407d73d8a49eeb85d32cf465507dd71d507100c1'}); + test({ type: 'string', expected: 'welcome to ethereum. welcome to ethereum. welcome to ethereum.', + value: '0000000000000000000000000000000000000000000000000000000000000020' + + '000000000000000000000000000000000000000000000000000000000000003e' + + '77656c636f6d6520746f20657468657265756d2e2077656c636f6d6520746f20' + + '657468657265756d2e2077656c636f6d6520746f20657468657265756d2e0000'}); }); }); @@ -62,26 +110,44 @@ describe('lib/solidity/coder', function () { test({ types: ['int'], expected: [new bn(1)], values: '0000000000000000000000000000000000000000000000000000000000000001'}); - test({ types: ['bytes32', 'int'], expected: ['gavofyork', new bn(5)], + test({ types: ['bytes32', 'int'], expected: ['0x6761766f66796f726b0000000000000000000000000000000000000000000000', new bn(5)], values: '6761766f66796f726b0000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000005'}); - test({ types: ['int', 'bytes32'], expected: [new bn(5), 'gavofyork'], + test({ types: ['int', 'bytes32'], expected: [new bn(5), '0x6761766f66796f726b0000000000000000000000000000000000000000000000'], values: '0000000000000000000000000000000000000000000000000000000000000005' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], expected: [new bn(1), 'gavofyork', new bn(2), new bn(3), new bn(4), + test({ types: ['int', 'string', 'int', 'int', 'int', 'int[]'], expected: [new bn(1), 'gavofyork', new bn(2), new bn(3), new bn(4), [new bn(5), new bn(6), new bn(7)]], values: '0000000000000000000000000000000000000000000000000000000000000001' + - '00000000000000000000000000000000000000000000000000000000000000c0' + - '0000000000000000000000000000000000000000000000000000000000000002' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000004' + - '0000000000000000000000000000000000000000000000000000000000000100' + - '0000000000000000000000000000000000000000000000000000000000000009' + - '6761766f66796f726b0000000000000000000000000000000000000000000000' + - '0000000000000000000000000000000000000000000000000000000000000003' + - '0000000000000000000000000000000000000000000000000000000000000005' + - '0000000000000000000000000000000000000000000000000000000000000006' + - '0000000000000000000000000000000000000000000000000000000000000007'}); + '00000000000000000000000000000000000000000000000000000000000000c0' + + '0000000000000000000000000000000000000000000000000000000000000002' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000004' + + '0000000000000000000000000000000000000000000000000000000000000100' + + '0000000000000000000000000000000000000000000000000000000000000009' + + '6761766f66796f726b0000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000006' + + '0000000000000000000000000000000000000000000000000000000000000007'}); + test({ types: ['int', 'bytes', 'int', 'bytes'], expected: [ + new bn(5), + '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + new bn(3), + '0x331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + ], + values: '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000080' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '00000000000000000000000000000000000000000000000000000000000000e0' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); }); }); diff --git a/libjsqrc/ethereumjs/test/coder.encodeParam.js b/libjsqrc/ethereumjs/test/coder.encodeParam.js index 55ff657c2..71ae7804e 100644 --- a/libjsqrc/ethereumjs/test/coder.encodeParam.js +++ b/libjsqrc/ethereumjs/test/coder.encodeParam.js @@ -20,10 +20,37 @@ describe('lib/solidity/coder', function () { test({ type: 'int256', value: 1, expected: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ type: 'int256', value: 16, expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ type: 'int256', value: -1, expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); - test({ type: 'bytes32', value: 'gavofyork', expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ type: 'bytes', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000020' + + test({ type: 'bytes32', value: '0x6761766f66796f726b', + expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ type: 'bytes32', value: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + expected: '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'bytes32', value: '0x02838654a83c213dae3698391eabbd54a5b6e1fb3452bc7fa4ea0dd5c8ce7e29', + expected: '02838654a83c213dae3698391eabbd54a5b6e1fb3452bc7fa4ea0dd5c8ce7e29'}); + test({ type: 'bytes', value: '0x6761766f66796f726b', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ type: 'bytes', value: '0x731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000020' + + '731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'string', value: 'gavofyork', expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000009' + + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ type: 'bytes', value: '0xc3a40000c3a4', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000006' + + 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); + test({ type: 'bytes32', value: '0xc3a40000c3a4', + expected: 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); + test({ type: 'string', value: '\xc3\xa4\x00\x00\xc3\xa4', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000006' + + 'c3a40000c3a40000000000000000000000000000000000000000000000000000'}); + test({ type: 'string', value: '\xc3', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000001' + + 'c300000000000000000000000000000000000000000000000000000000000000'}); test({ type: 'int[]', value: [], expected: '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000000'}); test({ type: 'int[]', value: [3], expected: '0000000000000000000000000000000000000000000000000000000000000020' + @@ -48,6 +75,25 @@ describe('lib/solidity/coder', function () { test({ type: 'ureal', value: 1, expected: '0000000000000000000000000000000100000000000000000000000000000000'}); test({ type: 'ureal', value: 2.125, expected: '0000000000000000000000000000000220000000000000000000000000000000'}); test({ type: 'ureal', value: 8.5, expected: '0000000000000000000000000000000880000000000000000000000000000000'}); + test({ type: 'bytes', value: '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'bytes', value: '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '0000000000000000000000000000000000000000000000000000000000000060' + + '131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); + test({ type: 'string', value: 'welcome to ethereum. welcome to ethereum. welcome to ethereum.', + expected: '0000000000000000000000000000000000000000000000000000000000000020' + + '000000000000000000000000000000000000000000000000000000000000003e' + + '77656c636f6d6520746f20657468657265756d2e2077656c636f6d6520746f20' + + '657468657265756d2e2077656c636f6d6520746f20657468657265756d2e0000'}); }); }); @@ -67,8 +113,9 @@ describe('lib/solidity/coder', function () { test({ types: ['int256'], values: [1], expected: '0000000000000000000000000000000000000000000000000000000000000001'}); test({ types: ['int256'], values: [16], expected: '0000000000000000000000000000000000000000000000000000000000000010'}); test({ types: ['int256'], values: [-1], expected: 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}); - test({ types: ['bytes32'], values: ['gavofyork'], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['bytes'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000020' + + test({ types: ['bytes32'], values: ['0x6761766f66796f726b'], + expected: '6761766f66796f726b0000000000000000000000000000000000000000000000'}); + test({ types: ['string'], values: ['gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000020' + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); test({ types: ['int[]'], values: [[3]], expected: '0000000000000000000000000000000000000000000000000000000000000020' + @@ -91,18 +138,18 @@ describe('lib/solidity/coder', function () { '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003' + '0000000000000000000000000000000000000000000000000000000000000004'}); - test({ types: ['bytes32', 'int'], values: ['gavofyork', 5], + test({ types: ['bytes32', 'int'], values: ['0x6761766f66796f726b', 5], expected: '6761766f66796f726b0000000000000000000000000000000000000000000000' + '0000000000000000000000000000000000000000000000000000000000000005'}); - test({ types: ['int', 'bytes32'], values: [5, 'gavofyork'], + test({ types: ['int', 'bytes32'], values: [5, '0x6761766f66796f726b'], expected: '0000000000000000000000000000000000000000000000000000000000000005' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['bytes', 'int'], values: ['gavofyork', 5], + test({ types: ['string', 'int'], values: ['gavofyork', 5], expected: '0000000000000000000000000000000000000000000000000000000000000040' + '0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['bytes', 'bool', 'int[]'], values: ['gavofyork', true, [1, 2, 3]], + test({ types: ['string', 'bool', 'int[]'], values: ['gavofyork', true, [1, 2, 3]], expected: '0000000000000000000000000000000000000000000000000000000000000060' + '0000000000000000000000000000000000000000000000000000000000000001' + '00000000000000000000000000000000000000000000000000000000000000a0' + @@ -112,7 +159,7 @@ describe('lib/solidity/coder', function () { '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ types: ['bytes', 'int[]'], values: ['gavofyork', [1, 2, 3]], + test({ types: ['string', 'int[]'], values: ['gavofyork', [1, 2, 3]], expected: '0000000000000000000000000000000000000000000000000000000000000040' + '0000000000000000000000000000000000000000000000000000000000000080' + '0000000000000000000000000000000000000000000000000000000000000009' + @@ -121,12 +168,12 @@ describe('lib/solidity/coder', function () { '0000000000000000000000000000000000000000000000000000000000000001' + '0000000000000000000000000000000000000000000000000000000000000002' + '0000000000000000000000000000000000000000000000000000000000000003'}); - test({ types: ['int', 'bytes'], values: [5, 'gavofyork'], + test({ types: ['int', 'string'], values: [5, 'gavofyork'], expected: '0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000040' + '0000000000000000000000000000000000000000000000000000000000000009' + '6761766f66796f726b0000000000000000000000000000000000000000000000'}); - test({ types: ['int', 'bytes', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]], + test({ types: ['int', 'string', 'int', 'int', 'int', 'int[]'], values: [1, 'gavofyork', 2, 3, 4, [5, 6, 7]], expected: '0000000000000000000000000000000000000000000000000000000000000001' + '00000000000000000000000000000000000000000000000000000000000000c0' + '0000000000000000000000000000000000000000000000000000000000000002' + @@ -139,6 +186,24 @@ describe('lib/solidity/coder', function () { '0000000000000000000000000000000000000000000000000000000000000005' + '0000000000000000000000000000000000000000000000000000000000000006' + '0000000000000000000000000000000000000000000000000000000000000007'}); + test({ types: ['int', 'bytes', 'int', 'bytes'], values: [ + 5, + '0x131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + 3, + '0x331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b', + ], + expected: '0000000000000000000000000000000000000000000000000000000000000005' + + '0000000000000000000000000000000000000000000000000000000000000080' + + '0000000000000000000000000000000000000000000000000000000000000003' + + '00000000000000000000000000000000000000000000000000000000000000e0' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '231a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '0000000000000000000000000000000000000000000000000000000000000040' + + '331a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b' + + '431a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b'}); }); }); diff --git a/libjsqrc/ethereumjs/test/contract.js b/libjsqrc/ethereumjs/test/contract.js index 2632575f5..71ac20701 100644 --- a/libjsqrc/ethereumjs/test/contract.js +++ b/libjsqrc/ethereumjs/test/contract.js @@ -127,6 +127,147 @@ describe('web3.eth.contract', function () { }); }); + it('should create event filter and watch immediately', function (done) { + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + web3.reset(); // reset different polls + var signature = 'Changed(address,uint256,uint256,uint256)'; + var step = 0; + provider.injectValidation(function (payload) { + if (step === 0) { + step = 1; + provider.injectResult('0x3'); + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, 'eth_newFilter'); + assert.deepEqual(payload.params[0], { + topics: [ + '0x' + sha3(signature), + '0x0000000000000000000000001234567890123456789012345678901234567890', + null + ], + address: '0x1234567890123456789012345678901234567890' + }); + } else if (step === 1) { + step = 2; + provider.injectResult([{ + address: address, + topics: [ + '0x' + sha3(signature), + '0x0000000000000000000000001234567890123456789012345678901234567890', + '0x0000000000000000000000000000000000000000000000000000000000000001' + ], + number: 2, + data: '0x0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000008' + }]); + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, 'eth_getFilterLogs'); + } else if (step === 2 && utils.isArray(payload)) { + provider.injectBatchResults([[{ + address: address, + topics: [ + '0x' + sha3(signature), + '0x0000000000000000000000001234567890123456789012345678901234567890', + '0x0000000000000000000000000000000000000000000000000000000000000001' + ], + number: 2, + data: '0x0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000008' + }]]); + var r = payload.filter(function (p) { + return p.jsonrpc === '2.0' && p.method === 'eth_getFilterChanges' && p.params[0] === '0x3'; + }); + assert.equal(r.length > 0, true); + } + }); + + var contract = web3.eth.contract(desc).at(address); + + var res = 0; + var event = contract.Changed({from: address}, function(err, result) { + assert.equal(result.args.from, address); + assert.equal(result.args.amount, 1); + assert.equal(result.args.t1, 1); + assert.equal(result.args.t2, 8); + res++; + if (res === 2) { + done(); + } + }); + }); + + it('should create all event filter', function (done) { + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + web3.reset(); // reset different polls + var signature = 'Changed(address,uint256,uint256,uint256)'; + var step = 0; + provider.injectValidation(function (payload) { + if (step === 0) { + step = 1; + provider.injectResult('0x3'); + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, 'eth_newFilter'); + assert.deepEqual(payload.params[0], { + topics: [ + null, + null, + null, + null, + null + ], + address: '0x1234567890123456789012345678901234567890' + }); + } else if (step === 1) { + step = 2; + provider.injectResult([{ + address: address, + topics: [ + '0x' + sha3(signature), + '0x0000000000000000000000001234567890123456789012345678901234567890', + '0x0000000000000000000000000000000000000000000000000000000000000001' + ], + number: 2, + data: '0x0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000008' + }]); + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, 'eth_getFilterLogs'); + } else if (step === 2 && utils.isArray(payload)) { + provider.injectBatchResults([[{ + address: address, + topics: [ + '0x' + sha3(signature), + '0x0000000000000000000000001234567890123456789012345678901234567890', + '0x0000000000000000000000000000000000000000000000000000000000000001' + ], + number: 2, + data: '0x0000000000000000000000000000000000000000000000000000000000000001' + + '0000000000000000000000000000000000000000000000000000000000000008' + }]]); + var r = payload.filter(function (p) { + return p.jsonrpc === '2.0' && p.method === 'eth_getFilterChanges' && p.params[0] === '0x3'; + }); + assert.equal(r.length > 0, true); + } + }); + + var contract = web3.eth.contract(desc).at(address); + + var res = 0; + var event = contract.allEvents(); + event.watch(function(err, result) { + assert.equal(result.args.from, address); + assert.equal(result.args.amount, 1); + assert.equal(result.args.t1, 1); + assert.equal(result.args.t2, 8); + res++; + if (res === 2) { + done(); + } + }); + }); + it('should call constant function', function () { var provider = new FakeHttpProvider(); web3.setProvider(provider); diff --git a/libjsqrc/ethereumjs/test/polling.js b/libjsqrc/ethereumjs/test/polling.js index 8bd2b041c..88cfee4cc 100644 --- a/libjsqrc/ethereumjs/test/polling.js +++ b/libjsqrc/ethereumjs/test/polling.js @@ -63,6 +63,42 @@ var testPolling = function (tests) { var filter = web3[test.protocol].filter.apply(null, test.args); provider.injectBatchResults([test.secondResult]); filter.watch(function (err, result) { + console.log(err, result); + + if (test.err) { + // todo + } else { + assert.equal(result, test.secondResult[0]); + } + done(); + + }); + }); + it('should create && successfully poll filter when passed as callback', function (done) { + + // given + var provider = new FakeHttpProvider(); + web3.setProvider(provider); + web3.reset(); + provider.injectResult(test.firstResult); + var step = 0; + provider.injectValidation(function (payload) { + if (step === 0) { + step = 1; + assert.equal(payload.jsonrpc, '2.0'); + assert.equal(payload.method, test.firstPayload.method); + assert.deepEqual(payload.params, test.firstPayload.params); + } else if (step === 1 && utils.isArray(payload)) { + var r = payload.filter(function (p) { + return p.jsonrpc === '2.0' && p.method === test.secondPayload.method && p.params[0] === test.firstResult; + }); + assert.equal(r.length > 0, true); + } + + }); + + // add callback + test.args.push(function (err, result) { if (test.err) { // todo } else { @@ -71,6 +107,10 @@ var testPolling = function (tests) { done(); }); + + // when + var filter = web3[test.protocol].filter.apply(null, test.args); + provider.injectBatchResults([test.secondResult]); }); }); }); diff --git a/libjsqrc/ethereumjs/test/utils.toHex.js b/libjsqrc/ethereumjs/test/utils.toHex.js index 0a328e345..fdf88cd38 100644 --- a/libjsqrc/ethereumjs/test/utils.toHex.js +++ b/libjsqrc/ethereumjs/test/utils.toHex.js @@ -14,6 +14,7 @@ var tests = [ { value: '-0x1', expected: '-0x1'}, { value: '-15', expected: '-0xf'}, { value: '-0xf', expected: '-0xf'}, + { value: '0x657468657265756d', expected: '0x657468657265756d'}, { value: '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd', expected: '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd'}, { value: '-0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', expected: '-0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'}, { value: '-0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd', expected: '-0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd'}, diff --git a/libjsqrc/ethereumjs/test/web3.eth.filter.methods.js b/libjsqrc/ethereumjs/test/web3.eth.filter.methods.js index f40f3d0ac..c15d720e2 100644 --- a/libjsqrc/ethereumjs/test/web3.eth.filter.methods.js +++ b/libjsqrc/ethereumjs/test/web3.eth.filter.methods.js @@ -14,10 +14,10 @@ var implementation = { describe('web3.eth.filter', function () { describe('methods', function () { - //var f = filter({}, implementation); + // var f = filter({}, implementation); - //u.methodExists(f, 'watch'); - //u.methodExists(f, 'stopWatching'); - //u.methodExists(f, 'get'); + // u.methodExists(f, 'watch'); + // u.methodExists(f, 'stopWatching'); + // u.methodExists(f, 'get'); }); }); diff --git a/libp2p/Common.h b/libp2p/Common.h index 445ba0cca..c124115f9 100644 --- a/libp2p/Common.h +++ b/libp2p/Common.h @@ -236,7 +236,7 @@ template <> struct hash return boost::hash_range(range.begin(), range.end()); } if (_a.is_unspecified()) - return static_cast(0x3487194039229152ul); // Chosen by fair dice roll, guaranteed to be random + return static_cast(0x3487194039229152ull); // Chosen by fair dice roll, guaranteed to be random return std::hash()(_a.to_string()); } }; diff --git a/libp2p/Host.h b/libp2p/Host.h index 9523d0cca..17e98f8f6 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -33,7 +33,6 @@ #include #include -#include #include #include #include "NodeTable.h" @@ -203,6 +202,9 @@ public: /// Validates and starts peer session, taking ownership of _io. Disconnects and returns false upon error. void startPeerSession(Public const& _id, RLP const& _hello, RLPXFrameCoder* _io, std::shared_ptr const& _s); + /// Get session by id + std::shared_ptr peerSession(NodeId const& _id) { RecursiveGuard l(x_sessions); return m_sessions.count(_id) ? m_sessions[_id].lock() : std::shared_ptr(); } + protected: void onNodeTableEvent(NodeId const& _n, NodeTableEventType const& _e); @@ -212,8 +214,8 @@ protected: private: enum PeerSlotRatio { Egress = 2, Ingress = 9 }; - bool havePeerSession(NodeId _id) { RecursiveGuard l(x_sessions); return m_sessions.count(_id) ? !!m_sessions[_id].lock() : false; } - + bool havePeerSession(NodeId const& _id) { return !!peerSession(_id); } + /// Determines and sets m_tcpPublic to publicly advertised address. void determinePublic(); diff --git a/libp2p/RLPXSocket.h b/libp2p/RLPXSocket.h index 389418c76..58613bf82 100644 --- a/libp2p/RLPXSocket.h +++ b/libp2p/RLPXSocket.h @@ -45,7 +45,7 @@ public: bool isConnected() const { return m_socket.is_open(); } void close() { try { boost::system::error_code ec; m_socket.shutdown(bi::tcp::socket::shutdown_both, ec); if (m_socket.is_open()) m_socket.close(); } catch (...){} } - bi::tcp::endpoint remoteEndpoint() { try { return m_socket.remote_endpoint(); } catch (...){ return bi::tcp::endpoint(); } } + bi::tcp::endpoint remoteEndpoint() { boost::system::error_code ec; return m_socket.remote_endpoint(ec); } bi::tcp::socket& ref() { return m_socket; } protected: @@ -53,4 +53,4 @@ protected: }; } -} \ No newline at end of file +} diff --git a/libp2p/Session.cpp b/libp2p/Session.cpp index 6827a27d9..9a981786d 100644 --- a/libp2p/Session.cpp +++ b/libp2p/Session.cpp @@ -256,9 +256,8 @@ bool Session::checkPacket(bytesConstRef _msg) void Session::send(bytes&& _msg) { - clog(NetLeft) << RLP(bytesConstRef(&_msg).cropped(1)); - bytesConstRef msg(&_msg); + clog(NetLeft) << RLP(msg.cropped(1)); if (!checkPacket(msg)) clog(NetWarn) << "INVALID PACKET CONSTRUCTED!"; @@ -268,7 +267,7 @@ void Session::send(bytes&& _msg) bool doWrite = false; { Guard l(x_writeQueue); - m_writeQueue.push_back(_msg); + m_writeQueue.push_back(std::move(_msg)); doWrite = (m_writeQueue.size() == 1); } @@ -334,11 +333,12 @@ void Session::drop(DisconnectReason _reason) void Session::disconnect(DisconnectReason _reason) { clog(NetConnect) << "Disconnecting (our reason:" << reasonOf(_reason) << ")"; + size_t peerCount = m_server->peerCount(); //needs to be outside of lock to avoid deadlocking with other thread that capture x_info/x_sessions in reverse order DEV_GUARDED(x_info) StructuredLogger::p2pDisconnected( m_info.id.abridged(), m_peer->endpoint, // TODO: may not be 100% accurate - m_server->peerCount() + peerCount ); if (m_socket->ref().is_open()) { @@ -382,11 +382,11 @@ void Session::doRead() } catch (std::exception const& _e) { - clog(NetWarn) << "Exception decoding frame header RLP:" << bytesConstRef(m_data.data(), h128::size).cropped(3); + clog(NetWarn) << "Exception decoding frame header RLP:" << _e.what() << bytesConstRef(m_data.data(), h128::size).cropped(3); drop(BadProtocol); return; } - + /// read padded frame and mac auto tlen = header.length + header.padding + h128::size; ba::async_read(m_socket->ref(), boost::asio::buffer(m_data, tlen), [this, self, header, tlen](boost::system::error_code ec, std::size_t length) diff --git a/libp2p/Session.h b/libp2p/Session.h index 0a55b2653..8d8c3ea1e 100644 --- a/libp2p/Session.h +++ b/libp2p/Session.h @@ -31,7 +31,6 @@ #include #include -#include #include #include "RLPXFrameCoder.h" #include "RLPXSocket.h" diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index fac4360f1..161a7d35a 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -802,12 +802,11 @@ void FunctionCall::checkTypeRequirements(TypePointers const*) m_expression->checkTypeRequirements(isPositionalCall ? &argumentTypes : nullptr); - Type const* expressionType = m_expression->getType().get(); + TypePointer const& expressionType = m_expression->getType(); + FunctionTypePointer functionType; if (isTypeConversion()) { TypeType const& type = dynamic_cast(*expressionType); - //@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("Exactly one argument expected for explicit type conversion.")); if (!isPositionalCall) @@ -815,87 +814,106 @@ void FunctionCall::checkTypeRequirements(TypePointers const*) if (!m_arguments.front()->getType()->isExplicitlyConvertibleTo(*type.getActualType())) BOOST_THROW_EXCEPTION(createTypeError("Explicit type conversion not allowed.")); m_type = type.getActualType(); + return; } - else if (FunctionType const* functionType = dynamic_cast(expressionType)) + + if (isStructConstructorCall()) { - //@todo would be nice to create a struct type from the arguments - // and then ask if that is implicitly convertible to the struct represented by the - // function parameters - TypePointers const& parameterTypes = functionType->getParameterTypes(); - if (!functionType->takesArbitraryParameters() && parameterTypes.size() != m_arguments.size()) - BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for function call.")); + TypeType const& type = dynamic_cast(*expressionType); + auto const& structType = dynamic_cast(*type.getActualType()); + functionType = structType.constructorType(); + } + else + functionType = dynamic_pointer_cast(expressionType); - if (isPositionalCall) - { - // call by positional arguments - for (size_t i = 0; i < m_arguments.size(); ++i) - if ( - !functionType->takesArbitraryParameters() && - !m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]) - ) - BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( - "Invalid type for argument in function call. " - "Invalid implicit conversion from " + - m_arguments[i]->getType()->toString() + - " to " + - parameterTypes[i]->toString() + - " requested." - )); - } - else - { - // call by named arguments - if (functionType->takesArbitraryParameters()) - BOOST_THROW_EXCEPTION(createTypeError("Named arguments cannnot be used for functions " - "that take arbitrary parameters.")); - auto const& parameterNames = functionType->getParameterNames(); - if (parameterNames.size() != m_names.size()) - BOOST_THROW_EXCEPTION(createTypeError("Some argument names are missing.")); - - // check duplicate names - for (size_t i = 0; i < m_names.size(); i++) - for (size_t j = i + 1; j < m_names.size(); j++) - if (*m_names[i] == *m_names[j]) - BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError("Duplicate named argument.")); - - for (size_t i = 0; i < m_names.size(); i++) { - bool found = false; - for (size_t j = 0; j < parameterNames.size(); j++) { - if (parameterNames[j] == *m_names[i]) { - // check type convertible - if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[j])) - BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( - "Invalid type for argument in function call. " - "Invalid implicit conversion from " + - m_arguments[i]->getType()->toString() + - " to " + - parameterTypes[i]->toString() + - " requested." - )); - - found = true; - break; - } + if (!functionType) + BOOST_THROW_EXCEPTION(createTypeError("Type is not callable.")); + + //@todo would be nice to create a struct type from the arguments + // and then ask if that is implicitly convertible to the struct represented by the + // function parameters + TypePointers const& parameterTypes = functionType->getParameterTypes(); + if (!functionType->takesArbitraryParameters() && parameterTypes.size() != m_arguments.size()) + BOOST_THROW_EXCEPTION(createTypeError("Wrong argument count for function call.")); + + if (isPositionalCall) + { + // call by positional arguments + for (size_t i = 0; i < m_arguments.size(); ++i) + if ( + !functionType->takesArbitraryParameters() && + !m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[i]) + ) + BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( + "Invalid type for argument in function call. " + "Invalid implicit conversion from " + + m_arguments[i]->getType()->toString() + + " to " + + parameterTypes[i]->toString() + + " requested." + )); + } + else + { + // call by named arguments + if (functionType->takesArbitraryParameters()) + BOOST_THROW_EXCEPTION(createTypeError( + "Named arguments cannnot be used for functions that take arbitrary parameters." + )); + auto const& parameterNames = functionType->getParameterNames(); + if (parameterNames.size() != m_names.size()) + BOOST_THROW_EXCEPTION(createTypeError("Some argument names are missing.")); + + // check duplicate names + for (size_t i = 0; i < m_names.size(); i++) + for (size_t j = i + 1; j < m_names.size(); j++) + if (*m_names[i] == *m_names[j]) + BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError("Duplicate named argument.")); + + for (size_t i = 0; i < m_names.size(); i++) { + bool found = false; + for (size_t j = 0; j < parameterNames.size(); j++) { + if (parameterNames[j] == *m_names[i]) { + // check type convertible + if (!m_arguments[i]->getType()->isImplicitlyConvertibleTo(*parameterTypes[j])) + BOOST_THROW_EXCEPTION(m_arguments[i]->createTypeError( + "Invalid type for argument in function call. " + "Invalid implicit conversion from " + + m_arguments[i]->getType()->toString() + + " to " + + parameterTypes[i]->toString() + + " requested." + )); + + found = true; + break; } - if (!found) - BOOST_THROW_EXCEPTION(createTypeError("Named argument does not match function declaration.")); } + if (!found) + BOOST_THROW_EXCEPTION(createTypeError("Named argument does not match function declaration.")); } - - // @todo actually the return type should be an anonymous struct, - // but we change it to the type of the first return value until we have structs - if (functionType->getReturnParameterTypes().empty()) - m_type = make_shared(); - else - m_type = functionType->getReturnParameterTypes().front(); } + + // @todo actually the return type should be an anonymous struct, + // but we change it to the type of the first return value until we have anonymous + // structs and tuples + if (functionType->getReturnParameterTypes().empty()) + m_type = make_shared(); else - BOOST_THROW_EXCEPTION(createTypeError("Type is not callable.")); + m_type = functionType->getReturnParameterTypes().front(); } bool FunctionCall::isTypeConversion() const { - return m_expression->getType()->getCategory() == Type::Category::TypeType; + return m_expression->getType()->getCategory() == Type::Category::TypeType && !isStructConstructorCall(); +} + +bool FunctionCall::isStructConstructorCall() const +{ + if (auto const* type = dynamic_cast(m_expression->getType().get())) + return type->getActualType()->getCategory() == Type::Category::Struct; + else + return false; } void NewExpression::checkTypeRequirements(TypePointers const*) diff --git a/libsolidity/AST.h b/libsolidity/AST.h index ff0d708f5..658b3de9f 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -1136,9 +1136,11 @@ public: std::vector> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; } std::vector> const& getNames() const { return m_names; } - /// Returns true if this is not an actual function call, but an explicit type conversion - /// or constructor call. + /// @returns true if this is not an actual function call, but an explicit type conversion. + /// Returns false for struct constructor calls. bool isTypeConversion() const; + /// @return true if this is a constructor call for a struct, i.e. StructName(...). + bool isStructConstructorCall() const; private: ASTPointer m_expression; diff --git a/libsolidity/CompilerUtils.cpp b/libsolidity/CompilerUtils.cpp index 208d7cecc..297e6aa09 100644 --- a/libsolidity/CompilerUtils.cpp +++ b/libsolidity/CompilerUtils.cpp @@ -113,6 +113,16 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound solAssert(ref->location() == DataLocation::Memory, ""); storeInMemoryDynamic(IntegerType(256), _padToWordBoundaries); } + else if (auto str = dynamic_cast(&_type)) + { + m_context << eth::Instruction::DUP1; + storeStringData(bytesConstRef(str->value())); + if (_padToWordBoundaries) + m_context << u256(((str->value().size() + 31) / 32) * 32); + else + m_context << u256(str->value().size()); + m_context << eth::Instruction::ADD; + } else { unsigned numBytes = prepareMemoryStore(_type, _padToWordBoundaries); @@ -169,7 +179,8 @@ void CompilerUtils::encodeToMemory( TypePointer type = targetType; if ( _givenTypes[i]->dataStoredIn(DataLocation::Storage) || - _givenTypes[i]->dataStoredIn(DataLocation::CallData) + _givenTypes[i]->dataStoredIn(DataLocation::CallData) || + _givenTypes[i]->getCategory() == Type::Category::StringLiteral ) type = _givenTypes[i]; // delay conversion else @@ -192,36 +203,48 @@ void CompilerUtils::encodeToMemory( solAssert(!!targetType, "Externalable type expected."); if (targetType->isDynamicallySized() && !_copyDynamicDataInPlace) { - solAssert(_givenTypes[i]->getCategory() == Type::Category::Array, "Unknown dynamic type."); - auto const& arrayType = dynamic_cast(*_givenTypes[i]); // copy tail pointer (=mem_end - mem_start) to memory m_context << eth::dupInstruction(2 + dynPointers) << eth::Instruction::DUP2; m_context << eth::Instruction::SUB; m_context << eth::dupInstruction(2 + dynPointers - thisDynPointer); m_context << eth::Instruction::MSTORE; - // now copy the array - copyToStackTop(argSize - stackPos + dynPointers + 2, arrayType.getSizeOnStack()); - // stack: ... - // copy length to memory - m_context << eth::dupInstruction(1 + arrayType.getSizeOnStack()); - if (arrayType.location() == DataLocation::CallData) - m_context << eth::Instruction::DUP2; // length is on stack - else if (arrayType.location() == DataLocation::Storage) - m_context << eth::Instruction::DUP3 << eth::Instruction::SLOAD; + // stack: ... + if (_givenTypes[i]->getCategory() == Type::Category::StringLiteral) + { + auto const& strType = dynamic_cast(*_givenTypes[i]); + m_context << u256(strType.value().size()); + storeInMemoryDynamic(IntegerType(256), true); + // stack: ... + storeInMemoryDynamic(strType, _padToWordBoundaries); + } else { - solAssert(arrayType.location() == DataLocation::Memory, ""); - m_context << eth::Instruction::DUP2 << eth::Instruction::MLOAD; + solAssert(_givenTypes[i]->getCategory() == Type::Category::Array, "Unknown dynamic type."); + auto const& arrayType = dynamic_cast(*_givenTypes[i]); + // now copy the array + copyToStackTop(argSize - stackPos + dynPointers + 2, arrayType.getSizeOnStack()); + // stack: ... + // copy length to memory + m_context << eth::dupInstruction(1 + arrayType.getSizeOnStack()); + if (arrayType.location() == DataLocation::CallData) + m_context << eth::Instruction::DUP2; // length is on stack + else if (arrayType.location() == DataLocation::Storage) + m_context << eth::Instruction::DUP3 << eth::Instruction::SLOAD; + else + { + solAssert(arrayType.location() == DataLocation::Memory, ""); + m_context << eth::Instruction::DUP2 << eth::Instruction::MLOAD; + } + // stack: ... + storeInMemoryDynamic(IntegerType(256), true); + // stack: ... + // copy the new memory pointer + m_context << eth::swapInstruction(arrayType.getSizeOnStack() + 1) << eth::Instruction::POP; + // stack: ... + // copy data part + ArrayUtils(m_context).copyArrayToMemory(arrayType, _padToWordBoundaries); + // stack: ... } - // stack: ... - storeInMemoryDynamic(IntegerType(256), true); - // stack: ... - // copy the new memory pointer - m_context << eth::swapInstruction(arrayType.getSizeOnStack() + 1) << eth::Instruction::POP; - // stack: ... - // copy data part - ArrayUtils(m_context).copyArrayToMemory(arrayType, _padToWordBoundaries); - // stack: ... thisDynPointer++; } @@ -269,22 +292,22 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp // conversion from bytes to integer. no need to clean the high bit // only to shift right because of opposite alignment IntegerType const& targetIntegerType = dynamic_cast(_targetType); - m_context << (u256(1) << (256 - typeOnStack.getNumBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV; - if (targetIntegerType.getNumBits() < typeOnStack.getNumBytes() * 8) - convertType(IntegerType(typeOnStack.getNumBytes() * 8), _targetType, _cleanupNeeded); + m_context << (u256(1) << (256 - typeOnStack.numBytes() * 8)) << eth::Instruction::SWAP1 << eth::Instruction::DIV; + if (targetIntegerType.getNumBits() < typeOnStack.numBytes() * 8) + convertType(IntegerType(typeOnStack.numBytes() * 8), _targetType, _cleanupNeeded); } else { // clear lower-order bytes for conversion to shorter bytes - we always clean solAssert(targetTypeCategory == Type::Category::FixedBytes, "Invalid type conversion requested."); FixedBytesType const& targetType = dynamic_cast(_targetType); - if (targetType.getNumBytes() < typeOnStack.getNumBytes()) + if (targetType.numBytes() < typeOnStack.numBytes()) { - if (targetType.getNumBytes() == 0) + if (targetType.numBytes() == 0) m_context << eth::Instruction::DUP1 << eth::Instruction::XOR; else { - m_context << (u256(1) << (256 - targetType.getNumBytes() * 8)); + m_context << (u256(1) << (256 - targetType.numBytes() * 8)); m_context << eth::Instruction::DUP1 << eth::Instruction::SWAP2; m_context << eth::Instruction::DIV << eth::Instruction::MUL; } @@ -306,9 +329,9 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp // only to shift left because of opposite alignment FixedBytesType const& targetBytesType = dynamic_cast(_targetType); if (auto typeOnStack = dynamic_cast(&_typeOnStack)) - if (targetBytesType.getNumBytes() * 8 > typeOnStack->getNumBits()) + if (targetBytesType.numBytes() * 8 > typeOnStack->getNumBits()) cleanHigherOrderBits(*typeOnStack); - m_context << (u256(1) << (256 - targetBytesType.getNumBytes() * 8)) << eth::Instruction::MUL; + m_context << (u256(1) << (256 - targetBytesType.numBytes() * 8)) << eth::Instruction::MUL; } else if (targetTypeCategory == Type::Category::Enum) // just clean @@ -340,6 +363,37 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp } } break; + case Type::Category::StringLiteral: + { + auto const& literalType = dynamic_cast(_typeOnStack); + string const& value = literalType.value(); + bytesConstRef data(value); + if (targetTypeCategory == Type::Category::FixedBytes) + { + solAssert(data.size() <= 32, ""); + m_context << h256::Arith(h256(data, h256::AlignLeft)); + } + else if (targetTypeCategory == Type::Category::Array) + { + auto const& arrayType = dynamic_cast(_targetType); + solAssert(arrayType.isByteArray(), ""); + u256 storageSize(32 + ((data.size() + 31) / 32) * 32); + m_context << storageSize; + allocateMemory(); + // stack: mempos + m_context << eth::Instruction::DUP1 << u256(data.size()); + storeInMemoryDynamic(IntegerType(256)); + // stack: mempos datapos + storeStringData(data); + break; + } + else + solAssert( + false, + "Invalid conversion from string literal to " + _targetType.toString(false) + " requested." + ); + break; + } case Type::Category::Array: { solAssert(targetTypeCategory == stackTypeCategory, ""); @@ -436,19 +490,54 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp } case Type::Category::Struct: { - //@todo we can probably use some of the code for arrays here. solAssert(targetTypeCategory == stackTypeCategory, ""); auto& targetType = dynamic_cast(_targetType); - auto& stackType = dynamic_cast(_typeOnStack); + auto& typeOnStack = dynamic_cast(_typeOnStack); solAssert( - targetType.location() == DataLocation::Storage && - stackType.location() == DataLocation::Storage, - "Non-storage structs not yet implemented." - ); - solAssert( - targetType.isPointer(), - "Type conversion to non-pointer struct requested." - ); + targetType.location() != DataLocation::CallData && + typeOnStack.location() != DataLocation::CallData + , ""); + switch (targetType.location()) + { + case DataLocation::Storage: + // Other cases are done explicitly in LValue::storeValue, and only possible by assignment. + solAssert( + targetType.isPointer() && + typeOnStack.location() == DataLocation::Storage, + "Invalid conversion to storage type." + ); + break; + case DataLocation::Memory: + // Copy the array to a free position in memory, unless it is already in memory. + if (typeOnStack.location() != DataLocation::Memory) + { + solAssert(typeOnStack.location() == DataLocation::Storage, ""); + // stack: + m_context << eth::Instruction::POP; + m_context << typeOnStack.memorySize(); + allocateMemory(); + m_context << eth::Instruction::SWAP1 << eth::Instruction::DUP2; + // stack: + for (auto const& member: typeOnStack.getMembers()) + { + if (!member.type->canLiveOutsideStorage()) + continue; + pair const& offsets = typeOnStack.getStorageOffsetsOfMember(member.name); + m_context << offsets.first << eth::Instruction::DUP3 << eth::Instruction::ADD; + m_context << u256(offsets.second); + StorageItem(m_context, *member.type).retrieveValue(SourceLocation(), true); + TypePointer targetMemberType = targetType.getMemberType(member.name); + solAssert(!!targetMemberType, "Member not found in target type."); + convertType(*member.type, *targetMemberType, true); + storeInMemoryDynamic(*targetMemberType, true); + } + m_context << eth::Instruction::POP << eth::Instruction::POP; + } + break; + case DataLocation::CallData: + solAssert(false, "Invalid type conversion target location CallData."); + break; + } break; } default: @@ -571,6 +660,28 @@ void CompilerUtils::computeHashStatic() m_context << u256(32) << u256(0) << eth::Instruction::SHA3; } +void CompilerUtils::storeStringData(bytesConstRef _data) +{ + //@todo provide both alternatives to the optimiser + // stack: mempos + if (_data.size() <= 128) + { + for (unsigned i = 0; i < _data.size(); i += 32) + { + m_context << h256::Arith(h256(_data.cropped(i), h256::AlignLeft)); + storeInMemoryDynamic(IntegerType(256)); + } + m_context << eth::Instruction::POP; + } + else + { + // stack: mempos mempos_data + m_context.appendData(_data.toBytes()); + m_context << u256(_data.size()) << eth::Instruction::SWAP2; + m_context << eth::Instruction::CODECOPY; + } +} + unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries) { unsigned numBytes = _type.getCalldataEncodedSize(_padToWordBoundaries); diff --git a/libsolidity/CompilerUtils.h b/libsolidity/CompilerUtils.h index 7dd44da8f..dbb00a1de 100644 --- a/libsolidity/CompilerUtils.h +++ b/libsolidity/CompilerUtils.h @@ -148,7 +148,12 @@ private: /// Address of the precompiled identity contract. static const unsigned identityContractAddress; - //// Appends code that cleans higher-order bits for integer types. + /// Stores the given string in memory. + /// Stack pre: mempos + /// Stack post: + void storeStringData(bytesConstRef _data); + + /// Appends code that cleans higher-order bits for integer types. void cleanHigherOrderBits(IntegerType const& _typeOnStack); /// Prepares the given type for storing in memory by shifting it if necessary. diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 59907b14b..058358187 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -155,11 +155,14 @@ bool ExpressionCompiler::visit(Assignment const& _assignment) TypePointer type = _assignment.getRightHandSide().getType(); if (!_assignment.getType()->dataStoredIn(DataLocation::Storage)) { - //@todo we should delay conversion here if RHS is not in memory, LHS is a MemoryItem - // and not dynamically-sized. utils().convertType(*type, *_assignment.getType()); type = _assignment.getType(); } + else + { + utils().convertType(*type, *type->mobileType()); + type = type->mobileType(); + } _assignment.getLeftHandSide().accept(*this); solAssert(!!m_currentLValue, "LValue not retrieved."); @@ -315,38 +318,66 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) using Location = FunctionType::Location; if (_functionCall.isTypeConversion()) { - //@todo struct construction solAssert(_functionCall.getArguments().size() == 1, ""); solAssert(_functionCall.getNames().empty(), ""); Expression const& firstArgument = *_functionCall.getArguments().front(); firstArgument.accept(*this); utils().convertType(*firstArgument.getType(), *_functionCall.getType()); + return false; } + + FunctionTypePointer functionType; + if (_functionCall.isStructConstructorCall()) + { + auto const& type = dynamic_cast(*_functionCall.getExpression().getType()); + auto const& structType = dynamic_cast(*type.getActualType()); + functionType = structType.constructorType(); + } + else + functionType = dynamic_pointer_cast(_functionCall.getExpression().getType()); + + TypePointers const& parameterTypes = functionType->getParameterTypes(); + vector> const& callArguments = _functionCall.getArguments(); + vector> const& callArgumentNames = _functionCall.getNames(); + if (!functionType->takesArbitraryParameters()) + solAssert(callArguments.size() == parameterTypes.size(), ""); + + vector> arguments; + if (callArgumentNames.empty()) + // normal arguments + arguments = callArguments; else + // named arguments + for (auto const& parameterName: functionType->getParameterNames()) + { + bool found = false; + for (size_t j = 0; j < callArgumentNames.size() && !found; j++) + if ((found = (parameterName == *callArgumentNames[j]))) + // we found the actual parameter position + arguments.push_back(callArguments[j]); + solAssert(found, ""); + } + + if (_functionCall.isStructConstructorCall()) { - FunctionType const& function = dynamic_cast(*_functionCall.getExpression().getType()); - TypePointers const& parameterTypes = function.getParameterTypes(); - vector> const& callArguments = _functionCall.getArguments(); - vector> const& callArgumentNames = _functionCall.getNames(); - if (!function.takesArbitraryParameters()) - solAssert(callArguments.size() == parameterTypes.size(), ""); - - vector> arguments; - if (callArgumentNames.empty()) - // normal arguments - arguments = callArguments; - else - // named arguments - for (auto const& parameterName: function.getParameterNames()) - { - bool found = false; - for (size_t j = 0; j < callArgumentNames.size() && !found; j++) - if ((found = (parameterName == *callArgumentNames[j]))) - // we found the actual parameter position - arguments.push_back(callArguments[j]); - solAssert(found, ""); - } + TypeType const& type = dynamic_cast(*_functionCall.getExpression().getType()); + auto const& structType = dynamic_cast(*type.getActualType()); + m_context << u256(max(32u, structType.getCalldataEncodedSize(true))); + utils().allocateMemory(); + m_context << eth::Instruction::DUP1; + + for (unsigned i = 0; i < arguments.size(); ++i) + { + arguments[i]->accept(*this); + utils().convertType(*arguments[i]->getType(), *functionType->getParameterTypes()[i]); + utils().storeInMemoryDynamic(*functionType->getParameterTypes()[i]); + } + m_context << eth::Instruction::POP; + } + else + { + FunctionType const& function = *functionType; switch (function.getLocation()) { case Location::Internal: @@ -691,7 +722,8 @@ void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess) } case DataLocation::Memory: { - solAssert(false, "Member access for memory structs not yet implemented."); + m_context << type.memoryOffsetOfMember(member) << eth::Instruction::ADD; + setLValue(_memberAccess, *_memberAccess.getType()); break; } default: @@ -871,13 +903,15 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) void ExpressionCompiler::endVisit(Literal const& _literal) { CompilerContext::LocationSetter locationSetter(m_context, _literal); - switch (_literal.getType()->getCategory()) + TypePointer type = _literal.getType(); + switch (type->getCategory()) { case Type::Category::IntegerConstant: case Type::Category::Bool: - case Type::Category::FixedBytes: - m_context << _literal.getType()->literalValue(&_literal); + m_context << type->literalValue(&_literal); break; + case Type::Category::StringLiteral: + break; // will be done during conversion default: BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Only integer, boolean and string literals implemented for now.")); } diff --git a/libsolidity/LValue.cpp b/libsolidity/LValue.cpp index 7eec478b3..82701ea95 100644 --- a/libsolidity/LValue.cpp +++ b/libsolidity/LValue.cpp @@ -47,6 +47,7 @@ void StackVariable::retrieveValue(SourceLocation const& _location, bool) const errinfo_sourceLocation(_location) << errinfo_comment("Stack too deep, try removing local variables.") ); + solAssert(stackPos + 1 >= m_size, "Size and stack pos mismatch."); for (unsigned i = 0; i < m_size; ++i) m_context << eth::dupInstruction(stackPos + 1); } @@ -175,6 +176,7 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _location, bool _move) const { + CompilerUtils utils(m_context); // stack: value storage_key storage_offset if (m_dataType.isValueType()) { @@ -207,7 +209,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc // stack: value storage_ref cleared_value multiplier value if (m_dataType.getCategory() == Type::Category::FixedBytes) m_context - << (u256(0x1) << (256 - 8 * dynamic_cast(m_dataType).getNumBytes())) + << (u256(0x1) << (256 - 8 * dynamic_cast(m_dataType).numBytes())) << eth::Instruction::SWAP1 << eth::Instruction::DIV; else if ( m_dataType.getCategory() == Type::Category::Integer && @@ -238,52 +240,66 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc dynamic_cast(m_dataType), dynamic_cast(_sourceType)); if (_move) - CompilerUtils(m_context).popStackElement(_sourceType); + utils.popStackElement(m_dataType); } else if (m_dataType.getCategory() == Type::Category::Struct) { - // stack layout: source_ref source_offset target_ref target_offset + // stack layout: source_ref [source_offset] target_ref target_offset // note that we have structs, so offsets should be zero and are ignored auto const& structType = dynamic_cast(m_dataType); + auto const& sourceType = dynamic_cast(_sourceType); solAssert( - structType.structDefinition() == - dynamic_cast(_sourceType).structDefinition(), + structType.structDefinition() == sourceType.structDefinition(), "Struct assignment with conversion." ); + solAssert(sourceType.location() != DataLocation::CallData, "Structs in calldata not supported."); for (auto const& member: structType.getMembers()) { // assign each member that is not a mapping TypePointer const& memberType = member.type; if (memberType->getCategory() == Type::Category::Mapping) continue; + TypePointer sourceMemberType = sourceType.getMemberType(member.name); + if (sourceType.location() == DataLocation::Storage) + { + // stack layout: source_ref source_offset target_ref target_offset + pair const& offsets = sourceType.getStorageOffsetsOfMember(member.name); + m_context << offsets.first << eth::Instruction::DUP5 << eth::Instruction::ADD; + m_context << u256(offsets.second); + // stack: source_ref source_off target_ref target_off source_member_ref source_member_off + StorageItem(m_context, *sourceMemberType).retrieveValue(_location, true); + // stack: source_ref source_off target_ref target_off source_value... + } + else + { + solAssert(sourceType.location() == DataLocation::Memory, ""); + // stack layout: source_ref target_ref target_offset + TypePointer sourceMemberType = sourceType.getMemberType(member.name); + m_context << sourceType.memoryOffsetOfMember(member.name); + m_context << eth::Instruction::DUP4 << eth::Instruction::ADD; + MemoryItem(m_context, *sourceMemberType).retrieveValue(_location, true); + // stack layout: source_ref target_ref target_offset source_value... + } + unsigned stackSize = sourceMemberType->getSizeOnStack(); pair const& offsets = structType.getStorageOffsetsOfMember(member.name); - m_context - << offsets.first << u256(offsets.second) - << eth::Instruction::DUP6 << eth::Instruction::DUP3 - << eth::Instruction::ADD << eth::Instruction::DUP2; - // stack: source_ref source_off target_ref target_off member_slot_offset member_byte_offset source_member_ref source_member_off - StorageItem(m_context, *memberType).retrieveValue(_location, true); - // stack: source_ref source_off target_ref target_off member_offset source_value... - solAssert( - 4 + memberType->getSizeOnStack() <= 16, - "Stack too deep, try removing local varibales." - ); - m_context - << eth::dupInstruction(4 + memberType->getSizeOnStack()) - << eth::dupInstruction(3 + memberType->getSizeOnStack()) << eth::Instruction::ADD - << eth::dupInstruction(2 + memberType->getSizeOnStack()); - // stack: source_ref source_off target_ref target_off member_slot_offset member_byte_offset source_value... target_member_ref target_member_byte_off - StorageItem(m_context, *memberType).storeValue(*memberType, _location, true); - m_context << eth::Instruction::POP << eth::Instruction::POP; + m_context << eth::dupInstruction(2 + stackSize) << offsets.first << eth::Instruction::ADD; + m_context << u256(offsets.second); + // stack: source_ref [source_off] target_ref target_off source_value... target_member_ref target_member_byte_off + StorageItem(m_context, *memberType).storeValue(*sourceMemberType, _location, true); } + // stack layout: source_ref [source_offset] target_ref target_offset + unsigned sourceStackSize = sourceType.getSizeOnStack(); if (_move) - m_context - << eth::Instruction::POP << eth::Instruction::POP - << eth::Instruction::POP << eth::Instruction::POP; - else - m_context - << eth::Instruction::SWAP2 << eth::Instruction::POP - << eth::Instruction::SWAP2 << eth::Instruction::POP; + utils.popStackSlots(2 + sourceType.getSizeOnStack()); + else if (sourceType.getSizeOnStack() >= 1) + { + // remove the source ref + solAssert(sourceStackSize <= 2, "Invalid stack size."); + m_context << eth::swapInstruction(sourceStackSize); + if (sourceStackSize == 2) + m_context << eth::Instruction::POP; + m_context << eth::Instruction::SWAP2 << eth::Instruction::POP; + } } else BOOST_THROW_EXCEPTION( diff --git a/libsolidity/LValue.h b/libsolidity/LValue.h index 882b3626e..a93df9f9d 100644 --- a/libsolidity/LValue.h +++ b/libsolidity/LValue.h @@ -103,7 +103,7 @@ private: class MemoryItem: public LValue { public: - MemoryItem(CompilerContext& _compilerContext, Type const& _type, bool _padded); + MemoryItem(CompilerContext& _compilerContext, Type const& _type, bool _padded = true); virtual unsigned sizeOnStack() const override { return 1; } virtual void retrieveValue(SourceLocation const& _location, bool _remove = false) const override; virtual void storeValue( diff --git a/libsolidity/Types.cpp b/libsolidity/Types.cpp index c1769d000..3ea9caa7d 100644 --- a/libsolidity/Types.cpp +++ b/libsolidity/Types.cpp @@ -30,11 +30,8 @@ #include using namespace std; - -namespace dev -{ -namespace solidity -{ +using namespace dev; +using namespace dev::solidity; void StorageOffsets::computeOffsets(TypePointers const& _types) { @@ -215,8 +212,7 @@ TypePointer Type::forLiteral(Literal const& _literal) case Token::Number: return make_shared(_literal); case Token::StringLiteral: - //@todo put larger strings into dynamic strings - return FixedBytesType::smallestTypeForLiteral(_literal.getValue()); + return make_shared(_literal); default: return shared_ptr(); } @@ -381,7 +377,7 @@ bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) cons else if (_convertTo.getCategory() == Category::FixedBytes) { FixedBytesType const& fixedBytes = dynamic_cast(_convertTo); - return fixedBytes.getNumBytes() * 8 >= getIntegerType()->getNumBits(); + return fixedBytes.numBytes() * 8 >= getIntegerType()->getNumBits(); } else return false; @@ -533,6 +529,33 @@ shared_ptr IntegerConstantType::getIntegerType() const ); } +StringLiteralType::StringLiteralType(Literal const& _literal): + m_value(_literal.getValue()) +{ +} + +bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const +{ + if (auto fixedBytes = dynamic_cast(&_convertTo)) + return size_t(fixedBytes->numBytes()) >= m_value.size(); + else if (auto arrayType = dynamic_cast(&_convertTo)) + return arrayType->isByteArray(); + else + return false; +} + +bool StringLiteralType::operator==(const Type& _other) const +{ + if (_other.getCategory() != getCategory()) + return false; + return m_value == dynamic_cast(_other).m_value; +} + +TypePointer StringLiteralType::mobileType() const +{ + return make_shared(DataLocation::Memory, true); +} + shared_ptr FixedBytesType::smallestTypeForLiteral(string const& _literal) { if (_literal.length() <= 32) @@ -593,15 +616,6 @@ bool FixedBytesType::operator==(Type const& _other) const return other.m_bytes == m_bytes; } -u256 FixedBytesType::literalValue(const Literal* _literal) const -{ - solAssert(_literal, ""); - u256 value = 0; - for (char c: _literal->getValue()) - value = (value << 8) | byte(c); - return value << ((32 - _literal->getValue().length()) * 8); -} - bool BoolType::isExplicitlyConvertibleTo(Type const& _convertTo) const { // conversion to integer is fine, but not to address @@ -999,6 +1013,15 @@ unsigned StructType::getCalldataEncodedSize(bool _padded) const return size; } +u256 StructType::memorySize() const +{ + u256 size; + for (auto const& member: getMembers()) + if (member.type->canLiveOutsideStorage()) + size += member.type->memoryHeadSize(); + return size; +} + u256 StructType::getStorageSize() const { return max(1, getMembers().getStorageSize()); @@ -1012,6 +1035,14 @@ bool StructType::canLiveOutsideStorage() const return true; } +unsigned StructType::getSizeOnStack() const +{ + if (location() == DataLocation::Storage) + return 2; // slot and offset + else + return 1; +} + string StructType::toString(bool _short) const { string ret = "struct " + m_struct.getName(); @@ -1047,6 +1078,26 @@ TypePointer StructType::copyForLocation(DataLocation _location, bool _isPointer) return copy; } +FunctionTypePointer StructType::constructorType() const +{ + TypePointers paramTypes; + strings paramNames; + for (auto const& member: getMembers()) + { + if (!member.type->canLiveOutsideStorage()) + continue; + paramNames.push_back(member.name); + paramTypes.push_back(copyForLocationIfReference(DataLocation::Memory, member.type)); + } + return make_shared( + paramTypes, + TypePointers{copyForLocation(DataLocation::Memory, false)}, + paramNames, + strings(), + FunctionType::Location::Internal + ); +} + pair const& StructType::getStorageOffsetsOfMember(string const& _name) const { auto const* offsets = getMembers().getMemberStorageOffset(_name); @@ -1054,6 +1105,18 @@ pair const& StructType::getStorageOffsetsOfMember(string const& return *offsets; } +u256 StructType::memoryOffsetOfMember(string const& _name) const +{ + u256 offset; + for (auto const& member: getMembers()) + if (member.name == _name) + return offset; + else + offset += member.type->memoryHeadSize(); + solAssert(false, "Member not found in struct."); + return 0; +} + TypePointer EnumType::unaryOperatorResult(Token::Value _operator) const { return _operator == Token::Delete ? make_shared() : TypePointer(); @@ -1663,6 +1726,3 @@ string MagicType::toString(bool) const BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of magic.")); } } - -} -} diff --git a/libsolidity/Types.h b/libsolidity/Types.h index 6b03b1ae2..e17a262c6 100644 --- a/libsolidity/Types.h +++ b/libsolidity/Types.h @@ -131,7 +131,7 @@ class Type: private boost::noncopyable, public std::enable_shared_from_this const& getStorageOffsetsOfMember(std::string const& _name) const; + u256 memoryOffsetOfMember(std::string const& _name) const; StructDefinition const& structDefinition() const { return m_struct; } diff --git a/libsolidity/Version.cpp b/libsolidity/Version.cpp new file mode 100644 index 000000000..971fb334b --- /dev/null +++ b/libsolidity/Version.cpp @@ -0,0 +1,39 @@ +/* + 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 . +*/ +/** + * @author Christian + * @date 2015 + * Versioning. + */ + +#include +#include +#include +#include + +using namespace dev; +using namespace dev::solidity; +using namespace std; + +char const* dev::solidity::VersionNumber = "0.1.0"; +extern string const dev::solidity::VersionString = + string(dev::solidity::VersionNumber) + + "-" + + string(DEV_QUOTED(ETH_COMMIT_HASH)).substr(0, 8) + + (ETH_CLEAN_REPO ? "" : "*") + + "/" DEV_QUOTED(ETH_BUILD_TYPE) "-" DEV_QUOTED(ETH_BUILD_PLATFORM); + diff --git a/libsolidity/Version.h b/libsolidity/Version.h new file mode 100644 index 000000000..6e00f07b4 --- /dev/null +++ b/libsolidity/Version.h @@ -0,0 +1,36 @@ +/* + 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 . +*/ +/** + * @author Christian + * @date 2015 + * Versioning. + */ + +#pragma once + +#include + +namespace dev +{ +namespace solidity +{ + +extern char const* VersionNumber; +extern std::string const VersionString; + +} +} diff --git a/libtestutils/StateLoader.cpp b/libtestutils/StateLoader.cpp index 9eff30b29..235f1c573 100644 --- a/libtestutils/StateLoader.cpp +++ b/libtestutils/StateLoader.cpp @@ -1,16 +1,16 @@ /* 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 . */ @@ -36,10 +36,10 @@ StateLoader::StateLoader(Json::Value const& _json, std::string const& _dbPath): Address address = Address(name); bytes code = fromHex(o["code"].asString().substr(2)); - if (code.size()) + if (!code.empty()) { m_state.m_cache[address] = Account(u256(o["balance"].asString()), Account::ContractConception); - m_state.m_cache[address].setCode(code); + m_state.m_cache[address].setCode(std::move(code)); } else m_state.m_cache[address] = Account(u256(o["balance"].asString()), Account::NormalCreation); diff --git a/libweb3jsonrpc/AccountHolder.cpp b/libweb3jsonrpc/AccountHolder.cpp index 3250eae6b..43a7073d2 100644 --- a/libweb3jsonrpc/AccountHolder.cpp +++ b/libweb3jsonrpc/AccountHolder.cpp @@ -106,20 +106,22 @@ AddressHash SimpleAccountHolder::realAccounts() const return m_keyManager.accountsHash(); } -void SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) +h256 SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) { if (isRealAccount(_t.from)) - m_client()->submitTransaction(m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); }), _t); + return m_client()->submitTransaction(_t, m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); })).first; else if (isProxyAccount(_t.from)) queueTransaction(_t); + return h256(); } -void FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) +h256 FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t) { if (isRealAccount(_t.from)) - m_client()->submitTransaction(m_accounts[_t.from], _t); + return m_client()->submitTransaction(_t, m_accounts[_t.from]).first; else if (isProxyAccount(_t.from)) queueTransaction(_t); + return h256(); } diff --git a/libweb3jsonrpc/AccountHolder.h b/libweb3jsonrpc/AccountHolder.h index 559f8509a..4a30826ae 100644 --- a/libweb3jsonrpc/AccountHolder.h +++ b/libweb3jsonrpc/AccountHolder.h @@ -51,7 +51,7 @@ public: virtual AddressHash realAccounts() const = 0; // use m_web3's submitTransaction // or use AccountHolder::queueTransaction(_t) to accept - virtual void authenticate(dev::eth::TransactionSkeleton const& _t) = 0; + virtual h256 authenticate(dev::eth::TransactionSkeleton const& _t) = 0; Addresses allAccounts() const; bool isRealAccount(Address const& _account) const { return realAccounts().count(_account) > 0; } @@ -85,7 +85,7 @@ public: {} AddressHash realAccounts() const override; - void authenticate(dev::eth::TransactionSkeleton const& _t) override; + h256 authenticate(dev::eth::TransactionSkeleton const& _t) override; private: std::function m_getPassword; @@ -117,7 +117,7 @@ public: // use m_web3's submitTransaction // or use AccountHolder::queueTransaction(_t) to accept - void authenticate(dev::eth::TransactionSkeleton const& _t) override; + h256 authenticate(dev::eth::TransactionSkeleton const& _t) override; private: std::unordered_map m_accounts; diff --git a/libweb3jsonrpc/JsonHelper.cpp b/libweb3jsonrpc/JsonHelper.cpp index c148d792c..ec69aba22 100644 --- a/libweb3jsonrpc/JsonHelper.cpp +++ b/libweb3jsonrpc/JsonHelper.cpp @@ -182,6 +182,33 @@ Json::Value toJson(dev::eth::TransactionReceipt const& _t) return res; } +Json::Value toJson(dev::eth::TransactionReceipt const& _tr, std::pair _location, BlockNumber _blockNumber, Transaction const& _t) +{ + Json::Value res; + h256 h = _t.sha3(); + res["transactionHash"] = toJS(h); + res["transactionIndex"] = _location.second; + res["blockHash"] = toJS(_location.first); + res["blockNumber"] = _blockNumber; + res["cumulativeGasUsed"] = toJS(_tr.gasUsed()); // TODO: check if this is fine + res["gasUsed"] = toJS(_tr.gasUsed()); + res["contractAddress"] = toJS(toAddress(_t.from(), _t.nonce())); + res["logs"] = Json::Value(Json::arrayValue); + for (unsigned i = 0; i < _tr.log().size(); i++) + { + LogEntry e = _tr.log()[i]; + Json::Value l = toJson(e); + l["type"] = "mined"; + l["blockNumber"] = _blockNumber; + l["blockHash"] = toJS(_location.first); + l["logIndex"] = i; + l["transactionHash"] = toJS(h); + l["transactionIndex"] = _location.second; + res["logs"].append(l); + } + return res; +} + Json::Value toJson(dev::eth::Transaction const& _t) { Json::Value res; @@ -327,6 +354,9 @@ TransactionSkeleton toTransactionSkeleton(Json::Value const& _json) if (!_json["code"].empty()) ret.data = jsToBytes(_json["code"].asString()); + + if (!_json["nonce"].empty()) + ret.nonce = jsToU256(_json["nonce"].asString()); return ret; } diff --git a/libweb3jsonrpc/JsonHelper.h b/libweb3jsonrpc/JsonHelper.h index 7f4370046..0386a5b58 100644 --- a/libweb3jsonrpc/JsonHelper.h +++ b/libweb3jsonrpc/JsonHelper.h @@ -50,12 +50,15 @@ using UncleHashes = h256s; using TransactionHashes = h256s; Json::Value toJson(BlockInfo const& _bi); +//TODO: wrap these params into one structure eg. "LocalisedTransaction" Json::Value toJson(Transaction const& _t, std::pair _location, BlockNumber _blockNumber); Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes const& _us, Transactions const& _ts); Json::Value toJson(BlockInfo const& _bi, BlockDetails const& _bd, UncleHashes const& _us, TransactionHashes const& _ts); Json::Value toJson(TransactionSkeleton const& _t); Json::Value toJson(Transaction const& _t); Json::Value toJson(TransactionReceipt const& _t); +//TODO: wrap these params into one structure eg. "LocalisedTransactionReceipt" +Json::Value toJson(TransactionReceipt const& _tr, std::pair _location, BlockNumber _blockNumber, Transaction const& _t); Json::Value toJson(LocalisedLogEntry const& _e); Json::Value toJson(LogEntry const& _e); Json::Value toJson(std::map const& _entriesByBlock); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 4e4d42469..28b76b13a 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -242,21 +242,16 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) { try { - string ret; TransactionSkeleton t = toTransactionSkeleton(_json); if (!t.from) t.from = m_ethAccounts->defaultTransactAccount(); - if (t.creation) - ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; if (t.gasPrice == UndefinedU256) t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. if (t.gas == UndefinedU256) t.gas = min(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); - m_ethAccounts->authenticate(t); - - return ret; + return toJS(m_ethAccounts->authenticate(t)); } catch (...) { @@ -268,13 +263,10 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json) { try { - string ret; TransactionSkeleton t = toTransactionSkeleton(_json); if (!t.from) t.from = m_ethAccounts->defaultTransactAccount(); - if (t.creation) - ret = toJS(right160(sha3(rlpList(t.from, client()->countAt(t.from)))));; if (t.gasPrice == UndefinedU256) t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. if (t.gas == UndefinedU256) @@ -427,6 +419,23 @@ Json::Value WebThreeStubServerBase::eth_getTransactionByBlockNumberAndIndex(stri } } +Json::Value WebThreeStubServerBase::eth_getTransactionReceipt(string const& _transactionHash) +{ + try + { + h256 h = jsToFixed<32>(_transactionHash); + if (!client()->isKnownTransaction(h)) + return Json::Value(Json::nullValue); + + auto l = client()->transactionLocation(h); + return toJson(client()->transactionReceipt(h), l, client()->numberFromHash(l.first), client()->transaction(h)); + } + catch (...) + { + BOOST_THROW_EXCEPTION(JsonRpcException(Errors::ERROR_RPC_INVALID_PARAMS)); + } +} + Json::Value WebThreeStubServerBase::eth_getUncleByBlockHashAndIndex(string const& _blockHash, string const& _uncleIndex) { try diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 94fbd1acb..d90015aec 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -119,6 +119,7 @@ public: virtual Json::Value eth_getTransactionByHash(std::string const& _transactionHash); virtual Json::Value eth_getTransactionByBlockHashAndIndex(std::string const& _blockHash, std::string const& _transactionIndex); virtual Json::Value eth_getTransactionByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _transactionIndex); + virtual Json::Value eth_getTransactionReceipt(std::string const& _transactionHash); virtual Json::Value eth_getUncleByBlockHashAndIndex(std::string const& _blockHash, std::string const& _uncleIndex); virtual Json::Value eth_getUncleByBlockNumberAndIndex(std::string const& _blockNumber, std::string const& _uncleIndex); virtual Json::Value eth_getCompilers(); diff --git a/libweb3jsonrpc/abstractwebthreestubserver.h b/libweb3jsonrpc/abstractwebthreestubserver.h index 6d0db7394..988271c95 100644 --- a/libweb3jsonrpc/abstractwebthreestubserver.h +++ b/libweb3jsonrpc/abstractwebthreestubserver.h @@ -40,6 +40,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServerbindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByHash", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByHashI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByBlockHashAndIndexI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionByBlockNumberAndIndexI); + this->bindAndAddMethod(jsonrpc::Procedure("eth_getTransactionReceipt", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getTransactionReceiptI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockHashAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleByBlockHashAndIndexI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getUncleByBlockNumberAndIndex", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_OBJECT, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_getUncleByBlockNumberAndIndexI); this->bindAndAddMethod(jsonrpc::Procedure("eth_getCompilers", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_getCompilersI); @@ -224,6 +225,10 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServereth_getTransactionByBlockNumberAndIndex(request[0u].asString(), request[1u].asString()); } + inline virtual void eth_getTransactionReceiptI(const Json::Value &request, Json::Value &response) + { + response = this->eth_getTransactionReceipt(request[0u].asString()); + } inline virtual void eth_getUncleByBlockHashAndIndexI(const Json::Value &request, Json::Value &response) { response = this->eth_getUncleByBlockHashAndIndex(request[0u].asString(), request[1u].asString()); @@ -489,6 +494,7 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServersetExtraData(rlpList(0, _clientVersion, m_net.id())); + } if (_interfaces.count("shh")) m_whisper = m_net.registerCapability(new WhisperHost); diff --git a/libwhisper/BloomFilter.cpp b/libwhisper/BloomFilter.cpp deleted file mode 100644 index 554274011..000000000 --- a/libwhisper/BloomFilter.cpp +++ /dev/null @@ -1,28 +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 BloomFilter.cpp -* @author Vladislav Gluhovsky -* @date June 2015 -*/ - -#include "BloomFilter.h" - -using namespace std; -using namespace dev; -using namespace dev::shh; - - diff --git a/libwhisper/BloomFilter.h b/libwhisper/BloomFilter.h index a624be157..02cc80505 100644 --- a/libwhisper/BloomFilter.h +++ b/libwhisper/BloomFilter.h @@ -35,21 +35,22 @@ public: TopicBloomFilterBase() { init(); } TopicBloomFilterBase(FixedHash const& _h): FixedHash(_h) { init(); } - void addBloom(dev::shh::AbridgedTopic const& _h) { addRaw(_h.template bloomPart()); } - void removeBloom(dev::shh::AbridgedTopic const& _h) { removeRaw(_h.template bloomPart()); } - bool containsBloom(dev::shh::AbridgedTopic const& _h) const { return this->contains(_h.template bloomPart()); } + void addBloom(AbridgedTopic const& _h) { addRaw(bloom(_h)); } + void removeBloom(AbridgedTopic const& _h) { removeRaw(bloom(_h)); } + bool containsBloom(AbridgedTopic const& _h) const { return this->contains(bloom(_h)); } void addRaw(FixedHash const& _h); void removeRaw(FixedHash const& _h); bool containsRaw(FixedHash const& _h) const { return this->contains(_h); } - enum { BitsPerBloom = 3 }; + static FixedHash bloom(AbridgedTopic const& _h); + static void setBit(FixedHash& _h, unsigned index); + static bool isBitSet(FixedHash const& _h, unsigned _index); private: void init() { for (unsigned i = 0; i < CounterSize; ++i) m_refCounter[i] = 0; } - static bool isBitSet(FixedHash const& _h, unsigned _index); - enum { CounterSize = 8 * TopicBloomFilterBase::size }; + static const unsigned CounterSize = N * 8; std::array m_refCounter; }; @@ -85,13 +86,52 @@ void TopicBloomFilterBase::removeRaw(FixedHash const& _h) template bool TopicBloomFilterBase::isBitSet(FixedHash const& _h, unsigned _index) -{ +{ unsigned iByte = _index / 8; unsigned iBit = _index % 8; return (_h[iByte] & c_powerOfTwoBitMmask[iBit]) != 0; } -using TopicBloomFilter = TopicBloomFilterBase; +template +void TopicBloomFilterBase::setBit(FixedHash& _h, unsigned _index) +{ + unsigned iByte = _index / 8; + unsigned iBit = _index % 8; + _h[iByte] |= c_powerOfTwoBitMmask[iBit]; +} + +template +FixedHash TopicBloomFilterBase::bloom(AbridgedTopic const& _h) +{ + // The size of AbridgedTopic is 32 bits, and 27 of them participate in this algorithm. + + // We need to review the algorithm if any of the following constants will be changed. + static_assert(4 == AbridgedTopic::size, "wrong template parameter in TopicBloomFilterBase::bloom()"); + static_assert(3 == BitsPerBloom, "wrong template parameter in TopicBloomFilterBase::bloom()"); + + FixedHash ret; + + if (TopicBloomFilterSize == N) + for (unsigned i = 0; i < BitsPerBloom; ++i) + { + unsigned x = _h[i]; + if (_h[BitsPerBloom] & c_powerOfTwoBitMmask[i]) + x += 256; + + setBit(ret, x); + } + else + for (unsigned i = 0; i < BitsPerBloom; ++i) + { + unsigned x = unsigned(_h[i]) + unsigned(_h[i + 1]); + x %= N * 8; + setBit(ret, x); + } + + return ret; +} + +using TopicBloomFilter = TopicBloomFilterBase; } } diff --git a/libwhisper/Common.cpp b/libwhisper/Common.cpp index 748180647..4681a21b3 100644 --- a/libwhisper/Common.cpp +++ b/libwhisper/Common.cpp @@ -100,7 +100,7 @@ TopicBloomFilterHash TopicFilter::exportBloom() const TopicBloomFilterHash ret; for (TopicMask const& t: m_topicMasks) for (auto const& i: t) - ret |= i.first.template bloomPart(); + ret |= TopicBloomFilter::bloom(i.first); return ret; } diff --git a/libwhisper/Common.h b/libwhisper/Common.h index d5d926291..277ce0902 100644 --- a/libwhisper/Common.h +++ b/libwhisper/Common.h @@ -58,8 +58,9 @@ enum WhisperPacket PacketCount }; -static const int c_topicBloomFilterSize = 64; -static const int c_whisperProtocolVersion = 3; +static const unsigned TopicBloomFilterSize = 64; +static const unsigned BitsPerBloom = 3; +static const unsigned WhisperProtocolVersion = 3; using AbridgedTopic = FixedHash<4>; using Topic = h256; @@ -67,7 +68,7 @@ using Topic = h256; using AbridgedTopics = std::vector; using Topics = h256s; -using TopicBloomFilterHash = FixedHash; +using TopicBloomFilterHash = FixedHash; AbridgedTopic abridge(Topic const& _topic); AbridgedTopics abridge(Topics const& _topics); diff --git a/libwhisper/Message.cpp b/libwhisper/Message.cpp index 50020b783..dd72ff734 100644 --- a/libwhisper/Message.cpp +++ b/libwhisper/Message.cpp @@ -20,6 +20,7 @@ */ #include "Message.h" +#include "BloomFilter.h" using namespace std; using namespace dev; @@ -161,23 +162,30 @@ unsigned Envelope::workProved() const void Envelope::proveWork(unsigned _ms) { - // PoW h256 d[2]; d[0] = sha3(WithoutNonce); - uint32_t& n = *(uint32_t*)&(d[1][28]); unsigned bestBitSet = 0; bytesConstRef chuck(d[0].data(), 64); chrono::high_resolution_clock::time_point then = chrono::high_resolution_clock::now() + chrono::milliseconds(_ms); - for (n = 0; chrono::high_resolution_clock::now() < then; ) + while (chrono::high_resolution_clock::now() < then) // do it rounds of 1024 for efficiency - for (unsigned i = 0; i < 1024; ++i, ++n) + for (unsigned i = 0; i < 1024; ++i, ++d[1]) { auto fbs = dev::sha3(chuck).firstBitSet(); if (fbs > bestBitSet) { bestBitSet = fbs; - m_nonce = n; + m_nonce = (h256::Arith)d[1]; } } } + +bool Envelope::matchesBloomFilter(TopicBloomFilterHash const& f) const +{ + for (AbridgedTopic t: m_topic) + if (f.contains(TopicBloomFilter::bloom(t))) + return true; + + return false; +} diff --git a/libwhisper/Message.h b/libwhisper/Message.h index 3529054e0..ae61f210a 100644 --- a/libwhisper/Message.h +++ b/libwhisper/Message.h @@ -80,6 +80,8 @@ public: unsigned workProved() const; void proveWork(unsigned _ms); + bool matchesBloomFilter(TopicBloomFilterHash const& f) const; + private: Envelope(unsigned _exp, unsigned _ttl, AbridgedTopics const& _topic): m_expiry(_exp), m_ttl(_ttl), m_topic(_topic) {} diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp index 150d5cd63..5d83dd399 100644 --- a/libwhisper/WhisperHost.cpp +++ b/libwhisper/WhisperHost.cpp @@ -51,6 +51,9 @@ void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p) { + // this function processes both outgoing messages originated both by local host (_p == null) + // and incoming messages from remote peers (_p != null) + cnote << this << ": inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data()); if (_m.expiry() <= (unsigned)time(0)) @@ -66,13 +69,32 @@ void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p) m_expiryQueue.insert(make_pair(_m.expiry(), h)); } + // rating of incoming message from remote host is assessed according to the following criteria: + // 1. installed watch match; 2. bloom filter match; 2. ttl; 3. proof of work + + int rating = 0; + DEV_GUARDED(m_filterLock) + if (_m.matchesBloomFilter(m_bloom)) + { + ++rating; + for (auto const& f: m_filters) + if (f.second.filter.matches(_m)) + for (auto& i: m_watches) + if (i.second.id == f.first) + { + i.second.changes.push_back(h); + rating += 2; + } + } + + if (_p) // incoming message from remote peer { - for (auto const& f: m_filters) - if (f.second.filter.matches(_m)) - for (auto& i: m_watches) - if (i.second.id == f.first) - i.second.changes.push_back(h); + rating *= 256; + unsigned ttlReward = (256 > _m.ttl() ? 256 - _m.ttl() : 0); + rating += ttlReward; + rating *= 256; + rating += _m.workProved(); } // TODO p2p: capability-based rating @@ -80,7 +102,7 @@ void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p) { auto w = i.first->cap().get(); if (w == _p) - w->addRating(1); + w->addRating(rating); else w->noteNewMessage(h, _m); } diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h index a6de09c38..fc1bcb557 100644 --- a/libwhisper/WhisperHost.h +++ b/libwhisper/WhisperHost.h @@ -50,7 +50,7 @@ class WhisperHost: public HostCapability, public Interface, public public: WhisperHost(); virtual ~WhisperHost(); - unsigned protocolVersion() const { return c_whisperProtocolVersion; } + unsigned protocolVersion() const { return WhisperProtocolVersion; } /// remove old messages void cleanup(); std::map all() const { dev::ReadGuard l(x_messages); return m_messages; } diff --git a/libwhisper/WhisperPeer.cpp b/libwhisper/WhisperPeer.cpp index d749aa26e..30a188f2d 100644 --- a/libwhisper/WhisperPeer.cpp +++ b/libwhisper/WhisperPeer.cpp @@ -91,19 +91,17 @@ void WhisperPeer::sendMessages() if (m_advertiseTopicsOfInterest) sendTopicsOfInterest(host()->bloom()); + multimap available; + DEV_GUARDED(x_unseen) + m_unseen.swap(available); + RLPStream amalg; - unsigned msgCount = 0; - { - Guard l(x_unseen); - msgCount = m_unseen.size(); - while (m_unseen.size()) - { - auto p = *m_unseen.begin(); - m_unseen.erase(m_unseen.begin()); - host()->streamMessage(p.second, amalg); - } - } - + + // send the highest rated messages first + for (auto i = available.rbegin(); i != available.rend(); ++i) + host()->streamMessage(i->second, amalg); + + unsigned msgCount = available.size(); if (msgCount) { RLPStream s; @@ -114,8 +112,31 @@ void WhisperPeer::sendMessages() void WhisperPeer::noteNewMessage(h256 _h, Envelope const& _m) { + unsigned rate = ratingForPeer(_m); Guard l(x_unseen); - m_unseen.insert(make_pair(rating(_m), _h)); + m_unseen.insert(make_pair(rate, _h)); +} + +unsigned WhisperPeer::ratingForPeer(Envelope const& e) const +{ + // we try to estimate, how valuable this nessage will be for the remote peer, + // according to the following criteria: + // 1. bloom filter + // 2. time to live + // 3. proof of work + + unsigned rating = 0; + + if (e.matchesBloomFilter(bloom())) + ++rating; + + rating *= 256; + unsigned ttlReward = (256 > e.ttl() ? 256 - e.ttl() : 0); + rating += ttlReward; + + rating *= 256; + rating += e.workProved(); + return rating; } void WhisperPeer::sendTopicsOfInterest(TopicBloomFilterHash const& _bloom) diff --git a/libwhisper/WhisperPeer.h b/libwhisper/WhisperPeer.h index 48f984013..4d093d259 100644 --- a/libwhisper/WhisperPeer.h +++ b/libwhisper/WhisperPeer.h @@ -53,7 +53,7 @@ public: virtual ~WhisperPeer(); WhisperHost* host() const; static std::string name() { return "shh"; } - static u256 version() { return c_whisperProtocolVersion; } + static u256 version() { return WhisperProtocolVersion; } static unsigned messageCount() { return PacketCount; } TopicBloomFilterHash bloom() const { dev::Guard g(x_bloom); return m_bloom; } void sendTopicsOfInterest(TopicBloomFilterHash const& _bloom); ///< sends our bloom filter to remote peer @@ -62,7 +62,7 @@ public: private: virtual bool interpret(unsigned _id, RLP const&) override; void sendMessages(); - unsigned rating(Envelope const&) const { return 0; } // TODO + unsigned ratingForPeer(Envelope const& e) const; void noteNewMessage(h256 _h, Envelope const& _m); void setBloom(TopicBloomFilterHash const& _b) { dev::Guard g(x_bloom); m_bloom = _b; } diff --git a/mix/CMakeLists.txt b/mix/CMakeLists.txt index 6a434534f..c239edd47 100644 --- a/mix/CMakeLists.txt +++ b/mix/CMakeLists.txt @@ -15,6 +15,11 @@ include_directories(BEFORE ${JSONCPP_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) include_directories(BEFORE ..) +if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.6") AND NOT APPLE) + # Supress warnings for qt headers for clang+ccache + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-inconsistent-missing-override") +endif () + find_package (Qt5WebEngine QUIET) qt5_add_resources(UI_RESOURCES res.qrc qml.qrc) diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index e07641db8..90ff19feb 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -206,6 +206,21 @@ QVariantList ClientModel::gasCosts() const return res; } +void ClientModel::addAccount(QString const& _secret) +{ + KeyPair key(Secret(_secret.toStdString())); + m_accountsSecret.push_back(key); + Address address = key.address(); + m_accounts[address] = Account(u256(0), Account::NormalCreation); + m_ethAccounts->setAccounts(m_accountsSecret); +} + +QString ClientModel::resolveAddress(QString const& _secret) +{ + KeyPair key(Secret(_secret.toStdString())); + return "0x" + QString::fromStdString(key.address().hex()); +} + void ClientModel::setupScenario(QVariantMap _scenario) { onStateReset(); @@ -336,6 +351,7 @@ void ClientModel::executeSequence(vector const& _sequence) if (!transaction.isFunctionCall) { callAddress(Address(address.toStdString()), bytes(), transaction); + onNewTransaction(); continue; } @@ -658,8 +674,7 @@ void ClientModel::debugRecord(unsigned _index) Address ClientModel::deployContract(bytes const& _code, TransactionSettings const& _ctrTransaction) { - Address newAddress = m_client->submitTransaction(_ctrTransaction.sender, _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice, _ctrTransaction.gasAuto); - return newAddress; + return m_client->submitTransaction(_ctrTransaction.sender, _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice, _ctrTransaction.gasAuto); } void ClientModel::callAddress(Address const& _contract, bytes const& _data, TransactionSettings const& _tr) @@ -674,7 +689,7 @@ RecordLogEntry* ClientModel::lastBlock() const strGas << blockInfo.gasUsed; stringstream strNumber; strNumber << blockInfo.number; - RecordLogEntry* record = new RecordLogEntry(0, QString::fromStdString(strNumber.str()), tr(" - Block - "), tr("Hash: ") + QString(QString::fromStdString(dev::toHex(blockInfo.hash().ref()))), QString(), QString(), QString(), false, RecordLogEntry::RecordType::Block, QString::fromStdString(strGas.str()), QString(), tr("Block"), QVariantMap(), QVariantList()); + RecordLogEntry* record = new RecordLogEntry(0, QString::fromStdString(strNumber.str()), tr(" - Block - "), tr("Hash: ") + QString(QString::fromStdString(dev::toHex(blockInfo.hash().ref()))), QString(), QString(), QString(), false, RecordLogEntry::RecordType::Block, QString::fromStdString(strGas.str()), QString(), tr("Block"), QVariantMap(), QVariantMap(), QVariantList()); QQmlEngine::setObjectOwnership(record, QQmlEngine::JavaScriptOwnership); return record; } @@ -735,6 +750,7 @@ void ClientModel::onNewTransaction() Address contractAddress = (bool)tr.address ? tr.address : tr.contractAddress; auto contractAddressIter = m_contractNames.find(contractAddress); QVariantMap inputParameters; + QVariantMap returnParameters; QVariantList logs; if (contractAddressIter != m_contractNames.end()) { @@ -754,6 +770,11 @@ void ClientModel::onNewTransaction() returned += "("; returned += returnValues.join(", "); returned += ")"; + + QStringList returnParams = encoder.decode(funcDef->returnParameters(), tr.result.output); + for (int k = 0; k < returnParams.length(); ++k) + returnParameters.insert(funcDef->returnParameters().at(k)->name(), returnParams.at(k)); + bytes data = tr.inputParameters; data.erase(data.begin(), data.begin() + 4); QStringList parameters = encoder.decode(funcDef->parametersList(), data); @@ -837,9 +858,25 @@ void ClientModel::onNewTransaction() } RecordLogEntry* log = new RecordLogEntry(recordIndex, transactionIndex, contract, function, value, address, returned, tr.isCall(), RecordLogEntry::RecordType::Transaction, - gasUsed, sender, label, inputParameters, logs); + gasUsed, sender, label, inputParameters, returnParameters, logs); QQmlEngine::setObjectOwnership(log, QQmlEngine::JavaScriptOwnership); emit newRecord(log); + + // retrieving all accounts balance + QVariantMap state; + QVariantMap accountBalances; + for (auto const& ctr : m_contractAddresses) + { + u256 wei = m_client->balanceAt(ctr.second, PendingBlock); + accountBalances.insert("0x" + QString::fromStdString(ctr.second.hex()), QEther(wei, QEther::Wei).format()); + } + for (auto const& account : m_accounts) + { + u256 wei = m_client->balanceAt(account.first, PendingBlock); + accountBalances.insert("0x" + QString::fromStdString(account.first.hex()), QEther(wei, QEther::Wei).format()); + } + state.insert("accounts", accountBalances); + emit newState(recordIndex, state); } } diff --git a/mix/ClientModel.h b/mix/ClientModel.h index b5b783b3d..ca8c36b79 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -32,6 +32,7 @@ #include #include #include "MachineStates.h" +#include "QEther.h" namespace dev { @@ -115,6 +116,8 @@ class RecordLogEntry: public QObject Q_PROPERTY(QString label MEMBER m_label CONSTANT) /// input parameters Q_PROPERTY(QVariantMap parameters MEMBER m_inputParameters CONSTANT) + /// return parameters + Q_PROPERTY(QVariantMap returnParameters MEMBER m_returnParameters CONSTANT) /// logs Q_PROPERTY(QVariantList logs MEMBER m_logs CONSTANT) @@ -128,9 +131,9 @@ public: RecordLogEntry(): m_recordIndex(0), m_call(false), m_type(RecordType::Transaction) {} RecordLogEntry(unsigned _recordIndex, QString _transactionIndex, QString _contract, QString _function, QString _value, QString _address, QString _returned, bool _call, RecordType _type, QString _gasUsed, - QString _sender, QString _label, QVariantMap _inputParameters, QVariantList _logs): + QString _sender, QString _label, QVariantMap _inputParameters, QVariantMap _returnParameters, QVariantList _logs): m_recordIndex(_recordIndex), m_transactionIndex(_transactionIndex), m_contract(_contract), m_function(_function), m_value(_value), m_address(_address), m_returned(_returned), m_call(_call), m_type(_type), m_gasUsed(_gasUsed), - m_sender(_sender), m_label(_label), m_inputParameters(_inputParameters), m_logs(_logs) {} + m_sender(_sender), m_label(_label), m_inputParameters(_inputParameters), m_returnParameters(_returnParameters), m_logs(_logs) {} private: unsigned m_recordIndex; @@ -146,6 +149,7 @@ private: QString m_sender; QString m_label; QVariantMap m_inputParameters; + QVariantMap m_returnParameters; QVariantList m_logs; }; @@ -183,6 +187,10 @@ public: Q_INVOKABLE QString encodeStringParam(QString const& _param); /// To Hex number Q_INVOKABLE QString toHex(QString const& _int); + /// Add new account to the model + Q_INVOKABLE void addAccount(QString const& _secret); + /// Return the address associated with the current secret + Q_INVOKABLE QString resolveAddress(QString const& _secret); public slots: /// Setup scenario, run transaction sequence, show debugger for the last transaction @@ -236,13 +244,15 @@ signals: void newRecord(RecordLogEntry* _r); /// State (transaction log) cleared void stateCleared(); + /// new state has been processed + void newState(unsigned _record, QVariantMap _accounts); private: RecordLogEntry* lastBlock() const; QVariantMap contractAddresses() const; QVariantList gasCosts() const; void executeSequence(std::vector const& _sequence); - dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); + Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); void callAddress(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); void onNewTransaction(); void onStateReset(); diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index 655be1c08..082745cfe 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -543,7 +543,7 @@ void CodeModel::retrieveSubType(SolidityType& _wrapperType, dev::solidity::Type SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) { - SolidityType r { SolidityType::Type::UnsignedInteger, 32, 1, false, false, QString::fromStdString(_type->toString()), std::vector(), std::vector(), nullptr }; + SolidityType r { SolidityType::Type::UnsignedInteger, 32, 1, false, false, QString::fromStdString(_type->toString(true)), std::vector(), std::vector(), nullptr }; if (!_type) return r; switch (_type->getCategory()) @@ -562,7 +562,7 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) { FixedBytesType const* b = dynamic_cast(_type); r.type = SolidityType::Type::Bytes; - r.size = static_cast(b->getNumBytes()); + r.size = static_cast(b->numBytes()); } break; case Type::Category::Contract: @@ -608,6 +608,7 @@ SolidityType CodeModel::nodeType(dev::solidity::Type const* _type) break; case Type::Category::Function: case Type::Category::IntegerConstant: + case Type::Category::StringLiteral: case Type::Category::Magic: case Type::Category::Mapping: case Type::Category::Modifier: diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index 37bc194fb..c80aecdd8 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -69,7 +69,7 @@ class QSolState: public QObject public: QSolState(QObject* _parent, QVariantMap&& _storage, QVariantList&& _callStack, QVariantMap&& _locals, int _start, int _end, QString _sourceName): - QObject(_parent), m_storage(_storage), m_callStack(_callStack), m_locals(_locals), m_start(_start), m_end(_end), m_sourceName(_sourceName) + QObject(_parent), m_storage(std::move(_storage)), m_callStack(std::move(_callStack)), m_locals(std::move(_locals)), m_start(_start), m_end(_end), m_sourceName(_sourceName) { } private: @@ -92,7 +92,7 @@ class QCode: public QObject Q_PROPERTY(QString documentId MEMBER m_document CONSTANT) public: - QCode(QObject* _owner, QString const& _address, QVariantList&& _instrunctions): QObject(_owner), m_instructions(_instrunctions), m_address(_address) {} + QCode(QObject* _owner, QString const& _address, QVariantList&& _instrunctions): QObject(_owner), m_instructions(std::move(_instrunctions)), m_address(_address) {} void setDocument(QString const& _documentId) { m_document = _documentId; } private: @@ -110,7 +110,7 @@ class QCallData: public QObject Q_PROPERTY(QVariantList items MEMBER m_items CONSTANT) public: - QCallData(QObject* _owner, QVariantList&& _items): QObject(_owner), m_items(_items) {} + QCallData(QObject* _owner, QVariantList&& _items): QObject(_owner), m_items(std::move(_items)) {} private: QVariantList m_items; @@ -126,7 +126,7 @@ class QDebugData: public QObject public: QDebugData() { } - void setStates(QVariantList&& _states) { m_states = _states; } + void setStates(QVariantList&& _states) { m_states = std::move(_states); } private: QVariantList m_states; diff --git a/mix/HttpServer.h b/mix/HttpServer.h index 50a345747..606fa4ff1 100644 --- a/mix/HttpServer.h +++ b/mix/HttpServer.h @@ -46,7 +46,7 @@ class HttpRequest: public QObject private: HttpRequest(QObject* _parent, QUrl&& _url, QString&& _content, QVariantMap&& _headers): - QObject(_parent), m_url(_url), m_content(_content), m_headers(_headers) + QObject(_parent), m_url(std::move(_url)), m_content(std::move(_content)), m_headers(std::move(_headers)) { } diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 0b1c7c44f..8373c7c51 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -303,22 +303,15 @@ State MixClient::asOf(h256 const& _block) const return ret; } -void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, bool _gasAuto) +pair MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto) { WriteGuard l(x_state); - u256 n = m_state.transactionsFrom(toAddress(_secret)); - Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); + TransactionSkeleton ts = _ts; + ts.from = toAddress(_secret); + ts.nonce = m_state.transactionsFrom(ts.from); + eth::Transaction t(ts, _secret); executeTransaction(t, m_state, false, _gasAuto, _secret); -} - -Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto) -{ - WriteGuard l(x_state); - u256 n = m_state.transactionsFrom(toAddress(_secret)); - eth::Transaction t(_endowment, _gasPrice, _gas, _init, n, _secret); - executeTransaction(t, m_state, false, _gasAuto, _secret); - Address address = right160(sha3(rlpList(t.sender(), t.nonce()))); - return address; + return make_pair(t.sha3(), toAddress(ts.from, ts.nonce)); } dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff) @@ -335,16 +328,6 @@ dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Add return lastExecution().result; } -void MixClient::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) -{ - submitTransaction(_secret, _value, _dest, _data, _gas, _gasPrice, false); -} - -Address MixClient::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) -{ - return submitTransaction(_secret, _endowment, _init, _gas, _gasPrice, false); -} - dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, eth::FudgeFactor _ff) { return call(_from, _value, _dest, _data, _gas, _gasPrice, _blockNumber, false, _ff); diff --git a/mix/MixClient.h b/mix/MixClient.h index 1172bffbd..f9574e90a 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -54,14 +54,12 @@ public: ExecutionResult lastExecution() const; ExecutionResult execution(unsigned _index) const; - void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) override; - Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice) override; dev::eth::ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override; dev::eth::ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * eth::szabo, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override; using ClientBase::submitTransaction; - void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, bool _gasAuto); - Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice, bool _gasAuto); + virtual std::pair submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret) override { return submitTransaction(_ts, _secret, false); } + std::pair submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto); dev::eth::ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber, bool _gasAuto, eth::FudgeFactor _ff = eth::FudgeFactor::Strict); void setAddress(Address _us) override; @@ -78,6 +76,9 @@ public: using Interface::blockInfo; // to remove warning about hiding virtual function eth::BlockInfo blockInfo() const; + /// return the new address generated by the last tr (if creation). returns empty address if other cases. + Address lastCreatedContractAddr() const; + protected: /// ClientBase methods using ClientBase::asOf; diff --git a/mix/qml.qrc b/mix/qml.qrc index 16bb01b83..34295b022 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -69,5 +69,7 @@ qml/ScenarioExecution.qml qml/ScenarioLoader.qml qml/ScenarioButton.qml + qml/Watchers.qml + qml/KeyValuePanel.qml diff --git a/mix/qml/Block.qml b/mix/qml/Block.qml index 75d34a766..732166628 100644 --- a/mix/qml/Block.qml +++ b/mix/qml/Block.qml @@ -22,6 +22,7 @@ ColumnLayout property int blockIndex property variant scenario property string labelColor: "#414141" + signal txSelected(var txIndex) function calculateHeight() { @@ -36,6 +37,14 @@ ColumnLayout return trHeight } + function editTx(txIndex) + { + transactionDialog.stateAccounts = scenario.accounts + transactionDialog.execute = false + transactionDialog.editMode = true + transactionDialog.open(txIndex, blockIndex, transactions.get(txIndex)) + } + onOpenedTrChanged: { Layout.preferredHeight = calculateHeight() @@ -156,11 +165,11 @@ ColumnLayout Image { anchors.top: parent.top anchors.left: parent.left - anchors.leftMargin: -9 - anchors.topMargin: -9 + anchors.leftMargin: -4 + anchors.topMargin: 0 id: saveStatusImage source: "qrc:/qml/img/recyclediscard@2x.png" - width: statusWidth + 20 + width: statusWidth + 10 fillMode: Image.PreserveAspectFit } @@ -194,185 +203,125 @@ ColumnLayout Rectangle { Layout.preferredWidth: blockWidth - Layout.preferredHeight: parent.height + Layout.preferredHeight: trHeight + height: trHeight color: "#DEDCDC" id: rowContentTr anchors.top: parent.top + property bool selected: false + Connections + { + target: blockChainPanel + onTxSelected: { + if (root.blockIndex !== blockIndex || index !== txIndex) + rowContentTr.deselect() + } + } + + function deselect() + { + rowContentTr.selected = false + rowContentTr.color = "#DEDCDC" + hash.color = labelColor + func.color = labelColor + } + MouseArea { anchors.fill: parent + onClicked: { + if (!rowContentTr.selected) + { + rowContentTr.selected = true + rowContentTr.color = "#4F4F4F" + hash.color = "#EAB920" + func.color = "#EAB920" + txSelected(index) + } + else + rowContentTr.deselect() + + } onDoubleClicked: { - transactionDialog.stateAccounts = scenario.accounts - transactionDialog.execute = false - transactionDialog.open(index, blockIndex, transactions.get(index)) + root.editTx(index) } } - ColumnLayout + RowLayout { - anchors.top: parent.top - width: parent.width - spacing: 20 - RowLayout + Layout.fillWidth: true + Layout.preferredHeight: trHeight - 10 + anchors.verticalCenter: parent.verticalCenter + Rectangle { - anchors.top: parent.top - Layout.fillWidth: true - Rectangle + Layout.preferredWidth: fromWidth + anchors.left: parent.left + anchors.leftMargin: horizontalMargin + Text { - Layout.preferredWidth: fromWidth - anchors.left: parent.left - anchors.leftMargin: horizontalMargin - Text - { - id: hash - width: parent.width - 30 - elide: Text.ElideRight - anchors.verticalCenter: parent.verticalCenter - maximumLineCount: 1 - color: labelColor - font.pointSize: dbgStyle.absoluteSize(1) - font.bold: true - text: { - if (index >= 0) - return transactions.get(index).sender - else - return "" - } - } - } - - Rectangle - { - Layout.preferredWidth: toWidth - Text - { - id: func - text: { - if (index >= 0) - parent.parent.userFrienldyToken(transactions.get(index).label) - else - return "" - } - elide: Text.ElideRight - anchors.verticalCenter: parent.verticalCenter - color: labelColor - font.pointSize: dbgStyle.absoluteSize(1) - font.bold: true - maximumLineCount: 1 - width: parent.width - } - } - - function userFrienldyToken(value) - { - if (value && value.indexOf("<") === 0) - { - if (value.split("> ")[1] === " - ") - return value.split(" - ")[0].replace("<", "") + id: hash + width: parent.width - 30 + elide: Text.ElideRight + anchors.verticalCenter: parent.verticalCenter + maximumLineCount: 1 + color: labelColor + font.pointSize: dbgStyle.absoluteSize(1) + font.bold: true + text: { + if (index >= 0) + return clientModel.resolveAddress(transactions.get(index).sender) else - return value.split(" - ")[0].replace("<", "") + "." + value.split("> ")[1] + "()"; - } - else - return value - } - - Rectangle - { - Layout.preferredWidth: valueWidth - Text - { - id: returnValue - elide: Text.ElideRight - anchors.verticalCenter: parent.verticalCenter - maximumLineCount: 1 - color: labelColor - font.bold: true - font.pointSize: dbgStyle.absoluteSize(1) - width: parent.width - 30 - text: { - if (index >= 0 && transactions.get(index).returned) - return transactions.get(index).returned - else - return "" - } + return "" } } + } - Rectangle + Rectangle + { + Layout.preferredWidth: toWidth + Text { - Layout.preferredWidth: logsWidth - Layout.preferredHeight: trHeight - 10 - width: logsWidth - color: "transparent" - Text - { - id: logs - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: 10 - color: labelColor - font.bold: true - font.pointSize: dbgStyle.absoluteSize(1) - text: { - if (index >= 0 && transactions.get(index).logs && transactions.get(index).logs.count) - return transactions.get(index).logs.count - else - return "" - } - } - MouseArea { - anchors.fill: parent - onClicked: { - rowTransaction.displayContent(); - } + id: func + text: { + if (index >= 0) + parent.parent.userFrienldyToken(transactions.get(index).label) + else + return "" } + elide: Text.ElideRight + anchors.verticalCenter: parent.verticalCenter + color: labelColor + font.pointSize: dbgStyle.absoluteSize(1) + font.bold: true + maximumLineCount: 1 + width: parent.width } } - RowLayout + function userFrienldyToken(value) { - id: rowDetailedContent - visible: false - Layout.preferredHeight:{ - if (index >= 0 && transactions.get(index).logs) - return 100 * transactions.get(index).logs.count - else - return 100 - } - onVisibleChanged: + if (value && value.indexOf("<") === 0) { - var lognb = transactions.get(index).logs.count - if (visible) - { - rowContentTr.Layout.preferredHeight = trHeight + 100 * lognb - openedTr += 100 * lognb - } + if (value.split("> ")[1] === " - ") + return value.split(" - ")[0].replace("<", "") else - { - rowContentTr.Layout.preferredHeight = trHeight - openedTr -= 100 * lognb - } + return value.split(" - ")[0].replace("<", "") + "." + value.split("> ")[1] + "()"; } - - Text { - anchors.left: parent.left - anchors.leftMargin: horizontalMargin - id: logsText - } - } + else + return value + } } } Rectangle { width: debugActionWidth - height: trHeight - anchors.left: rowContentTr.right - anchors.topMargin: -6 + height: trHeight - 10 + anchors.right: rowContentTr.right anchors.top: rowContentTr.top - anchors.leftMargin: -50 + anchors.rightMargin: 10 color: "transparent" Image { @@ -380,7 +329,6 @@ ColumnLayout source: "qrc:/qml/img/rightarrow@2x.png" width: debugActionWidth fillMode: Image.PreserveAspectFit - anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter visible: transactions.get(index).recordIndex !== undefined } diff --git a/mix/qml/BlockChain.qml b/mix/qml/BlockChain.qml index 02ff72be2..ccc027444 100644 --- a/mix/qml/BlockChain.qml +++ b/mix/qml/BlockChain.qml @@ -13,12 +13,18 @@ import "." ColumnLayout { id: blockChainPanel + property alias trDialog: transactionDialog + property alias blockChainRepeater: blockChainRepeater property variant model + property var states: ({}) spacing: 0 property int previousWidth property variant debugTrRequested: [] signal chainChanged signal chainReloaded + signal txSelected(var blockIndex, var txIndex) + signal rebuilding + signal accountAdded(string address, string amount) Connections { @@ -40,20 +46,23 @@ ColumnLayout { var minWidth = scenarioMinWidth - 20 // margin if (width <= minWidth || previousWidth <= minWidth) { - fromWidth = 100 - toWidth = 100 - valueWidth = 200 + fromWidth = 250 + toWidth = 240 } else { var diff = (width - previousWidth) / 3; - fromWidth = fromWidth + diff < 100 ? 100 : fromWidth + diff - toWidth = toWidth + diff < 100 ? 100 : toWidth + diff - valueWidth = valueWidth + diff < 200 ? 200 : valueWidth + diff + fromWidth = fromWidth + diff < 250 ? 250 : fromWidth + diff + toWidth = toWidth + diff < 240 ? 240 : toWidth + diff } previousWidth = width } + function getState(record) + { + return states[record] + } + function load(scenario) { if (!scenario) @@ -61,6 +70,7 @@ ColumnLayout { if (model) rebuild.startBlinking() model = scenario + states = [] blockModel.clear() for (var b in model.blocks) blockModel.append(model.blocks[b]) @@ -68,10 +78,8 @@ ColumnLayout { } property int statusWidth: 30 - property int fromWidth: 150 - property int toWidth: 100 - property int valueWidth: 200 - property int logsWidth: 40 + property int fromWidth: 250 + property int toWidth: 240 property int debugActionWidth: 40 property int horizontalMargin: 10 property int cellSpacing: 10 @@ -80,7 +88,7 @@ ColumnLayout { { id: header spacing: 0 - Layout.preferredHeight: 30 + Layout.preferredHeight: 24 Rectangle { Layout.preferredWidth: statusWidth @@ -91,12 +99,13 @@ ColumnLayout { anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter source: "qrc:/qml/img/recycleicon@2x.png" - width: statusWidth + 20 + width: statusWidth + 10 fillMode: Image.PreserveAspectFit } } Rectangle { + anchors.verticalCenter: parent.verticalCenter Layout.preferredWidth: fromWidth Label { @@ -109,21 +118,13 @@ ColumnLayout { Label { text: "To" + anchors.verticalCenter: parent.verticalCenter Layout.preferredWidth: toWidth + cellSpacing } Label - { - text: "Value" - Layout.preferredWidth: valueWidth + cellSpacing - } - Label - { - text: "Logs" - Layout.preferredWidth: logsWidth + cellSpacing - } - Label { text: "" + anchors.verticalCenter: parent.verticalCenter Layout.preferredWidth: debugActionWidth } } @@ -162,8 +163,22 @@ ColumnLayout { { id: blockChainRepeater model: blockModel + + function editTx(blockIndex, txIndex) + { + itemAt(blockIndex).editTx(txIndex) + } + Block { + Connections + { + target: block + onTxSelected: { + blockChainPanel.txSelected(index, txIndex) + } + } + id: block scenario: blockChainPanel.model Layout.preferredWidth: blockChainScrollView.width Layout.preferredHeight: @@ -248,6 +263,8 @@ ColumnLayout { Rectangle { Layout.preferredWidth: parent.width + Layout.preferredHeight: 70 + color: "transparent" RowLayout { anchors.horizontalCenter: parent.horizontalCenter @@ -270,7 +287,9 @@ ColumnLayout { { if (ensureNotFuturetime.running) return; + rebuilding() stopBlinking() + states = [] var retBlocks = []; var bAdded = 0; for (var j = 0; j < model.blocks.length; j++) @@ -316,7 +335,7 @@ ColumnLayout { blockModel.append(model.blocks[j]) ensureNotFuturetime.start() - clientModel.setupScenario(model); + clientModel.setupScenario(model); } buttonShortcut: "" sourceImg: "qrc:/qml/img/recycleicon@2x.png" @@ -346,6 +365,7 @@ ColumnLayout { var item = TransactionHelper.defaultTransaction() transactionDialog.stateAccounts = model.accounts transactionDialog.execute = true + transactionDialog.editMode = false transactionDialog.open(model.blocks[model.blocks.length - 1].transactions.length, model.blocks.length - 1, item) } width: 100 @@ -397,7 +417,6 @@ ColumnLayout { } else addNewBlock() - } function addNewBlock() @@ -410,7 +429,7 @@ ColumnLayout { height: 30 buttonShortcut: "" - sourceImg: "qrc:/qml/img/addblock@2x.png" + sourceImg: "qrc:/qml/img/newblock@2x.png" } } @@ -448,11 +467,13 @@ ColumnLayout { tr.recordIndex = _r.recordIndex tr.logs = _r.logs tr.sender = _r.sender + tr.returnParameters = _r.returnParameters var trModel = blockModel.getTransaction(blockIndex, trIndex) trModel.returned = _r.returned trModel.recordIndex = _r.recordIndex trModel.logs = _r.logs trModel.sender = _r.sender + trModel.returnParameters = _r.returnParameters blockModel.setTransaction(blockIndex, trIndex, trModel) return; } @@ -472,9 +493,15 @@ ColumnLayout { itemTr.sender = _r.sender itemTr.recordIndex = _r.recordIndex itemTr.logs = _r.logs + itemTr.returnParameters = _r.returnParameters model.blocks[model.blocks.length - 1].transactions.push(itemTr) blockModel.appendTransaction(itemTr) } + + onNewState: { + states[_record] = _accounts + } + onMiningComplete: { } @@ -484,7 +511,12 @@ ColumnLayout { id: newAccount text: qsTr("New Account..") onClicked: { - model.accounts.push(projectModel.stateListModel.newAccount("1000000", QEther.Ether)) + var ac = projectModel.stateListModel.newAccount("O", QEther.Wei) + model.accounts.push(ac) + clientModel.addAccount(ac.secret); + for (var k in Object.keys(blockChainPanel.states)) + blockChainPanel.states[k].accounts["0x" + ac.address] = "0 wei" // add the account in all the previous state (balance at O) + accountAdded(ac.address, "0") } Layout.preferredWidth: 100 Layout.preferredHeight: 30 diff --git a/mix/qml/KeyValuePanel.qml b/mix/qml/KeyValuePanel.qml new file mode 100644 index 000000000..056384b9e --- /dev/null +++ b/mix/qml/KeyValuePanel.qml @@ -0,0 +1,134 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Dialogs 1.1 +import QtQuick.Layouts 1.1 +import Qt.labs.settings 1.0 +import org.ethereum.qml.QEther 1.0 +import "js/Debugger.js" as Debugger +import "js/ErrorLocationFormater.js" as ErrorLocationFormater +import "js/TransactionHelper.js" as TransactionHelper +import "js/QEtherHelper.js" as QEtherHelper +import "." + +ColumnLayout { + id: root + property alias title: titleLabel.text + property variant _data + property string role + property alias model: modelKeyValue + + function add(key, value) + { + modelKeyValue.append({ "key": key, "value": value }) + } + + function clear() + { + modelKeyValue.clear() + } + + function init() + { + modelKeyValue.clear() + if (typeof(computeData) !== "undefined" && computeData instanceof Function) + computeData() + else + { + if (_data !== undefined && _data[role] !== undefined) + { + var keys = Object.keys(_data[role]) + for (var k in keys) + { + modelKeyValue.append({ "key": keys[k] === "" ? "undefined" : keys[k], "value": _data[role][keys[k]] }) + } + } + } + } + + RowLayout + { + Layout.preferredHeight: 20 + Layout.fillWidth: true + Label + { + id: titleLabel + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + color: "white" + } + } + + RowLayout + { + Layout.fillWidth: true + Layout.preferredHeight: 100 + ListModel + { + id: modelKeyValue + } + + Rectangle + { + Layout.fillWidth: true + Layout.fillHeight: true + color: "white" + radius: 2 + ScrollView + { + id: columnValues + horizontalScrollBarPolicy: Qt.ScrollBarAlwaysOff + anchors.fill: parent + clip: true + ColumnLayout + { + anchors.margins: 10 + Repeater + { + id: repeaterKeyValue + model: modelKeyValue + RowLayout + { + Layout.fillWidth: true + Layout.preferredHeight: 30 + spacing: 0 + Rectangle + { + Layout.preferredWidth: columnValues.width / 2 + Label + { + anchors.left: parent.left + anchors.leftMargin: 10 + text: { + if (index >= 0 && repeaterKeyValue.model.get(index).key !== undefined) + return repeaterKeyValue.model.get(index).key + else + return "" + } + } + } + + Rectangle + { + Layout.preferredWidth: columnValues.width / 2 - 10 + Label + { + anchors.right: parent.right + anchors.rightMargin: 10 + text: { + if (index >= 0 && repeaterKeyValue.model.get(index).value !== undefined) + return repeaterKeyValue.model.get(index).value + else + return "" + } + } + } + } + } + } + + } + } + } +} + diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index 7f180a899..376135695 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -31,7 +31,7 @@ Rectangle { property alias codeEditor: codeEditor property bool webViewHorizontal: codeWebSplitter.orientation === Qt.Vertical //vertical splitter positions elements vertically, splits screen horizontally property bool firstCompile: true - property int scenarioMinWidth: 590 + property int scenarioMinWidth: 620 Connections { target: codeModel diff --git a/mix/qml/ScenarioExecution.qml b/mix/qml/ScenarioExecution.qml index 3e9d8e089..687c8e99f 100644 --- a/mix/qml/ScenarioExecution.qml +++ b/mix/qml/ScenarioExecution.qml @@ -8,6 +8,7 @@ import "js/Debugger.js" as Debugger import "js/ErrorLocationFormater.js" as ErrorLocationFormater import "." + Rectangle { color: "#ededed" property alias bc: blockChain @@ -18,50 +19,109 @@ Rectangle { onProjectLoaded: { loader.init() } - } - Column + ScrollView { - anchors.margins: 10 anchors.fill: parent - spacing: 10 - ScenarioLoader - { - height: 100 - width: parent.width - id: loader + onWidthChanged: { + columnExe.width = width - 40 } - Connections + ColumnLayout { - target: blockChain - onChainChanged: - { - loader.needSaveOrReload() - } - } + id: columnExe + Layout.preferredWidth: parent.width + width: parent.width - 40 + anchors.left: parent.left + anchors.leftMargin: 15 + ColumnLayout + { + id: scenarioColumn + width: parent.width + spacing: 10 + ScenarioLoader + { + anchors.horizontalCenter: parent.horizontalCenter + height: 100 + Layout.preferredWidth: 400 + width: 400 + id: loader + } - Rectangle - { - width: parent.parent.width - height: 1 - color: "#cccccc" - } + Connections + { + target: blockChain + onChainChanged: + { + loader.needSaveOrReload() + } + } - Connections - { - target: loader - onLoaded: + Rectangle + { + Layout.preferredWidth: parent.width + height: 1 + color: "#cccccc" + } + + Connections + { + target: loader + onLoaded: + { + watchers.clear() + blockChain.load(scenario) + } + } + + BlockChain + { + id: blockChain + width: parent.width + } + + Connections + { + target: blockChain + property var currentSelectedBlock + property var currentSelectedTx + onTxSelected: { + currentSelectedBlock = blockIndex + currentSelectedTx = txIndex + updateWatchers(blockIndex, txIndex) + } + + function updateWatchers(blockIndex, txIndex){ + var tx = blockChain.model.blocks[blockIndex].transactions[txIndex] + var state = blockChain.getState(tx.recordIndex) + watchers.updateWidthTx(tx, state, blockIndex, txIndex) + } + + onRebuilding: { + watchers.clear() + } + + onAccountAdded: { + watchers.addAccount(address, "0 wei") + } + } + } + + Watchers { - blockChain.load(scenario) + id: watchers + bc: blockChain + Layout.fillWidth: true + Layout.preferredHeight: 740 } - } - BlockChain - { - id: blockChain - width: parent.width + Rectangle + { + color: "transparent" + Layout.preferredHeight: 50 + Layout.fillWidth: true + } } } } diff --git a/mix/qml/ScenarioLoader.qml b/mix/qml/ScenarioLoader.qml index bc26b103d..58247b213 100644 --- a/mix/qml/ScenarioLoader.qml +++ b/mix/qml/ScenarioLoader.qml @@ -107,11 +107,13 @@ ColumnLayout Rectangle { id: editIconRect + anchors.top: scenarioName.top + anchors.topMargin: 6 anchors.left: scenarioName.right - anchors.leftMargin: 15 + anchors.leftMargin: 20 Image { - source: "qrc:/qml/img/edit.png" - width: 10 + source: "qrc:/qml/img/edittransaction.png" + width: 30 fillMode: Image.PreserveAspectFit anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter @@ -126,7 +128,6 @@ ColumnLayout scenarioNameEdit.save() else scenarioNameEdit.edit() - } } } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index 992113cc6..d3bf1c860 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -257,7 +257,8 @@ Item { _secret = clientModel.newSecret(); var address = clientModel.address(_secret); var name = qsTr("Account") + "-" + address.substring(0, 4); - return { name: name, secret: _secret, balance: QEtherHelper.createEther(_balance, _unit), address: address }; + var amount = QEtherHelper.createEther(_balance, _unit) + return { name: name, secret: _secret, balance: amount, address: address }; } function duplicateState(index) diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index f4aa9a5f0..4edc601de 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -16,7 +16,8 @@ Dialog { width: 580 height: 500 visible: false - title: qsTr("Edit Transaction") + title: editMode ? qsTr("Edit Transaction") : qsTr("Add Transaction") + property bool editMode property int transactionIndex property int blockIndex property alias gas: gasValueEdit.gasValue; @@ -390,7 +391,7 @@ Dialog { objectName: "trTypeExecute" exclusiveGroup: rbbuttonList height: 30 - text: qsTr("Execute Contract") + text: qsTr("Transact with Contract") } } } @@ -687,7 +688,7 @@ Dialog { } Button { - text: qsTr("Update"); + text: editMode ? qsTr("Update") : qsTr("Ok") onClicked: { var invalid = InputValidator.validate(paramsModel, paramValues); if (invalid.length === 0) diff --git a/mix/qml/Watchers.qml b/mix/qml/Watchers.qml new file mode 100644 index 000000000..9625d9424 --- /dev/null +++ b/mix/qml/Watchers.qml @@ -0,0 +1,203 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.1 +import QtQuick.Controls.Styles 1.1 +import QtQuick.Dialogs 1.1 +import QtQuick.Layouts 1.1 +import Qt.labs.settings 1.0 +import org.ethereum.qml.QEther 1.0 +import "js/Debugger.js" as Debugger +import "js/ErrorLocationFormater.js" as ErrorLocationFormater +import "js/TransactionHelper.js" as TransactionHelper +import "js/QEtherHelper.js" as QEtherHelper +import "." + +Rectangle { + color: "#4F4F4F" + radius: 4 + property variant tx + property variant currentState + property variant bc + property var blockIndex + property var txIndex + + function clear() + { + from.text = "" + to.text = "" + value.text = "" + inputParams.clear() + returnParams.clear() + accounts.clear() + events.clear() + } + + function addAccount(address, amount) + { + accounts.add(address, amount) + } + + function updateWidthTx(_tx, _state, _blockIndex, _txIndex) + { + from.text = clientModel.resolveAddress(_tx.sender) + to.text = _tx.label + value.text = _tx.value.format() + tx = _tx + blockIndex = _blockIndex + txIndex = _txIndex + currentState = _state + inputParams.init() + if (_tx.isContractCreation) + { + returnParams.role = "creationAddr" + returnParams._data = { + creationAddr : { + } + } + returnParams._data.creationAddr[qsTr("contract address")] = _tx.returned + } + else + { + returnParams.role = "returnParameters" + returnParams._data = tx + } + returnParams.init() + accounts.init() + events.init() + } + + Column { + anchors.fill: parent + spacing: 15 + Rectangle + { + height: 15 + width: parent.width - 30 + color: "transparent" + Row + { + id: rowHeader + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: rowHeader.parent.top + anchors.topMargin: 6 + spacing: 5 + Label { + id: fromLabel + text: qsTr("from") + visible: from.text !== "" + color: "#EAB920" + } + Label { + id: from + color: "#EAB920" + elide: Text.ElideRight + maximumLineCount: 1 + clip: true + width: 200 + } + Label { + id: toLabel + text: qsTr("to") + visible: from.text !== "" + color: "#EAB920" + } + Label { + id: to + color: "#EAB920" + elide: Text.ElideRight + maximumLineCount: 1 + clip: true + width: 100 + } + Label { + id: value + color: "#EAB920" + font.italic: true + clip: true + } + } + + Image { + anchors.right: rowHeader.parent.right + anchors.top: rowHeader.parent.top + anchors.topMargin: -3 + source: "qrc:/qml/img/edittransaction2.png" + height: 30 + fillMode: Image.PreserveAspectFit + visible: from.text !== "" + MouseArea + { + anchors.fill: parent + onClicked: + { + bc.blockChainRepeater.editTx(blockIndex, txIndex) + } + } + } + } + + Rectangle { + height: 1 + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + border.color: "#cccccc" + border.width: 1 + } + + KeyValuePanel + { + height: 150 + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + id: inputParams + title: qsTr("INPUT PARAMETERS") + role: "parameters" + _data: tx + } + + KeyValuePanel + { + height: 150 + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + id: returnParams + title: qsTr("RETURN PARAMETERS") + role: "returnParameters" + _data: tx + } + + KeyValuePanel + { + height: 150 + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + id: accounts + title: qsTr("ACCOUNTS") + role: "accounts" + _data: currentState + } + + KeyValuePanel + { + height: 150 + width: parent.width - 30 + anchors.horizontalCenter: parent.horizontalCenter + id: events + title: qsTr("EVENTS") + function computeData() + { + model.clear() + var ret = [] + for (var k in tx.logs) + { + var param = "" + for (var p in tx.logs[k].param) + { + param += " " + tx.logs[k].param[p].value + " " + } + param = "(" + param + ")" + model.append({ "key": tx.logs[k].name, "value": param }) + } + } + } + } +} diff --git a/mix/res.qrc b/mix/res.qrc index b50aa3d9f..c868ff34b 100644 --- a/mix/res.qrc +++ b/mix/res.qrc @@ -90,5 +90,10 @@ qml/img/saveicon@2x.png qml/img/sendtransactionicon.png qml/img/sendtransactionicon@2x.png + qml/img/edittransaction@2x.png + qml/img/newblock@2x.png + qml/img/edittransaction2@2x.png + qml/img/edittransaction.png + qml/img/edittransaction2.png diff --git a/neth/main.cpp b/neth/main.cpp index a55c3d559..5ec253440 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -101,7 +101,7 @@ void help() << " -x,--peers Attempt to connect to given number of peers (default: 5)." << endl << " -V,--version Show the version and exit." << endl #if ETH_EVMJIT - << " --jit Use EVM JIT (default: off)." << endl + << " --vm Select VM. Options are: interpreter, jit, smart. (default: interpreter)" << endl #endif ; exit(0); @@ -363,11 +363,7 @@ int main(int argc, char** argv) coinbase = config[1].toHash
(); } else - { - RLPStream config(2); - config << us.secret() << coinbase; - writeFile(configFile, config.out()); - } + writeFile(configFile, rlpList(us.secret(), coinbase)); for (int i = 1; i < argc; ++i) { @@ -514,15 +510,23 @@ int main(int argc, char** argv) return -1; } } - else if (arg == "--jit") - { #if ETH_EVMJIT - jit = true; -#else - cerr << "EVM JIT not enabled" << endl; - return -1; -#endif + else if (arg == "--vm" && i + 1 < argc) + { + string vmKind = argv[++i]; + if (vmKind == "interpreter") + VMFactory::setKind(VMKind::Interpreter); + else if (vmKind == "jit") + VMFactory::setKind(VMKind::JIT); + else if (vmKind == "smart") + VMFactory::setKind(VMKind::Smart); + else + { + cerr << "Unknown VM kind: " << vmKind << endl; + return -1; + } } +#endif else if (arg == "-h" || arg == "--help") help(); else if (arg == "-V" || arg == "--version") @@ -551,7 +555,7 @@ int main(int argc, char** argv) mode == NodeMode::Full ? set{"eth", "shh"} : set(), netPrefs, &nodesState); - + web3.setIdealPeerCount(peers); std::shared_ptr gasPricer = make_shared(u256(double(ether / 1000) / etherPrice), u256(blockFees * 1000)); eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; @@ -1053,9 +1057,7 @@ int main(int argc, char** argv) else if (gas < minGas) cwarn << "Minimum gas amount is" << minGas; else - { c->submitTransaction(us.secret(), endowment, init, gas); - } } } else if (c && cmd == "inspect") diff --git a/rlp/main.cpp b/rlp/main.cpp index 3924f9c44..8ff7202c3 100644 --- a/rlp/main.cpp +++ b/rlp/main.cpp @@ -49,6 +49,7 @@ void help() << "General options:" << endl << " -L,--lenience Try not to bomb out early if possible." << endl << " -x,--hex,--base-16 Treat input RLP as hex encoded data." << endl + << " -k,--keccak Output Keccak-256 hash only." << endl << " --64,--base-64 Treat input RLP as base-64 encoded data." << endl << " -b,--bin,--base-256 Treat input RLP as raw binary data." << endl << " -h,--help Print this help message and exit." << endl @@ -75,6 +76,7 @@ enum class Encoding { Hex, Base64, Binary, + Keccak, }; bool isAscii(string const& _s) @@ -111,9 +113,9 @@ public: m_out << "null"; else if (_d.isInt() && !m_prefs.stringInts) if (m_prefs.hexInts) - m_out << (m_prefs.hexPrefix ? "0x" : "") << toHex(toCompactBigEndian(_d.toInt(RLP::LaisezFaire), 1), 1); + m_out << (m_prefs.hexPrefix ? "0x" : "") << toHex(toCompactBigEndian(_d.toInt(RLP::LaissezFaire), 1), 1); else - m_out << _d.toInt(RLP::LaisezFaire); + m_out << _d.toInt(RLP::LaissezFaire); else if (_d.isData() || (_d.isInt() && m_prefs.stringInts)) if (m_prefs.forceString || (!m_prefs.forceHex && isAscii(_d.toString()))) m_out << escaped(_d.toString(), m_prefs.escapeAll); @@ -186,6 +188,8 @@ int main(int argc, char** argv) version(); else if (arg == "-x" || arg == "--hex" || arg == "--base-16") encoding = Encoding::Hex; + else if (arg == "-k" || arg == "--keccak") + encoding = Encoding::Keccak; else if (arg == "--64" || arg == "--base-64") encoding = Encoding::Base64; else if (arg == "-b" || arg == "--bin" || arg == "--base-256") @@ -371,6 +375,9 @@ int main(int argc, char** argv) case Encoding::Binary: cout.write((char const*)out.out().data(), out.out().size()); break; + case Encoding::Keccak: + cout << sha3(out.out()).hex() << endl; + break; } break; } diff --git a/solc/CMakeLists.txt b/solc/CMakeLists.txt index e60d3c8cf..df72f52dd 100644 --- a/solc/CMakeLists.txt +++ b/solc/CMakeLists.txt @@ -13,6 +13,8 @@ set(EXECUTABLE solc) file(GLOB HEADERS "*.h") add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) +add_dependencies(${EXECUTABLE} BuildInfo.h) + target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES}) target_link_libraries(${EXECUTABLE} ${Boost_PROGRAM_OPTIONS_LIBRARIES}) target_link_libraries(${EXECUTABLE} solidity) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index c95f34f62..00bf2ab33 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -81,9 +82,12 @@ static set const g_combinedJsonArgs{ static void version() { - cout << "solc, the solidity compiler commandline interface " << dev::Version << endl - << " by Christian and Lefteris , (c) 2014." << endl - << "Build: " << DEV_QUOTED(ETH_BUILD_PLATFORM) << "/" << DEV_QUOTED(ETH_BUILD_TYPE) << endl; + cout << + "solc, the solidity compiler commandline interface" << + endl << + "Version: " << + dev::solidity::VersionString << + endl; exit(0); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 952b1674f..cbf184808 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -72,6 +72,7 @@ add_executable(testeth ${SRC_LIST} ${HEADERS}) target_link_libraries(testeth ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) target_link_libraries(testeth ${CURL_LIBRARIES}) +target_link_libraries(testeth ${CRYPTOPP_LIBRARIES}) target_link_libraries(testeth ethereum) target_link_libraries(testeth ethcore) if (NOT WIN32) diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 698f35122..9a1b16935 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -199,10 +199,10 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state, stateOptio stateOptions.m_bHasCode = true; } - if (code.size()) + if (!code.empty()) { _state.m_cache[address] = Account(balance, Account::ContractConception); - _state.m_cache[address].setCode(code); + _state.m_cache[address].setCode(std::move(code)); } else _state.m_cache[address] = Account(balance, Account::NormalCreation); @@ -235,7 +235,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) } void ImportTest::importTransaction(json_spirit::mObject& _o) -{ +{ if (_o.count("secretKey") > 0) { assert(_o.count("nonce") > 0); @@ -728,10 +728,20 @@ Options::Options() for (auto i = 0; i < argc; ++i) { auto arg = std::string{argv[i]}; - if (arg == "--jit") - eth::VMFactory::setKind(eth::VMKind::JIT); - else if (arg == "--vm=smart") - eth::VMFactory::setKind(eth::VMKind::Smart); + if (arg == "--vm" && i + 1 < argc) + { + string vmKind = argv[++i]; + if (vmKind == "interpreter") + VMFactory::setKind(VMKind::Interpreter); + else if (vmKind == "jit") + VMFactory::setKind(VMKind::JIT); + else if (vmKind == "smart") + VMFactory::setKind(VMKind::Smart); + else + cerr << "Unknown VM kind: " << vmKind << endl; + } + else if (arg == "--jit") // TODO: Remove deprecated option "--jit" + VMFactory::setKind(VMKind::JIT); else if (arg == "--vmtrace") vmtrace = true; else if (arg == "--filltests") diff --git a/test/TestHelper.h b/test/TestHelper.h index 1c1dfb5f0..4ac59e917 100644 --- a/test/TestHelper.h +++ b/test/TestHelper.h @@ -188,6 +188,7 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin); void doStateTests(json_spirit::mValue& v, bool _fillin); void doVMTests(json_spirit::mValue& v, bool _fillin); void doBlockchainTests(json_spirit::mValue& _v, bool _fillin); +void doRlpTests(json_spirit::mValue& v, bool _fillin); template void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs) diff --git a/test/fuzzTesting/createRandomTest.cpp b/test/fuzzTesting/createRandomTest.cpp index b4a00440e..c26c9b7f7 100644 --- a/test/fuzzTesting/createRandomTest.cpp +++ b/test/fuzzTesting/createRandomTest.cpp @@ -220,6 +220,7 @@ void parseTestWithTypes(std::string& _test) options.setWeight(dev::eth::Instruction::STOP, 10); //default 50 options.setWeight(dev::eth::Instruction::SSTORE, 70); options.setWeight(dev::eth::Instruction::CALL, 75); + options.setWeight(dev::eth::Instruction::CALLCODE, 55); options.addAddress(dev::Address("0xffffffffffffffffffffffffffffffffffffffff")); options.addAddress(dev::Address("0x1000000000000000000000000000000000000000")); options.addAddress(dev::Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87")); @@ -230,7 +231,7 @@ void parseTestWithTypes(std::string& _test) options.addAddress(dev::Address("0x0000000000000000000000000000000000000002")); options.addAddress(dev::Address("0x0000000000000000000000000000000000000003")); options.addAddress(dev::Address("0x0000000000000000000000000000000000000004")); - options.smartCodeProbability = 35; + options.smartCodeProbability = 60; std::vector types = getTypes(); for (unsigned i = 0; i < types.size(); i++) diff --git a/test/fuzzTesting/fuzzHelper.cpp b/test/fuzzTesting/fuzzHelper.cpp index 8e03bd767..b6a3bd700 100644 --- a/test/fuzzTesting/fuzzHelper.cpp +++ b/test/fuzzTesting/fuzzHelper.cpp @@ -74,7 +74,7 @@ std::string RandomCode::generate(int _maxOpNumber, RandomCodeOptions _options) uint8_t opcode = weightsDefined ? randOpCodeWeight() : randOpCodeGen(); dev::eth::InstructionInfo info = dev::eth::instructionInfo((dev::eth::Instruction) opcode); - if (info.name.find_first_of("INVALID_INSTRUCTION") > 0) + if (info.name.find("INVALID_INSTRUCTION") != std::string::npos) { //Byte code is yet not implemented if (_options.useUndefinedOpCodes == false) @@ -84,9 +84,17 @@ std::string RandomCode::generate(int _maxOpNumber, RandomCodeOptions _options) } } else + { + if (info.name.find("PUSH") != std::string::npos) + code += toCompactHex(opcode); code += fillArguments((dev::eth::Instruction) opcode, _options); - std::string byte = toCompactHex(opcode); - code += (byte == "") ? "00" : byte; + } + + if (info.name.find("PUSH") == std::string::npos) + { + std::string byte = toCompactHex(opcode); + code += (byte == "") ? "00" : byte; + } } return code; } @@ -141,18 +149,59 @@ std::string RandomCode::fillArguments(dev::eth::Instruction _opcode, RandomCodeO if (smart) { + //PUSH1 ... PUSH32 + if (dev::eth::Instruction::PUSH1 <= _opcode && _opcode <= dev::eth::Instruction::PUSH32) + { + code += rndByteSequence(int(_opcode) - int(dev::eth::Instruction::PUSH1) + 1); + return code; + } + + //SWAP1 ... SWAP16 || DUP1 ... DUP16 + bool isSWAP = (dev::eth::Instruction::SWAP1 <= _opcode && _opcode <= dev::eth::Instruction::SWAP16); + bool isDUP = (dev::eth::Instruction::DUP1 <= _opcode && _opcode <= dev::eth::Instruction::DUP16); + + if (isSWAP || isDUP) + { + int times = 0; + if (isSWAP) + times = int(_opcode) - int(dev::eth::Instruction::SWAP1) + 2; + else + if (isDUP) + times = int(_opcode) - int(dev::eth::Instruction::DUP1) + 1; + + for (int i = 0; i < times; i ++) + code += getPushCode(randUniIntGen() % 32); + + return code; + } + switch (_opcode) { + case dev::eth::Instruction::CREATE: + //(CREATE value mem1 mem2) + code += getPushCode(randUniIntGen() % 128); //memlen1 + code += getPushCode(randUniIntGen() % 32); //memlen1 + code += getPushCode(randUniIntGen()); //value + break; case dev::eth::Instruction::CALL: + case dev::eth::Instruction::CALLCODE: //(CALL gaslimit address value memstart1 memlen1 memstart2 memlen2) - code += getPushCode(randUniIntGen() % 32); //memlen2 + //(CALLCODE gaslimit address value memstart1 memlen1 memstart2 memlen2) + code += getPushCode(randUniIntGen() % 128); //memlen2 code += getPushCode(randUniIntGen() % 32); //memstart2 - code += getPushCode(randUniIntGen() % 32); //memlen1 + code += getPushCode(randUniIntGen() % 128); //memlen1 code += getPushCode(randUniIntGen() % 32); //memlen1 code += getPushCode(randUniIntGen()); //value code += getPushCode(toString(_options.getRandomAddress()));//address code += getPushCode(randUniIntGen()); //gaslimit break; + case dev::eth::Instruction::SUICIDE: //(SUICIDE address) + code += getPushCode(toString(_options.getRandomAddress())); + break; + case dev::eth::Instruction::RETURN: //(RETURN memlen1 memlen2) + code += getPushCode(randUniIntGen() % 128); //memlen1 + code += getPushCode(randUniIntGen() % 32); //memlen1 + break; default: smart = false; } diff --git a/test/libdevcore/FixedHash.cpp b/test/libdevcore/FixedHash.cpp new file mode 100644 index 000000000..dc5ced2c1 --- /dev/null +++ b/test/libdevcore/FixedHash.cpp @@ -0,0 +1,146 @@ +/* + 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 FixedHash.cpp + * @author Lefterus + * @date 2015 + */ + +#include +#include "../TestHelper.h" + +using namespace std; +using namespace dev; + +namespace dev +{ +namespace test +{ + +BOOST_AUTO_TEST_SUITE(FixedHashTests) + +BOOST_AUTO_TEST_CASE(FixedHashComparisons) +{ + FixedHash<4> h1(sha3("abcd")); + FixedHash<4> h2(sha3("abcd")); + FixedHash<4> h3(sha3("aadd")); + FixedHash<4> h4(0xBAADF00D); + FixedHash<4> h5(0xAAAAAAAA); + FixedHash<4> h6(0xBAADF00D); + + BOOST_CHECK(h1 == h2); + BOOST_CHECK(h2 != h3); + + BOOST_CHECK(h4 > h5); + BOOST_CHECK(h5 < h4); + BOOST_CHECK(h6 <= h4); + BOOST_CHECK(h6 >= h4); +} + +BOOST_AUTO_TEST_CASE(FixedHashXOR) +{ + FixedHash<2> h1("0xAAAA"); + FixedHash<2> h2("0xBBBB"); + + BOOST_CHECK((h1 ^ h2) == FixedHash<2>("0x1111")); + h1 ^= h2; + BOOST_CHECK(h1 == FixedHash<2>("0x1111")); +} + +BOOST_AUTO_TEST_CASE(FixedHashOR) +{ + FixedHash<4> h1("0xD3ADB33F"); + FixedHash<4> h2("0xBAADF00D"); + FixedHash<4> res("0xFBADF33F"); + + BOOST_CHECK((h1 | h2) == res); + h1 |= h2; + BOOST_CHECK(h1 == res); +} + +BOOST_AUTO_TEST_CASE(FixedHashAND) +{ + FixedHash<4> h1("0xD3ADB33F"); + FixedHash<4> h2("0xBAADF00D"); + FixedHash<4> h3("0x92aDB00D"); + + BOOST_CHECK((h1 & h2) == h3); + h1 &= h2; + BOOST_CHECK(h1 = h3); +} + +BOOST_AUTO_TEST_CASE(FixedHashInvert) +{ + FixedHash<4> h1("0xD3ADB33F"); + FixedHash<4> h2("0x2C524CC0"); + + BOOST_CHECK(~h1 == h2); +} + +BOOST_AUTO_TEST_CASE(FixedHashContains) +{ + FixedHash<4> h1("0xD3ADB331"); + FixedHash<4> h2("0x0000B331"); + FixedHash<4> h3("0x0000000C"); + + BOOST_CHECK(h1.contains(h2)); + BOOST_CHECK(!h1.contains(h3)); +} + +void incrementSingleIteration(unsigned seed) +{ + unsigned next = seed + 1; + + FixedHash<4> h1(seed); + FixedHash<4> h2 = h1; + FixedHash<4> h3(next); + + FixedHash<32> hh1(seed); + FixedHash<32> hh2 = hh1; + FixedHash<32> hh3(next); + + BOOST_CHECK_EQUAL(++h2, h3); + BOOST_CHECK_EQUAL(++hh2, hh3); + + BOOST_CHECK(h2 > h1); + BOOST_CHECK(hh2 > hh1); + + unsigned reverse1 = ((FixedHash<4>::Arith)h2).convert_to(); + unsigned reverse2 = ((FixedHash<32>::Arith)hh2).convert_to(); + + BOOST_CHECK_EQUAL(next, reverse1); + BOOST_CHECK_EQUAL(next, reverse2); +} + +BOOST_AUTO_TEST_CASE(FixedHashIncrement) +{ + incrementSingleIteration(0); + incrementSingleIteration(1); + incrementSingleIteration(0xBAD); + incrementSingleIteration(0xBEEF); + incrementSingleIteration(0xFFFF); + incrementSingleIteration(0xFEDCBA); + incrementSingleIteration(0x7FFFFFFF); + + FixedHash<4> h(0xFFFFFFFF); + FixedHash<4> zero; + BOOST_CHECK_EQUAL(++h, zero); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} diff --git a/test/libdevcore/RangeMask.cpp b/test/libdevcore/RangeMask.cpp new file mode 100644 index 000000000..05f58963a --- /dev/null +++ b/test/libdevcore/RangeMask.cpp @@ -0,0 +1,148 @@ +/* + 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 RangeMask.cpp + * @author Christian + * @date 2015 + */ + +#include +#include "../TestHelper.h" + +using namespace std; +using namespace dev; + +namespace dev +{ +namespace test +{ + +BOOST_AUTO_TEST_SUITE(RangeMaskTest) + +BOOST_AUTO_TEST_CASE(constructor) +{ + using RM = RangeMask; + using Range = pair; + for (RM r: {RM(), RM(1, 10), RM(Range(2, 10))}) + { + BOOST_CHECK(r.empty()); + BOOST_CHECK(!r.contains(0)); + BOOST_CHECK(!r.contains(1)); + BOOST_CHECK_EQUAL(0, r.size()); + } + BOOST_CHECK(RM().full()); + BOOST_CHECK(!RM(1, 10).full()); + BOOST_CHECK(!RM(Range(2, 10)).full()); +} + +BOOST_AUTO_TEST_CASE(simple_unions) +{ + using RM = RangeMask; + using Range = pair; + RM m(Range(0, 2000)); + m.unionWith(Range(1, 2)); + BOOST_CHECK_EQUAL(m.size(), 1); + m.unionWith(Range(50, 250)); + BOOST_CHECK_EQUAL(m.size(), 201); + m.unionWith(Range(10, 16)); + BOOST_CHECK_EQUAL(m.size(), 207); + BOOST_CHECK(m.contains(1)); + BOOST_CHECK(m.contains(11)); + BOOST_CHECK(m.contains(51)); + BOOST_CHECK(m.contains(200)); + BOOST_CHECK(!m.contains(2)); + BOOST_CHECK(!m.contains(7)); + BOOST_CHECK(!m.contains(17)); + BOOST_CHECK(!m.contains(258)); +} + +BOOST_AUTO_TEST_CASE(empty_union) +{ + using RM = RangeMask; + using Range = pair; + RM m(Range(0, 2000)); + m.unionWith(Range(3, 6)); + BOOST_CHECK_EQUAL(m.size(), 3); + m.unionWith(Range(50, 50)); + BOOST_CHECK_EQUAL(m.size(), 3); + m.unionWith(Range(0, 0)); + BOOST_CHECK_EQUAL(m.size(), 3); + m.unionWith(Range(1, 1)); + BOOST_CHECK_EQUAL(m.size(), 3); + m.unionWith(Range(2, 2)); + BOOST_CHECK_EQUAL(m.size(), 3); + m.unionWith(Range(3, 3)); + BOOST_CHECK_EQUAL(m.size(), 3); +} + +BOOST_AUTO_TEST_CASE(overlapping_unions) +{ + using RM = RangeMask; + using Range = pair; + RM m(Range(0, 2000)); + m.unionWith(Range(10, 20)); + BOOST_CHECK_EQUAL(10, m.size()); + m.unionWith(Range(30, 40)); + BOOST_CHECK_EQUAL(20, m.size()); + m.unionWith(Range(15, 30)); + BOOST_CHECK_EQUAL(40 - 10, m.size()); + m.unionWith(Range(50, 60)); + m.unionWith(Range(45, 55)); + // [40, 45) still missing here + BOOST_CHECK_EQUAL(60 - 10 - 5, m.size()); + m.unionWith(Range(15, 56)); + BOOST_CHECK_EQUAL(60 - 10, m.size()); + m.unionWith(Range(15, 65)); + BOOST_CHECK_EQUAL(65 - 10, m.size()); + m.unionWith(Range(5, 70)); + BOOST_CHECK_EQUAL(70 - 5, m.size()); +} + +BOOST_AUTO_TEST_CASE(complement) +{ + using RM = RangeMask; + using Range = pair; + RM m(Range(0, 2000)); + m.unionWith(7).unionWith(9); + m = ~m; + m.unionWith(7).unionWith(9); + m = ~m; + BOOST_CHECK(m.empty()); + + m += Range(0, 10); + m += Range(1000, 2000); + m.invert(); + BOOST_CHECK_EQUAL(m.size(), 1000 - 10); +} + +BOOST_AUTO_TEST_CASE(iterator) +{ + using RM = RangeMask; + using Range = pair; + RM m(Range(0, 2000)); + m.unionWith(Range(7, 9)); + m.unionWith(11); + m.unionWith(Range(200, 205)); + + vector elements; + copy(m.begin(), m.end(), back_inserter(elements)); + BOOST_CHECK(elements == (vector{7, 8, 11, 200, 201, 202, 203, 204})); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} diff --git a/test/libdevcore/core.cpp b/test/libdevcore/core.cpp new file mode 100644 index 000000000..e7c7c86a1 --- /dev/null +++ b/test/libdevcore/core.cpp @@ -0,0 +1,41 @@ +/* + 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 core.cpp + * @author Dimitry Khokhlov + * @date 2014 + * CORE test functions. + */ + +#include +#include +#include + +BOOST_AUTO_TEST_SUITE(CoreLibTests) + +BOOST_AUTO_TEST_CASE(byteRef) +{ + cnote << "bytesRef copyTo and toString..."; + dev::bytes originalSequence = dev::fromHex("0102030405060708091011121314151617181920212223242526272829303132"); + dev::bytesRef out(&originalSequence.at(0), 32); + dev::h256 hash32("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"); + hash32.ref().copyTo(out); + + BOOST_CHECK_MESSAGE(out.size() == 32, "Error wrong result size when h256::ref().copyTo(dev::bytesRef out)"); + BOOST_CHECK_MESSAGE(out.toBytes() == originalSequence, "Error when h256::ref().copyTo(dev::bytesRef out)"); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libdevcore/rlp.cpp b/test/libdevcore/rlp.cpp index 86780cfa6..74e422b05 100644 --- a/test/libdevcore/rlp.cpp +++ b/test/libdevcore/rlp.cpp @@ -40,8 +40,125 @@ namespace js = json_spirit; namespace dev { namespace test - { - static void buildRLP(js::mValue& _v, RLPStream& _rlp) + { + void buildRLP(js::mValue& _v, RLPStream& _rlp); + void checkRLPAgainstJson(js::mValue& v, RLP& u); + enum class RlpType + { + Valid, + Invalid, + Test + }; + + void doRlpTests(json_spirit::mValue& v, bool _fillin) + { + for (auto& i: v.get_obj()) + { + js::mObject& o = i.second.get_obj(); + if (test::Options::get().singleTest && test::Options::get().singleTestName != i.first) + { + o.clear(); + continue; + } + + cout << " " << i.first << endl; + TBOOST_REQUIRE((o.count("out") > 0)); + TBOOST_REQUIRE((!o["out"].is_null())); + + if (_fillin) + { + try + { + bytes payloadToDecode = fromHex(o["out"].get_str()); + RLP payload(payloadToDecode); + if (payload.isEmpty()) + BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("Decoded Empty RLP!")); + o["in"] = "VALID"; + } + catch (Exception const& _e) + { + cnote << "Exception: " << diagnostic_information(_e); + o["in"] = "INVALID"; + } + catch (std::exception const& _e) + { + cnote << "rlp exception: " << _e.what(); + o["in"] = "INVALID"; + } + } + else + { + //Check Encode + TBOOST_REQUIRE((o.count("in") > 0)); + RlpType rlpType = RlpType::Test; + if (o["in"].type() == js::str_type) + { + if (o["in"].get_str() == "INVALID") + rlpType = RlpType::Invalid; + else if (o["in"].get_str() == "VALID") + rlpType = RlpType::Valid; + } + + if (rlpType == RlpType::Test) + { + RLPStream s; + dev::test::buildRLP(o["in"], s); + string computedText = toHex(s.out()); + + string expectedText(o["out"].get_str()); + transform(expectedText.begin(), expectedText.end(), expectedText.begin(), ::tolower ); + + stringstream msg; + msg << "Encoding Failed: expected: " << expectedText << std::endl; + msg << " But Computed: " << computedText; + TBOOST_CHECK_MESSAGE( + (expectedText == computedText), + msg.str() + ); + } + + //Check Decode + // Uses the same test cases as encoding but in reverse. + // We read into the string of hex values, convert to bytes, + // and then compare the output structure to the json of the + // input object. + bool was_exception = false; + js::mValue& inputData = o["in"]; + try + { + bytes payloadToDecode = fromHex(o["out"].get_str()); + RLP payload(payloadToDecode); + + if (rlpType == RlpType::Test) + dev::test::checkRLPAgainstJson(inputData, payload); + } + catch (Exception const& _e) + { + cnote << "Exception: " << diagnostic_information(_e); + was_exception = true; + } + catch (exception const& _e) + { + cnote << "rlp exception: " << _e.what(); + was_exception = true; + } + + //Expect exception as input is INVALID + if (rlpType == RlpType::Invalid && was_exception) + continue; + + //Check that there was an exception as input is INVALID + if (rlpType == RlpType::Invalid && !was_exception) + TBOOST_ERROR("Expected RLP Exception as rlp should be invalid!"); + + //input is VALID check that there was no exceptions + if (was_exception) + TBOOST_ERROR("Unexpected RLP Exception!"); + } + } + } + + void buildRLP(js::mValue& _v, RLPStream& _rlp) { if (_v.type() == js::array_type) { @@ -62,67 +179,46 @@ namespace dev } } - static void getRLPTestCases(js::mValue& v) - { - string testPath = getTestPath(); - testPath += "/BasicTests"; - - string s = contentsString(testPath + "/rlptest.json"); - BOOST_REQUIRE_MESSAGE( s.length() > 0, - "Contents of 'rlptest.json' is empty. Have you cloned the 'tests' repo branch develop?"); - js::read_string(s, v); - } - - static void checkRLPTestCase(js::mObject& o) - { - BOOST_REQUIRE( o.count("in") > 0 ); - BOOST_REQUIRE( o.count("out") > 0 ); - BOOST_REQUIRE(!o["out"].is_null()); - } - - static void checkRLPAgainstJson(js::mValue& v, RLP& u) + void checkRLPAgainstJson(js::mValue& v, RLP& u) { if ( v.type() == js::str_type ) { - const std::string& expectedText = v.get_str(); + const string& expectedText = v.get_str(); if ( !expectedText.empty() && expectedText.front() == '#' ) { // Deal with bigint instead of a raw string - std::string bigIntStr = expectedText.substr(1,expectedText.length()-1); - std::stringstream bintStream(bigIntStr); + string bigIntStr = expectedText.substr(1,expectedText.length()-1); + stringstream bintStream(bigIntStr); bigint val; bintStream >> val; - BOOST_CHECK( !u.isList() ); - BOOST_CHECK( !u.isNull() ); - BOOST_CHECK( u ); // operator bool() - BOOST_CHECK(u == val); + TBOOST_CHECK(( !u.isList() )); + TBOOST_CHECK(( !u.isNull() )); + TBOOST_CHECK(( u == val )); } else { - BOOST_CHECK( !u.isList() ); - BOOST_CHECK( !u.isNull() ); - BOOST_CHECK( u.isData() ); - BOOST_CHECK( u ); - BOOST_CHECK( u.size() == expectedText.length() ); - BOOST_CHECK(u == expectedText); + TBOOST_CHECK(( !u.isList() )); + TBOOST_CHECK(( !u.isNull() )); + TBOOST_CHECK(( u.isData() )); + TBOOST_CHECK(( u.size() == expectedText.length() )); + TBOOST_CHECK(( u == expectedText )); } } else if ( v.type() == js::int_type ) { const int expectedValue = v.get_int(); - BOOST_CHECK( u.isInt() ); - BOOST_CHECK( !u.isList() ); - BOOST_CHECK( !u.isNull() ); - BOOST_CHECK( u ); // operator bool() - BOOST_CHECK(u == expectedValue); + TBOOST_CHECK(( u.isInt() )); + TBOOST_CHECK(( !u.isList() )); + TBOOST_CHECK(( !u.isNull() )); + TBOOST_CHECK(( u == expectedValue )); } else if ( v.type() == js::array_type ) { - BOOST_CHECK( u.isList() ); - BOOST_CHECK( !u.isInt() ); - BOOST_CHECK( !u.isData() ); + TBOOST_CHECK(( u.isList() )); + TBOOST_CHECK(( !u.isInt() )); + TBOOST_CHECK(( !u.isData() )); js::mArray& arr = v.get_array(); - BOOST_CHECK( u.itemCount() == arr.size() ); + TBOOST_CHECK(( u.itemCount() == arr.size() )); unsigned i; for( i = 0; i < arr.size(); i++ ) { @@ -132,71 +228,59 @@ namespace dev } else { - BOOST_ERROR("Invalid Javascript object!"); + TBOOST_ERROR("Invalid Javascript object!"); } - } } } -BOOST_AUTO_TEST_SUITE(BasicTests) +BOOST_AUTO_TEST_SUITE(RlpTests) -BOOST_AUTO_TEST_CASE(rlp_encoding_test) +BOOST_AUTO_TEST_CASE(invalidRLPtest) { - cnote << "Testing RLP Encoding..."; - js::mValue v; - dev::test::getRLPTestCases(v); - - for (auto& i: v.get_obj()) - { - js::mObject& o = i.second.get_obj(); - cnote << i.first; - dev::test::checkRLPTestCase(o); - - RLPStream s; - dev::test::buildRLP(o["in"], s); - - std::string expectedText(o["out"].get_str()); - std::transform(expectedText.begin(), expectedText.end(), expectedText.begin(), ::tolower ); - - const std::string& computedText = toHex(s.out()); - - std::stringstream msg; - msg << "Encoding Failed: expected: " << expectedText << std::endl; - msg << " But Computed: " << computedText; - - BOOST_CHECK_MESSAGE( - expectedText == computedText, - msg.str() - ); - } + dev::test::executeTests("invalidRLPTest", "/RLPTests", dev::test::getFolder(__FILE__) + "/RLPTestsFiller", dev::test::doRlpTests); +} +BOOST_AUTO_TEST_CASE(rlptest) +{ + dev::test::executeTests("rlptest", "/RLPTests", dev::test::getFolder(__FILE__) + "/RLPTestsFiller", dev::test::doRlpTests); } -BOOST_AUTO_TEST_CASE(rlp_decoding_test) +BOOST_AUTO_TEST_CASE(rlpRandom) { - cnote << "Testing RLP decoding..."; - // Uses the same test cases as encoding but in reverse. - // We read into the string of hex values, convert to bytes, - // and then compare the output structure to the json of the - // input object. - js::mValue v; - dev::test::getRLPTestCases(v); - for (auto& i: v.get_obj()) - { - js::mObject& o = i.second.get_obj(); - cnote << i.first; - dev::test::checkRLPTestCase(o); + test::Options::get(); - js::mValue& inputData = o["in"]; - bytes payloadToDecode = fromHex(o["out"].get_str()); + string testPath = dev::test::getTestPath(); + testPath += "/RLPTests/RandomRLPTests"; - RLP payload(payloadToDecode); + vector testFiles; + boost::filesystem::directory_iterator iterator(testPath); + for(; iterator != boost::filesystem::directory_iterator(); ++iterator) + if (boost::filesystem::is_regular_file(iterator->path()) && iterator->path().extension() == ".json") + testFiles.push_back(iterator->path()); - dev::test::checkRLPAgainstJson(inputData, payload); + for (auto& path: testFiles) + { + try + { + cnote << "Testing ..." << path.filename(); + json_spirit::mValue v; + string s = asString(dev::contents(path.string())); + TBOOST_REQUIRE_MESSAGE((s.length() > 0), "Content of " + path.string() + " is empty. Have you cloned the 'tests' repo branch develop and set ETHEREUM_TEST_PATH to its path?"); + json_spirit::read_string(s, v); + test::Listener::notifySuiteStarted(path.filename().string()); + dev::test::doRlpTests(v, false); + } + catch (Exception const& _e) + { + TBOOST_ERROR("Failed test with Exception: " << diagnostic_information(_e)); + } + catch (std::exception const& _e) + { + TBOOST_ERROR("Failed test with Exception: " << _e.what()); + } } } BOOST_AUTO_TEST_SUITE_END() - diff --git a/test/libdevcrypto/AES.cpp b/test/libdevcrypto/AES.cpp index 071f1509c..06f0515d6 100644 --- a/test/libdevcrypto/AES.cpp +++ b/test/libdevcrypto/AES.cpp @@ -79,7 +79,7 @@ BOOST_AUTO_TEST_CASE(AuthenticatedStreamConstructor) { cout << "AuthenticatedStreamConstructor" << endl; - Secret const sec("test"); + Secret const sec(dev::sha3("test")); crypto::aes::AuthenticatedStream as(crypto::aes::Encrypt, sec, 0); BOOST_CHECK(as.getMacInterval() == 0); as.adjustInterval(1); diff --git a/test/libdevcrypto/crypto.cpp b/test/libdevcrypto/crypto.cpp index 135292506..b70eae36e 100644 --- a/test/libdevcrypto/crypto.cpp +++ b/test/libdevcrypto/crypto.cpp @@ -69,7 +69,6 @@ BOOST_AUTO_TEST_CASE(emptySHA3Types) #if ETH_HAVE_SECP256K1 BOOST_AUTO_TEST_CASE(secp256k1lib) { - secp256k1Init(); KeyPair k = KeyPair::create(); BOOST_REQUIRE(!!k.sec()); BOOST_REQUIRE(!!k.pub()); diff --git a/test/libethereum/BlockchainTestsFiller/bcBlockGasLimitTestFiller.json b/test/libethereum/BlockchainTestsFiller/bcBlockGasLimitTestFiller.json new file mode 100644 index 000000000..ef3b208b5 --- /dev/null +++ b/test/libethereum/BlockchainTestsFiller/bcBlockGasLimitTestFiller.json @@ -0,0 +1,277 @@ +{ + "SuicideTransaction" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "125000", + "gasUsed" : "0", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "90000000000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0bff", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "100000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + } + ] + }, + + "GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideLast" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "147000", + "gasUsed" : "0", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "90000000000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0bff", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "4", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "5", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "22000", + "gasPrice" : "10", + "nonce" : "6", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + } + ] + }, + + "GasUsedHigherThanBlockGasLimitButNotWithRefundsSuicideFirst" : { + "genesisBlockHeader" : { + "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "coinbase" : "0x8888f1f195afa192cfee860698584c030f4c9db1", + "difficulty" : "131072", + "extraData" : "0x42", + "gasLimit" : "147000", + "gasUsed" : "0", + "mixHash" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "nonce" : "0x0102030405060708", + "number" : "0", + "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000", + "receiptTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot" : "0xf99eb1626cfa6db435c0836235942d7ccaa935f1ae247d3f1c21e495685f903a", + "timestamp" : "0x54c98c81", + "transactionsTrie" : "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "uncleHash" : "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" + }, + "expect" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "90000000000000000000000000", + "nonce" : "0", + "code" : "", + "storage": {} + }, + "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "10000000000", + "nonce" : "0", + "code" : "0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0bff", + "storage": {} + } + }, + "blocks" : [ + { + "transactions" : [ + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "6", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "2", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "3", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "4", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "21000", + "gasPrice" : "10", + "nonce" : "5", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + }, + { + "data" : "", + "gasLimit" : "22000", + "gasPrice" : "10", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "aaaf5374fce5edbc8e2a8697c15331677e6ebf0b", + "value" : "10" + } + ], + "uncleHeaders" : [ + ] + } + ] + } +} diff --git a/test/libethereum/BlockchainTestsFiller/bcWalletTestFiller.json b/test/libethereum/BlockchainTestsFiller/bcWalletTestFiller.json index a946ed724..ed4574cb0 100644 --- a/test/libethereum/BlockchainTestsFiller/bcWalletTestFiller.json +++ b/test/libethereum/BlockchainTestsFiller/bcWalletTestFiller.json @@ -41,8 +41,8 @@ { "transactions" : [ { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107557f9adeddf84386b336eb7b3e18e7a6099be08fd81ea5d5142f4d2b630f8d20cf0160006040a1610ee9806100716000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", - "gasLimit" : "0x116ffc", + "data" : "6060604052604051602080611014833960806040818152925160016000818155818055600160a060020a03331660038190558152610102909452938320939093556201518042046101075582917f102d25c49d33fcdb8976a3f2744e0785c98d9e43b88364859e6aec4ae82eff5c91a250610f958061007f6000396000f300606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x12343f", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -116,7 +116,7 @@ { "transactions" : [ { - "data" : "0x797af6276877e4536b661640954061cdbc3a9761fb5245c340fcb1721307cd9d5f285c96", + "data" : "0x797af62745cdc51a93c670e2712bcef060b979e79bd8c4c25fb303229debad0010481f16", "gasLimit" : "20141591", "gasPrice" : "1", "nonce" : "0", @@ -130,7 +130,6 @@ } ] }, - "wallet2outOf3txsRevoke" : { "genesisBlockHeader" : { "bloom" : "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", @@ -173,8 +172,8 @@ { "transactions" : [ { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107557f9adeddf84386b336eb7b3e18e7a6099be08fd81ea5d5142f4d2b630f8d20cf0160006040a1610ee9806100716000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", - "gasLimit" : "0x116ffc", + "data" : "6060604052604051602080611014833960806040818152925160016000818155818055600160a060020a03331660038190558152610102909452938320939093556201518042046101075582917f102d25c49d33fcdb8976a3f2744e0785c98d9e43b88364859e6aec4ae82eff5c91a250610f958061007f6000396000f300606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x12343f", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -248,7 +247,7 @@ { "transactions" : [ { - "data" : "0xb75c7dc66877e4536b661640954061cdbc3a9761fb5245c340fcb1721307cd9d5f285c96", + "data" : "0xb75c7dc645cdc51a93c670e2712bcef060b979e79bd8c4c25fb303229debad0010481f16", "gasLimit" : "20141591", "gasPrice" : "1", "nonce" : "5", @@ -263,7 +262,7 @@ { "transactions" : [ { - "data" : "0x797af6276877e4536b661640954061cdbc3a9761fb5245c340fcb1721307cd9d5f285c96", + "data" : "0x797af62745cdc51a93c670e2712bcef060b979e79bd8c4c25fb303229debad0010481f16", "gasLimit" : "20141591", "gasPrice" : "1", "nonce" : "0", @@ -319,8 +318,8 @@ { "transactions" : [ { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107557f9adeddf84386b336eb7b3e18e7a6099be08fd81ea5d5142f4d2b630f8d20cf0160006040a1610ee9806100716000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", - "gasLimit" : "0x116ffc", + "data" : "6060604052604051602080611014833960806040818152925160016000818155818055600160a060020a03331660038190558152610102909452938320939093556201518042046101075582917f102d25c49d33fcdb8976a3f2744e0785c98d9e43b88364859e6aec4ae82eff5c91a250610f958061007f6000396000f300606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x12343f", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -394,7 +393,7 @@ { "transactions" : [ { - "data" : "0xb75c7dc66877e4536b661640954061cdbc3a9761fb5245c340fcb1721307cd9d5f285c96", + "data" : "0xb75c7dc645cdc51a93c670e2712bcef060b979e79bd8c4c25fb303229debad0010481f16", "gasLimit" : "20141591", "gasPrice" : "1", "nonce" : "5", @@ -409,7 +408,7 @@ { "transactions" : [ { - "data" : "0x797af6276877e4536b661640954061cdbc3a9761fb5245c340fcb1721307cd9d5f285c96", + "data" : "0x797af62745cdc51a93c670e2712bcef060b979e79bd8c4c25fb303229debad0010481f16", "gasLimit" : "20141591", "gasPrice" : "1", "nonce" : "6", @@ -424,7 +423,7 @@ { "transactions" : [ { - "data" : "0x797af6276877e4536b661640954061cdbc3a9761fb5245c340fcb1721307cd9d5f285c96", + "data" : "0x797af62745cdc51a93c670e2712bcef060b979e79bd8c4c25fb303229debad0010481f16", "gasLimit" : "20141591", "gasPrice" : "1", "nonce" : "0", @@ -481,8 +480,8 @@ { "transactions" : [ { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107557f9adeddf84386b336eb7b3e18e7a6099be08fd81ea5d5142f4d2b630f8d20cf0160006040a1610e39806100716000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b6102976004356000604060003680828437909120905061053b815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7557610bd7565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067781610108565b610297600435604060003680828437909120905061049281610108565b61029d6004355b6000816108b481610108565b610297600435604060003680828437909120905061066b81610108565b61029d6004803590602480359160443591820191013560006106a3846000610dce33610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061061a81610108565b610297600435604060003680828437909120905061068581610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b61040d5b6101045460005b81811015610d2c57610104805482908110610d7457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b1561048d576104a082610146565b156104ab575061048f565b6104b36103ef565b60015460fa901015156104ca576104c86104e1565b505b60015460fa9010151561050b575061048f565b6105d25b600060015b600154811015610c17575b60015481108015610c7357506002816101008110610c6c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043257005b156103975773ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120549250821415610576575061048d565b6001600160005054036000600050541115610591575061048d565b600060028361010081106105a157005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104dd6103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b1561048d5760015482101561062f575061048f565b600082905561063c6103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b1561048d575061010655565b1561048f5760006101055550565b1561048d578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107415773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161075a57005b60406000368082843790912091506107669050816101ae565b506000915061088d9050565b15801561079657506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561088d57600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610895579182015b82811115610895578235826000505591602001919060010190610803565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b808211156108215760008155600101610899565b505b919050565b156108ad576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108ad5760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561093c57915260208220825b815481529060010190602001808311610928575b5050600084866185025a03f161094e57005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109ec57820191906000526020600020905b8154815290600101906020018083116109d8575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a675760008155600101610a53565b5050505060019150506108af565b6000868152610103602052604081208054909450909250821415610b00578154835560018381018390556101048054918201808255828015829011610b8c578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b8a5760008155600101610adf565b6000918252602090912001555b506001820154600284900a90811660001415610bd75773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610ba6576000868152610103602052610104805460409092206002015490918110610be057005b505b5050506002840181905561010480548892908110610af357005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bd7565b5090565b01546000145b15610c8057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2157506001546002906101008110610c1b57005b0154600014155b15610c4f576001016104f1565b60015481108015610ca457506001546002906101008110610c9d57005b0154600014155b8015610cbf57506002816101008110610cb957005b01546000145b15610cd8576001546002906101008110610cdd57005b01555b6104e6565b01546002826101008110610ced57005b01558061010260006002836101008110610d0357005b0154815260208101919091526040016000908120919091556001546002906101008110610cd557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610d60565b6000918252602082200154141515610dc65761010480546101039160009184908110610d9c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016103f6565b156108af5761010754610de45b62015180420490565b1115610dfd57600061010555610df8610ddb565b610107555b6101055480830110158015610e1b5750610105546101065490830111155b15610e31575061010580548201905560016108af565b5060006108af56", - "gasLimit" : "0x116ffc", + "data" : "6060604052604051602080611014833960806040818152925160016000818155818055600160a060020a03331660038190558152610102909452938320939093556201518042046101075582917f102d25c49d33fcdb8976a3f2744e0785c98d9e43b88364859e6aec4ae82eff5c91a250610f958061007f6000396000f300606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x12343f", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", diff --git a/test/libethereum/StateTestsFiller/stPreCompiledContractsTransactionFiller.json b/test/libethereum/StateTestsFiller/stPreCompiledContractsTransactionFiller.json deleted file mode 100644 index ff1e8c5d1..000000000 --- a/test/libethereum/StateTestsFiller/stPreCompiledContractsTransactionFiller.json +++ /dev/null @@ -1,854 +0,0 @@ -{ - "CallEcrecover0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000001", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549" - } - }, - - "CallEcrecover80": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000003f17f1962b36e491b30a40b2405849e597ba5fb5", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000001", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "00c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c00b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75f00b940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549" - } - }, - - "CallEcrecover0_gas3000": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "3000", - "to" : "0000000000000000000000000000000000000001", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000001c73b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549" - } - }, - - "CallEcrecover0_0input": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000001", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "" - } - }, - - "CallEcrecover1": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000001", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c000000000000000000000000000000000000000000000000000000000000000173b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549" - } - }, - - "CallEcrecover2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000001", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "18c547e4f7b0f325ad1e56f57e26c745b09a3e503d86e00e5255ff7f715d3d1c0073b1693892219d736caba55bdb67216e485557ea6b6af75f37096c9aa6a5a75feeb940b1d03b21e36b0e47e79769f095fe2ab855bd91e3a38756b7d75a9c4549" - } - }, - - "CallEcrecover3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x000000000000000000000000e4319f4b631c6d0fcfc84045dbcb676865fe5e13", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000001", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "2f380a2dea7e778d81affc2443403b8fe4644db442ae4862ff5bb3732829cdb9000000000000000000000000000000000000000000000000000000000000001b6b65ccb0558806e9b097f27a396d08f964e37b8b7af6ceeb516ff86739fbea0a37cbc8d883e129a4b1ef9d5f1df53c4f21a3ef147cf2a50a4ede0eb06ce092d4" - } - }, - - "CallSha256_0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0xec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000002", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "000000000000000000000000000000000000000000000000000000000000001" - } - }, - - "CallSha256_2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "300000", - "to" : "0000000000000000000000000000000000000002", - "value" : "0", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "" - } - }, - - "CallSha256_1_nonzeroValue": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000002", - "value" : "0x13", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "" - } - }, - - "CallSha256_2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0xcb39b3bde22925b2f931111130c774761d8895e0e08437c9b396c1e97d10f34d", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000002", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0000000000000000000000000000000000000000000000000000000000000000f34578907f" - } - }, - - "CallSha256_3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x7392925565d67be8e9620aacbcfaecd8cb6ec58d709d25da9eccf1d08a41ce35", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000002", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "000000000000000000000000000000000000000000000000000000f34578907f0000000000" - } - }, - - "CallSha256_4": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0xaf9613760f72635fbdb44a5a0a63c39f12af30f950a6ee5c971be188e89c4051", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000002", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - }, - - "CallSha256_5": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x259911ec9f4b02b7975dfa3f5da78fc58b7066604bdaea66c4485c90f6f55bec", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000002", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - - "CallRipemd160_0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x000000000000000000000000ae387fcfeb723c3f5964509af111cf5a67f30661", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000003", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "000000000000000000000000000000000000000000000000000000000000001" - } - }, - - "CallRipemd160_1": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000009c1185a5c5e9fc54612808977ee8f548b2258d31", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000003", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "" - } - }, - - "CallRipemd160_2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x000000000000000000000000dbc100f916bfbc53535573d98cf0cbb3a5b36124", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000003", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0000000000000000000000000000000000000000000000000000000000000000f34578907f" - } - }, - - "CallRipemd160_3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x000000000000000000000000316750573f9be26bc17727b47cacedbd0ab3e6ca", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000003", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "000000000000000000000000000000000000000000000000000000f34578907f0000000000" - } - }, - - "CallRipemd160_4": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000001cf4e77f5966e13e109703cd8a0df7ceda7f3dc3", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000003", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - }, - - "CallRipemd160_5": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000003", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - - "CallIdentitiy_0": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000001", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000004", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "000000000000000000000000000000000000000000000000000000000000001" - } - }, - - "CallIdentitiy_1": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000004", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "" - } - }, - - "CallIdentitiy_1_nonzeroValue": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000004", - "value" : "0x13", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "" - } - }, - - "CallIdentitiy_2": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x0000000000000000000000000000000000000000000000000000000000000000f34578907f", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000004", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0000000000000000000000000000000000000000000000000000000000000000f34578907f" - } - }, - - "CallIdentitiy_3": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x000000000000000000000000000000000000000000000000000000f34578907f0000000000", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000004", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "000000000000000000000000000000000000000000000000000000f34578907f0000000000" - } - }, - - "CallIdentitiy_4": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000004", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - }, - - "CallIdentitiy_4_gas17": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "0x", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "23176", - "to" : "0000000000000000000000000000000000000004", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - } - }, - - "CallIdentitiy_5": { - "env" : { - "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", - "currentNumber" : "0", - "currentGasLimit" : "10000000", - "currentDifficulty" : "256", - "currentTimestamp" : 1, - "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba" - }, - "expectOut" : "#35659", - "pre" : { - "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { - "balance" : "1000000000000000000", - "nonce" : "0", - "code" : "", - "storage": {} - } - }, - "transaction" : { - "nonce" : "0", - "gasPrice" : "1", - "gasLimit" : "200000", - "to" : "0000000000000000000000000000000000000004", - "value" : "", - "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", - "data" : "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - } - }, - - "callTxToPrecompiled_1": { - "env": { - "currentCoinbase": "aa69d40e4ab383b25fa6c17560dd77b387480dd8", - "currentDifficulty": "0x0100", - "currentGasLimit": "0x0f4240", - "currentNumber": "0x00", - "currentTimestamp": "0x01", - "previousHash": "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" - }, - "expectOut": "0x0000000000000000000000000000000000000000000000000000000000000000", - "pre": { - "cd2a3d9f938e13cd947ec05abc7fe734df8dd826": { - "balance": "150000240000000000000000", - "code": "0x", - "nonce": "0x31", - "storage": {} - }, - "aa69d40e4ab383b25fa6c17560dd77b387480dd8": { - "balance": "0x", - "code": "0x", - "nonce": "0x00", - "storage": {} - }, - "0000000000000000000000000000000000000001": { - "balance": "0x1", - "code": "0x", - "nonce": "0x00", - "storage": {} - } - }, - "transaction": { - "data": "", - "gasLimit": "0x09965e", - "gasPrice": "0x09184e72a000", - "nonce": "0x31", - "secretKey": "c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4", - "to": "0000000000000000000000000000000000000001", - "value": "0x0a968163f0a57b400000" - } - } -} diff --git a/test/libethereum/StateTestsFiller/stSpecialTestFiller.json b/test/libethereum/StateTestsFiller/stSpecialTestFiller.json index fb7a7aa8f..2944c23c4 100644 --- a/test/libethereum/StateTestsFiller/stSpecialTestFiller.json +++ b/test/libethereum/StateTestsFiller/stSpecialTestFiller.json @@ -488,5 +488,48 @@ "to" : "b03f030056db7d467d778326658bac0d1b35d8f7", "value" : "0" } + }, + + "BadStateRootTx" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "45678256", + "currentGasLimit" : "(2**256)-1", + "currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "expect" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "1000" + } + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "2000000", + "code" : "", + "nonce" : "0", + "storage" : { + } + }, + "1baf27b88c48dd02b744999cf3522766929d2b2a" : { + "balance" : "1000", + "code" : "0x600073a94f5374fce5edbc8e2a8697c15331677e6ebf0b3314156023573540602035145b15602e576040356000555b", + "nonce" : "0", + "storage" : { + } + } + }, + "transaction" : + { + "data" : "0x00000000000000000000000000000000000000000000000000000000000bc03712fac13c68425054e372b0861af05648614d69d32800fba9ad4522238d4b937a0000000000000000000000000000000000000000000000000000000000000000", + "gasLimit" : "200000", + "gasPrice" : "1", + "nonce" : "0", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "1baf27b88c48dd02b744999cf3522766929d2b2a", + "value" : "0" + } } } diff --git a/test/libethereum/StateTestsFiller/stWalletTestFiller.json b/test/libethereum/StateTestsFiller/stWalletTestFiller.json index de02277e8..51c3daec7 100644 --- a/test/libethereum/StateTestsFiller/stWalletTestFiller.json +++ b/test/libethereum/StateTestsFiller/stWalletTestFiller.json @@ -18,8 +18,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff166003819055815261010260205260408120919091556108ae90819061004590396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", - "gasLimit" : "0x03d0c3", + "data" : "606060409081526001600081815581805533600160a060020a0316600381905581526101026020529182205561090a90819061003b90396000f300606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x03e9c1", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -47,8 +47,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff166003819055815261010260205260408120919091556108ae90819061004590396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", - "gasLimit" : "0x0a98b3", + "data" : "606060409081526001600081815581805533600160a060020a0316600381905581526101026020529182205561090a90819061003b90396000f300606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x0af991", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -76,8 +76,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff166003819055815261010260205260408120919091556108ae90819061004590396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", - "gasLimit" : "0x0a98b4", + "data" : "606060409081526001600081815581805533600160a060020a0316600381905581526101026020529182205561090a90819061003b90396000f300606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "10000000", "gasPrice" : "1", "nonce" : "0", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -98,7 +98,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -138,7 +138,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -178,7 +178,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -218,7 +218,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -258,7 +258,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -298,7 +298,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -326,7 +326,7 @@ } }, - "multiOwnedRemoveOwner" : { + "multiOwnedRemoveOwner_mySelf" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "256", @@ -338,7 +338,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -366,7 +366,7 @@ } }, - "multiOwnedRemoveOwnerByNonOwner" : { + "multiOwnedRemoveOwner" : { "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentDifficulty" : "256", @@ -380,6 +380,48 @@ "balance" : "0x64", "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", "nonce" : "0x00", + "storage" : { + "0x00" : "0x01", + "0x01" : "0x02", + "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x04" : "0x3fb1cd2cd96c6d5c0b5eb3322d807b34482481d4", + "0x6e369836487c234b9e553ef3f787c2d8865520739d340c67b3d251a33986e58d" : "0x01", + "0xd3e69d8c7f41f7aeaf8130ddc53047aeee8cb46a73d6bae86b7e7d6bf8312e6b" : "0x02" + } + }, + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a75ef08f", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + } + }, + "transaction" : { + "data" : "0x173825d9000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "gasLimit" : "10000000", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "6295ee1b4f6dd65047762f924ecd367c17eabf8f", + "value" : "100" + } + }, + + "multiOwnedRemoveOwnerByNonOwner" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "256", + "currentGasLimit" : "10000000", + "currentNumber" : "0", + "currentTimestamp" : 1, + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : { + "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { + "balance" : "0x64", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "nonce" : "0x00", "storage" : { "0x00" : "0x01", "0x01" : "0x01", @@ -425,7 +467,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -465,7 +507,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -505,7 +547,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -545,7 +587,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -585,7 +627,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -625,7 +667,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -665,7 +707,7 @@ "pre" : { "6295ee1b4f6dd65047762f924ecd367c17eabf8f" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100655780632f54bf6e146100b75780637065cb48146100e8578063b75c7dc614610105578063ba51a6df14610142578063f00d4b5d1461015f57005b6101816004356000604060003680828437909120905061046d815b73ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120548180808381141561058f57610586565b6101876004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610181600435604060003680828437909120905061037c81610080565b61018160043573ffffffffffffffffffffffffffffffffffffffff3316600090815261010260205260408120549080808381141561019157610213565b610181600435604060003680828437909120905061053381610080565b6101816004356024356000604060003680828437909120905061028681610080565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561021357815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b1561027f57610294836100be565b1561029f5750610281565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156102d55750610281565b6102f75b6101045460005b8181101561080c5761010480548290811061085457005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061021a57005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103775761038a826100be565b156103955750610379565b61039d6102d9565b60015460fa901015156103b4576103b26103cb565b505b60015460fa901015156103f55750610379565b6104255b600060015b6001548110156106f7575b600154811080156107535750600281610100811061074c57005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061031c57005b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156102815773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104a85750610377565b60016001600050540360006000505411156104c35750610377565b600060028361010081106104d357005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556103c76102d9565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610377576001548211156105485750610379565b60008290556105046102d9565b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600086815261010360205260408120805490945090925082141561061a5781548355600183810183905561010480549182018082558280158290116106a6578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106a457600081556001016105f9565b6000918252602090912001555b506001820154600284900a908116600014156105865773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156105555760008681526101036020526101048054604090922060020154909181106106c057005b505b505050600284018190556101048054889290811061060d57005b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610586565b5090565b01546000145b1561076057600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610701575060015460029061010081106106fb57005b0154600014155b1561072f576001016103db565b600154811080156107845750600154600290610100811061077d57005b0154600014155b801561079f5750600281610100811061079957005b01546000145b156107b85760015460029061010081106107bd57005b01555b6103d0565b015460028261010081106107cd57005b015580610102600060028361010081106107e357005b01548152602081019190915260400160009081209190915560015460029061010081106107b557005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b8082111561027f5760008155600101610840565b60009182526020822001541415156108a6576101048054610103916000918490811061087c57005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b6001016102e056", + "code" : "0x606060405236156100775760e060020a6000350463173825d981146100795780632f54bf6e146100d55780634123cb6b146100f95780637065cb4814610102578063746c917114610136578063b75c7dc61461013f578063ba51a6df1461016f578063c2cf7326146101a3578063f00d4b5d146101e3575b005b610077600435600060003643604051808484808284375050509091019081526040519081900360200190209050610529815b600160a060020a033316600090815261010260205260408120548180808381141561066f57610806565b61021c6004355b600160a060020a0316600090815261010260205260408120541190565b61021c60015481565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506104a1816100ab565b61021c60005481565b610077600435600160a060020a033316600090815261010260205260408120549080808381141561022e576102b0565b610077600435600036436040518084848082843750505090910190815260405190819003602001902090506105e8816100ab565b61021c600435602435600082815261010360209081526040808320600160a060020a03851684526101029092528220548290818181141561064157610665565b61007760043560243560006000364360405180848480828437505050909101908152604051908190036020019020905061033a816100ab565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156102b05781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b1561033357610348836100dc565b156103535750610335565b600160a060020a03841660009081526101026020526040812054925082141561037c5750610335565b6102b75b6101045460005b818110156107b557610104805482908110156100025760009182526000805160206108ea8339815191520154146103fa576101048054610103916000918490811015610002576000805160206108ea83398151915201548252506020919091526040812081815560018101829055600201555b600101610387565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561049c576104af826100dc565b156104ba575061049e565b6104c2610380565b60015460fa90106104d7576104d56104ec565b505b60015460fa9010610402575061049e565b6105a65b600060015b6001548110156107ef575b6001548110801561051c5750600281610100811015610002570154600014155b1561080f576001016104fc565b1561033557600160a060020a038316600090815261010260205260408120549250821415610557575061049c565b6001600160005054036000600050541115610572575061049c565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556104e8610380565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561049c576001548211156105fd575061049e565b600082905561060a610380565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106605760009450610665565b600194505b5050505092915050565b60008681526101036020526040812080549094509092508214156106f85781548355600183810183905561010480549182018082558280158290116106c7578183600052602060002091820191016106c791906107db565b505050600284018190556101048054889290811015610002576000919091526000805160206108ea83398151915201555b506001820154600284900a908116600014156108065760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a18254600190116107f35760008681526101036020526040902060020154610104805490919081101561000257604060009081206000805160206108ea83398151915292909201819055808255600180830182905560029092015595506108069050565b6101048054600080835591909152610335906000805160206108ea833981519152908101905b808211156107ef57600081556001016107db565b5090565b8254600019018355600183018054821790555b50505050919050565b5b6001805411801561083257506001546002906101008110156100025701546000145b156108465760018054600019019055610810565b600154811080156108695750600154600290610100811015610002570154600014155b801561088357506002816101008110156100025701546000145b156108e457600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b6104f156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -712,8 +754,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107556109158061004b6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d9811461007b5780632f54bf6e146100cd5780635c52c2f5146100fe5780637065cb4814610118578063b20d30a914610135578063b75c7dc614610152578063ba51a6df1461018f578063f00d4b5d146101ac57005b6101ce60043560006040600036808284379091209050610472815b73ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054818080838114156105bc5761071e565b6101d46004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b6101ce60406000368082843790912090506105ae81610096565b6101ce60043560406000368082843790912090506103c981610096565b6101ce60043560406000368082843790912090506105a281610096565b6101ce60043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156101de57610260565b6101ce600435604060003680828437909120905061055181610096565b6101ce600435602435600060406000368082843790912090506102d381610096565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561026057815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b156102cc576102e1836100d4565b156102ec57506102ce565b73ffffffffffffffffffffffffffffffffffffffff841660009081526101026020526040812054925082141561032257506102ce565b6103445b6101045460005b81811015610873576101048054829081106108bb57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061026757005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103c4576103d7826100d4565b156103e257506103c6565b6103ea610326565b60015460fa90101515610401576103ff610418565b505b60015460fa9010151561044257506103c6565b6105095b600060015b60015481101561075e575b600154811080156107ba575060028161010081106107b357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061036957005b156102ce5773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104ad57506103c4565b60016001600050540360006000505411156104c857506103c4565b600060028361010081106104d857005b015573ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812055610414610326565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156103c45760015482111561056657506103c6565b6000829055610573610326565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b156103c4575061010655565b156103c65760006101055550565b60008681526101036020526040812080549094509092508214156106475781548355600183810183905561010480549182018082558280158290116106d3578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106d15760008155600101610626565b6000918252602090912001555b506001820154600284900a9081166000141561071e5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156106ed57600086815261010360205261010480546040909220600201549091811061072757005b505b505050600284018190556101048054889290811061063a57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600091825260208083209091018290558782526101039052604081208181556001818101839055600290910191909155945061071e565b5090565b01546000145b156107c757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b600180541180156107685750600154600290610100811061076257005b0154600014155b1561079657600101610428565b600154811080156107eb575060015460029061010081106107e457005b0154600014155b80156108065750600281610100811061080057005b01546000145b1561081f57600154600290610100811061082457005b01555b61041d565b0154600282610100811061083457005b0155806101026000600283610100811061084a57005b015481526020810191909152604001600090812091909155600154600290610100811061081c57005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156102cc57600081556001016108a7565b600091825260208220015414151561090d57610104805461010391600091849081106108e357005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b60010161032d56", - "gasLimit" : "0x0b5291", + "data" : "606060409081526001600081815581805533600160a060020a0316600381905581526101026020529190912055620151804204610107556109b4806100456000396000f300606060405236156100985760e060020a6000350463173825d9811461009a5780632f54bf6e146100f65780634123cb6b1461011a5780635c52c2f5146101235780637065cb4814610154578063746c917114610188578063b20d30a914610191578063b75c7dc6146101c5578063ba51a6df146101f5578063c2cf732614610229578063f00d4b5d14610269578063f1736d86146102a2575b005b6100986004356000600036436040518084848082843750505090910190815260405190819003602001902090506105b9815b600160a060020a0333166000908152610102602052604081205481808083811415610719576108b0565b6102ac6004355b600160a060020a0316600090815261010260205260408120541190565b6102ac60015481565b6100986000364360405180848480828437505050909101908152604051908190036020019020905061070b816100cc565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610531816100cc565b6102ac60005481565b610098600435600036436040518084848082843750505090910190815260405190819003602001902090506106ff816100cc565b610098600435600160a060020a03331660009081526101026020526040812054908080838114156102be57610340565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610678816100cc565b6102ac600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156106d1576106f5565b6100986004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506103ca816100cc565b6102ac6101055481565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156103405781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156103c3576103d8836100fd565b156103e357506103c5565b600160a060020a03841660009081526101026020526040812054925082141561040c57506103c5565b6103475b6101045460005b8181101561085f576101048054829081101561000257600091825260008051602061099483398151915201541461048a5761010480546101039160009184908110156100025760008051602061099483398151915201548252506020919091526040812081815560018101829055600201555b600101610417565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561052c5761053f826100fd565b1561054a575061052e565b610552610410565b60015460fa90106105675761056561057c565b505b60015460fa9010610492575061052e565b6106365b600060015b600154811015610899575b600154811080156105ac5750600281610100811015610002570154600014155b156108b95760010161058c565b156103c557600160a060020a0383166000908152610102602052604081205492508214156105e7575061052c565b6001600160005054036000600050541115610602575061052c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610578610410565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561052c5760015482111561068d575061052e565b600082905561069a610410565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106f057600094506106f5565b600194505b5050505092915050565b1561052c575061010555565b1561052e5760006101065550565b60008681526101036020526040812080549094509092508214156107a2578154835560018381018390556101048054918201808255828015829011610771578183600052602060002091820191016107719190610885565b5050506002840181905561010480548892908110156100025760009190915260008051602061099483398151915201555b506001820154600284900a908116600014156108b05760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a182546001901161089d57600086815261010360205260409020600201546101048054909190811015610002576040600090812060008051602061099483398151915292909201819055808255600180830182905560029092015595506108b09050565b61010480546000808355919091526103c590600080516020610994833981519152908101905b808211156108995760008155600101610885565b5090565b8254600019018355600183018054821790555b50505050919050565b5b600180541180156108dc57506001546002906101008110156100025701546000145b156108f057600180546000190190556108ba565b600154811080156109135750600154600290610100811015610002570154600014155b801561092d57506002816101008110156100025701546000145b1561098e57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61058156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x0bfabb", "gasPrice" : "1", "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -741,8 +783,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107556109158061004b6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d9811461007b5780632f54bf6e146100cd5780635c52c2f5146100fe5780637065cb4814610118578063b20d30a914610135578063b75c7dc614610152578063ba51a6df1461018f578063f00d4b5d146101ac57005b6101ce60043560006040600036808284379091209050610472815b73ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054818080838114156105bc5761071e565b6101d46004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b6101ce60406000368082843790912090506105ae81610096565b6101ce60043560406000368082843790912090506103c981610096565b6101ce60043560406000368082843790912090506105a281610096565b6101ce60043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156101de57610260565b6101ce600435604060003680828437909120905061055181610096565b6101ce600435602435600060406000368082843790912090506102d381610096565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561026057815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b156102cc576102e1836100d4565b156102ec57506102ce565b73ffffffffffffffffffffffffffffffffffffffff841660009081526101026020526040812054925082141561032257506102ce565b6103445b6101045460005b81811015610873576101048054829081106108bb57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061026757005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103c4576103d7826100d4565b156103e257506103c6565b6103ea610326565b60015460fa90101515610401576103ff610418565b505b60015460fa9010151561044257506103c6565b6105095b600060015b60015481101561075e575b600154811080156107ba575060028161010081106107b357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061036957005b156102ce5773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104ad57506103c4565b60016001600050540360006000505411156104c857506103c4565b600060028361010081106104d857005b015573ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812055610414610326565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156103c45760015482111561056657506103c6565b6000829055610573610326565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b156103c4575061010655565b156103c65760006101055550565b60008681526101036020526040812080549094509092508214156106475781548355600183810183905561010480549182018082558280158290116106d3578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106d15760008155600101610626565b6000918252602090912001555b506001820154600284900a9081166000141561071e5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156106ed57600086815261010360205261010480546040909220600201549091811061072757005b505b505050600284018190556101048054889290811061063a57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600091825260208083209091018290558782526101039052604081208181556001818101839055600290910191909155945061071e565b5090565b01546000145b156107c757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b600180541180156107685750600154600290610100811061076257005b0154600014155b1561079657600101610428565b600154811080156107eb575060015460029061010081106107e457005b0154600014155b80156108065750600281610100811061080057005b01546000145b1561081f57600154600290610100811061082457005b01555b61041d565b0154600282610100811061083457005b0155806101026000600283610100811061084a57005b015481526020810191909152604001600090812091909155600154600290610100811061081c57005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156102cc57600081556001016108a7565b600091825260208220015414151561090d57610104805461010391600091849081106108e357005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b60010161032d56", - "gasLimit" : "0x0b5290", + "data" : "606060409081526001600081815581805533600160a060020a0316600381905581526101026020529190912055620151804204610107556109b4806100456000396000f300606060405236156100985760e060020a6000350463173825d9811461009a5780632f54bf6e146100f65780634123cb6b1461011a5780635c52c2f5146101235780637065cb4814610154578063746c917114610188578063b20d30a914610191578063b75c7dc6146101c5578063ba51a6df146101f5578063c2cf732614610229578063f00d4b5d14610269578063f1736d86146102a2575b005b6100986004356000600036436040518084848082843750505090910190815260405190819003602001902090506105b9815b600160a060020a0333166000908152610102602052604081205481808083811415610719576108b0565b6102ac6004355b600160a060020a0316600090815261010260205260408120541190565b6102ac60015481565b6100986000364360405180848480828437505050909101908152604051908190036020019020905061070b816100cc565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610531816100cc565b6102ac60005481565b610098600435600036436040518084848082843750505090910190815260405190819003602001902090506106ff816100cc565b610098600435600160a060020a03331660009081526101026020526040812054908080838114156102be57610340565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610678816100cc565b6102ac600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156106d1576106f5565b6100986004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506103ca816100cc565b6102ac6101055481565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156103405781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156103c3576103d8836100fd565b156103e357506103c5565b600160a060020a03841660009081526101026020526040812054925082141561040c57506103c5565b6103475b6101045460005b8181101561085f576101048054829081101561000257600091825260008051602061099483398151915201541461048a5761010480546101039160009184908110156100025760008051602061099483398151915201548252506020919091526040812081815560018101829055600201555b600101610417565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561052c5761053f826100fd565b1561054a575061052e565b610552610410565b60015460fa90106105675761056561057c565b505b60015460fa9010610492575061052e565b6106365b600060015b600154811015610899575b600154811080156105ac5750600281610100811015610002570154600014155b156108b95760010161058c565b156103c557600160a060020a0383166000908152610102602052604081205492508214156105e7575061052c565b6001600160005054036000600050541115610602575061052c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610578610410565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561052c5760015482111561068d575061052e565b600082905561069a610410565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106f057600094506106f5565b600194505b5050505092915050565b1561052c575061010555565b1561052e5760006101065550565b60008681526101036020526040812080549094509092508214156107a2578154835560018381018390556101048054918201808255828015829011610771578183600052602060002091820191016107719190610885565b5050506002840181905561010480548892908110156100025760009190915260008051602061099483398151915201555b506001820154600284900a908116600014156108b05760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a182546001901161089d57600086815261010360205260409020600201546101048054909190811015610002576040600090812060008051602061099483398151915292909201819055808255600180830182905560029092015595506108b09050565b61010480546000808355919091526103c590600080516020610994833981519152908101905b808211156108995760008155600101610885565b5090565b8254600019018355600183018054821790555b50505050919050565b5b600180541180156108dc57506001546002906101008110156100025701546000145b156108f057600180546000190190556108ba565b600154811080156109135750600154600290610100811015610002570154600014155b801561092d57506002816101008110156100025701546000145b1561098e57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61058156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x0bfaba", "gasPrice" : "1", "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -770,8 +812,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107556109158061004b6000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d9811461007b5780632f54bf6e146100cd5780635c52c2f5146100fe5780637065cb4814610118578063b20d30a914610135578063b75c7dc614610152578063ba51a6df1461018f578063f00d4b5d146101ac57005b6101ce60043560006040600036808284379091209050610472815b73ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054818080838114156105bc5761071e565b6101d46004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b6101ce60406000368082843790912090506105ae81610096565b6101ce60043560406000368082843790912090506103c981610096565b6101ce60043560406000368082843790912090506105a281610096565b6101ce60043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156101de57610260565b6101ce600435604060003680828437909120905061055181610096565b6101ce600435602435600060406000368082843790912090506102d381610096565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561026057815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b156102cc576102e1836100d4565b156102ec57506102ce565b73ffffffffffffffffffffffffffffffffffffffff841660009081526101026020526040812054925082141561032257506102ce565b6103445b6101045460005b81811015610873576101048054829081106108bb57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061026757005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103c4576103d7826100d4565b156103e257506103c6565b6103ea610326565b60015460fa90101515610401576103ff610418565b505b60015460fa9010151561044257506103c6565b6105095b600060015b60015481101561075e575b600154811080156107ba575060028161010081106107b357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061036957005b156102ce5773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104ad57506103c4565b60016001600050540360006000505411156104c857506103c4565b600060028361010081106104d857005b015573ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812055610414610326565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156103c45760015482111561056657506103c6565b6000829055610573610326565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b156103c4575061010655565b156103c65760006101055550565b60008681526101036020526040812080549094509092508214156106475781548355600183810183905561010480549182018082558280158290116106d3578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106d15760008155600101610626565b6000918252602090912001555b506001820154600284900a9081166000141561071e5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156106ed57600086815261010360205261010480546040909220600201549091811061072757005b505b505050600284018190556101048054889290811061063a57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600091825260208083209091018290558782526101039052604081208181556001818101839055600290910191909155945061071e565b5090565b01546000145b156107c757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b600180541180156107685750600154600290610100811061076257005b0154600014155b1561079657600101610428565b600154811080156107eb575060015460029061010081106107e457005b0154600014155b80156108065750600281610100811061080057005b01546000145b1561081f57600154600290610100811061082457005b01555b61041d565b0154600282610100811061083457005b0155806101026000600283610100811061084a57005b015481526020810191909152604001600090812091909155600154600290610100811061081c57005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156102cc57600081556001016108a7565b600091825260208220015414151561090d57610104805461010391600091849081106108e357005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b60010161032d56", - "gasLimit" : "0x043a28", + "data" : "606060409081526001600081815581805533600160a060020a0316600381905581526101026020529190912055620151804204610107556109b4806100456000396000f300606060405236156100985760e060020a6000350463173825d9811461009a5780632f54bf6e146100f65780634123cb6b1461011a5780635c52c2f5146101235780637065cb4814610154578063746c917114610188578063b20d30a914610191578063b75c7dc6146101c5578063ba51a6df146101f5578063c2cf732614610229578063f00d4b5d14610269578063f1736d86146102a2575b005b6100986004356000600036436040518084848082843750505090910190815260405190819003602001902090506105b9815b600160a060020a0333166000908152610102602052604081205481808083811415610719576108b0565b6102ac6004355b600160a060020a0316600090815261010260205260408120541190565b6102ac60015481565b6100986000364360405180848480828437505050909101908152604051908190036020019020905061070b816100cc565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610531816100cc565b6102ac60005481565b610098600435600036436040518084848082843750505090910190815260405190819003602001902090506106ff816100cc565b610098600435600160a060020a03331660009081526101026020526040812054908080838114156102be57610340565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610678816100cc565b6102ac600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156106d1576106f5565b6100986004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506103ca816100cc565b6102ac6101055481565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156103405781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156103c3576103d8836100fd565b156103e357506103c5565b600160a060020a03841660009081526101026020526040812054925082141561040c57506103c5565b6103475b6101045460005b8181101561085f576101048054829081101561000257600091825260008051602061099483398151915201541461048a5761010480546101039160009184908110156100025760008051602061099483398151915201548252506020919091526040812081815560018101829055600201555b600101610417565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561052c5761053f826100fd565b1561054a575061052e565b610552610410565b60015460fa90106105675761056561057c565b505b60015460fa9010610492575061052e565b6106365b600060015b600154811015610899575b600154811080156105ac5750600281610100811015610002570154600014155b156108b95760010161058c565b156103c557600160a060020a0383166000908152610102602052604081205492508214156105e7575061052c565b6001600160005054036000600050541115610602575061052c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610578610410565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561052c5760015482111561068d575061052e565b600082905561069a610410565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106f057600094506106f5565b600194505b5050505092915050565b1561052c575061010555565b1561052e5760006101065550565b60008681526101036020526040812080549094509092508214156107a2578154835560018381018390556101048054918201808255828015829011610771578183600052602060002091820191016107719190610885565b5050506002840181905561010480548892908110156100025760009190915260008051602061099483398151915201555b506001820154600284900a908116600014156108b05760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a182546001901161089d57600086815261010360205260409020600201546101048054909190811015610002576040600090812060008051602061099483398151915292909201819055808255600180830182905560029092015595506108b09050565b61010480546000808355919091526103c590600080516020610994833981519152908101905b808211156108995760008155600101610885565b5090565b8254600019018355600183018054821790555b50505050919050565b5b600180541180156108dc57506001546002906101008110156100025701546000145b156108f057600180546000190190556108ba565b600154811080156109135750600154600290610100811015610002570154600014155b801561092d57506002816101008110156100025701546000145b1561098e57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61058156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x04661a", "gasPrice" : "1", "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -799,11 +841,12 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d9811461007b5780632f54bf6e146100cd5780635c52c2f5146100fe5780637065cb4814610118578063b20d30a914610135578063b75c7dc614610152578063ba51a6df1461018f578063f00d4b5d146101ac57005b6101ce60043560006040600036808284379091209050610472815b73ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054818080838114156105bc5761071e565b6101d46004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b6101ce60406000368082843790912090506105ae81610096565b6101ce60043560406000368082843790912090506103c981610096565b6101ce60043560406000368082843790912090506105a281610096565b6101ce60043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156101de57610260565b6101ce600435604060003680828437909120905061055181610096565b6101ce600435602435600060406000368082843790912090506102d381610096565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561026057815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b156102cc576102e1836100d4565b156102ec57506102ce565b73ffffffffffffffffffffffffffffffffffffffff841660009081526101026020526040812054925082141561032257506102ce565b6103445b6101045460005b81811015610873576101048054829081106108bb57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061026757005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103c4576103d7826100d4565b156103e257506103c6565b6103ea610326565b60015460fa90101515610401576103ff610418565b505b60015460fa9010151561044257506103c6565b6105095b600060015b60015481101561075e575b600154811080156107ba575060028161010081106107b357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061036957005b156102ce5773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104ad57506103c4565b60016001600050540360006000505411156104c857506103c4565b600060028361010081106104d857005b015573ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812055610414610326565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156103c45760015482111561056657506103c6565b6000829055610573610326565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b156103c4575061010655565b156103c65760006101055550565b60008681526101036020526040812080549094509092508214156106475781548355600183810183905561010480549182018082558280158290116106d3578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106d15760008155600101610626565b6000918252602090912001555b506001820154600284900a9081166000141561071e5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156106ed57600086815261010360205261010480546040909220600201549091811061072757005b505b505050600284018190556101048054889290811061063a57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600091825260208083209091018290558782526101039052604081208181556001818101839055600290910191909155945061071e565b5090565b01546000145b156107c757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b600180541180156107685750600154600290610100811061076257005b0154600014155b1561079657600101610428565b600154811080156107eb575060015460029061010081106107e457005b0154600014155b80156108065750600281610100811061080057005b01546000145b1561081f57600154600290610100811061082457005b01555b61041d565b0154600282610100811061083457005b0155806101026000600283610100811061084a57005b015481526020810191909152604001600090812091909155600154600290610100811061081c57005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156102cc57600081556001016108a7565b600091825260208220015414151561090d57610104805461010391600091849081106108e357005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b60010161032d56", + "code" : "0x606060405236156100985760e060020a6000350463173825d9811461009a5780632f54bf6e146100f65780634123cb6b1461011a5780635c52c2f5146101235780637065cb4814610154578063746c917114610188578063b20d30a914610191578063b75c7dc6146101c5578063ba51a6df146101f5578063c2cf732614610229578063f00d4b5d14610269578063f1736d86146102a2575b005b6100986004356000600036436040518084848082843750505090910190815260405190819003602001902090506105b9815b600160a060020a0333166000908152610102602052604081205481808083811415610719576108b0565b6102ac6004355b600160a060020a0316600090815261010260205260408120541190565b6102ac60015481565b6100986000364360405180848480828437505050909101908152604051908190036020019020905061070b816100cc565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610531816100cc565b6102ac60005481565b610098600435600036436040518084848082843750505090910190815260405190819003602001902090506106ff816100cc565b610098600435600160a060020a03331660009081526101026020526040812054908080838114156102be57610340565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610678816100cc565b6102ac600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156106d1576106f5565b6100986004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506103ca816100cc565b6102ac6101055481565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156103405781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156103c3576103d8836100fd565b156103e357506103c5565b600160a060020a03841660009081526101026020526040812054925082141561040c57506103c5565b6103475b6101045460005b8181101561085f576101048054829081101561000257600091825260008051602061099483398151915201541461048a5761010480546101039160009184908110156100025760008051602061099483398151915201548252506020919091526040812081815560018101829055600201555b600101610417565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561052c5761053f826100fd565b1561054a575061052e565b610552610410565b60015460fa90106105675761056561057c565b505b60015460fa9010610492575061052e565b6106365b600060015b600154811015610899575b600154811080156105ac5750600281610100811015610002570154600014155b156108b95760010161058c565b156103c557600160a060020a0383166000908152610102602052604081205492508214156105e7575061052c565b6001600160005054036000600050541115610602575061052c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610578610410565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561052c5760015482111561068d575061052e565b600082905561069a610410565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106f057600094506106f5565b600194505b5050505092915050565b1561052c575061010555565b1561052e5760006101065550565b60008681526101036020526040812080549094509092508214156107a2578154835560018381018390556101048054918201808255828015829011610771578183600052602060002091820191016107719190610885565b5050506002840181905561010480548892908110156100025760009190915260008051602061099483398151915201555b506001820154600284900a908116600014156108b05760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a182546001901161089d57600086815261010360205260409020600201546101048054909190811015610002576040600090812060008051602061099483398151915292909201819055808255600180830182905560029092015595506108b09050565b61010480546000808355919091526103c590600080516020610994833981519152908101905b808211156108995760008155600101610885565b5090565b8254600019018355600183018054821790555b50505050919050565b5b600180541180156108dc57506001546002906101008110156100025701546000145b156108f057600180546000190190556108ba565b600154811080156109135750600154600290610100811015610002570154600014155b801561092d57506002816101008110156100025701546000145b1561098e57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61058156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", "0x01" : "0x01", + "0x0107" : "0x0c22e4", "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x6e369836487c234b9e553ef3f787c2d8865520739d340c67b3d251a33986e58d" : "0x01" } @@ -839,11 +882,12 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d9811461007b5780632f54bf6e146100cd5780635c52c2f5146100fe5780637065cb4814610118578063b20d30a914610135578063b75c7dc614610152578063ba51a6df1461018f578063f00d4b5d146101ac57005b6101ce60043560006040600036808284379091209050610472815b73ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054818080838114156105bc5761071e565b6101d46004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b6101ce60406000368082843790912090506105ae81610096565b6101ce60043560406000368082843790912090506103c981610096565b6101ce60043560406000368082843790912090506105a281610096565b6101ce60043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156101de57610260565b6101ce600435604060003680828437909120905061055181610096565b6101ce600435602435600060406000368082843790912090506102d381610096565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561026057815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b156102cc576102e1836100d4565b156102ec57506102ce565b73ffffffffffffffffffffffffffffffffffffffff841660009081526101026020526040812054925082141561032257506102ce565b6103445b6101045460005b81811015610873576101048054829081106108bb57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061026757005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103c4576103d7826100d4565b156103e257506103c6565b6103ea610326565b60015460fa90101515610401576103ff610418565b505b60015460fa9010151561044257506103c6565b6105095b600060015b60015481101561075e575b600154811080156107ba575060028161010081106107b357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061036957005b156102ce5773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104ad57506103c4565b60016001600050540360006000505411156104c857506103c4565b600060028361010081106104d857005b015573ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812055610414610326565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156103c45760015482111561056657506103c6565b6000829055610573610326565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b156103c4575061010655565b156103c65760006101055550565b60008681526101036020526040812080549094509092508214156106475781548355600183810183905561010480549182018082558280158290116106d3578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106d15760008155600101610626565b6000918252602090912001555b506001820154600284900a9081166000141561071e5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156106ed57600086815261010360205261010480546040909220600201549091811061072757005b505b505050600284018190556101048054889290811061063a57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600091825260208083209091018290558782526101039052604081208181556001818101839055600290910191909155945061071e565b5090565b01546000145b156107c757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b600180541180156107685750600154600290610100811061076257005b0154600014155b1561079657600101610428565b600154811080156107eb575060015460029061010081106107e457005b0154600014155b80156108065750600281610100811061080057005b01546000145b1561081f57600154600290610100811061082457005b01555b61041d565b0154600282610100811061083457005b0155806101026000600283610100811061084a57005b015481526020810191909152604001600090812091909155600154600290610100811061081c57005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156102cc57600081556001016108a7565b600091825260208220015414151561090d57610104805461010391600091849081106108e357005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b60010161032d56", + "code" : "0x606060405236156100985760e060020a6000350463173825d9811461009a5780632f54bf6e146100f65780634123cb6b1461011a5780635c52c2f5146101235780637065cb4814610154578063746c917114610188578063b20d30a914610191578063b75c7dc6146101c5578063ba51a6df146101f5578063c2cf732614610229578063f00d4b5d14610269578063f1736d86146102a2575b005b6100986004356000600036436040518084848082843750505090910190815260405190819003602001902090506105b9815b600160a060020a0333166000908152610102602052604081205481808083811415610719576108b0565b6102ac6004355b600160a060020a0316600090815261010260205260408120541190565b6102ac60015481565b6100986000364360405180848480828437505050909101908152604051908190036020019020905061070b816100cc565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610531816100cc565b6102ac60005481565b610098600435600036436040518084848082843750505090910190815260405190819003602001902090506106ff816100cc565b610098600435600160a060020a03331660009081526101026020526040812054908080838114156102be57610340565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610678816100cc565b6102ac600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156106d1576106f5565b6100986004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506103ca816100cc565b6102ac6101055481565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156103405781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156103c3576103d8836100fd565b156103e357506103c5565b600160a060020a03841660009081526101026020526040812054925082141561040c57506103c5565b6103475b6101045460005b8181101561085f576101048054829081101561000257600091825260008051602061099483398151915201541461048a5761010480546101039160009184908110156100025760008051602061099483398151915201548252506020919091526040812081815560018101829055600201555b600101610417565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561052c5761053f826100fd565b1561054a575061052e565b610552610410565b60015460fa90106105675761056561057c565b505b60015460fa9010610492575061052e565b6106365b600060015b600154811015610899575b600154811080156105ac5750600281610100811015610002570154600014155b156108b95760010161058c565b156103c557600160a060020a0383166000908152610102602052604081205492508214156105e7575061052c565b6001600160005054036000600050541115610602575061052c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610578610410565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561052c5760015482111561068d575061052e565b600082905561069a610410565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106f057600094506106f5565b600194505b5050505092915050565b1561052c575061010555565b1561052e5760006101065550565b60008681526101036020526040812080549094509092508214156107a2578154835560018381018390556101048054918201808255828015829011610771578183600052602060002091820191016107719190610885565b5050506002840181905561010480548892908110156100025760009190915260008051602061099483398151915201555b506001820154600284900a908116600014156108b05760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a182546001901161089d57600086815261010360205260409020600201546101048054909190811015610002576040600090812060008051602061099483398151915292909201819055808255600180830182905560029092015595506108b09050565b61010480546000808355919091526103c590600080516020610994833981519152908101905b808211156108995760008155600101610885565b5090565b8254600019018355600183018054821790555b50505050919050565b5b600180541180156108dc57506001546002906101008110156100025701546000145b156108f057600180546000190190556108ba565b600154811080156109135750600154600290610100811015610002570154600014155b801561092d57506002816101008110156100025701546000145b1561098e57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61058156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", "0x01" : "0x01", + "0x0107" : "0x0c22e4", "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x6e369836487c234b9e553ef3f787c2d8865520739d340c67b3d251a33986e58d" : "0x01" } @@ -879,13 +923,14 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d9811461007b5780632f54bf6e146100cd5780635c52c2f5146100fe5780637065cb4814610118578063b20d30a914610135578063b75c7dc614610152578063ba51a6df1461018f578063f00d4b5d146101ac57005b6101ce60043560006040600036808284379091209050610472815b73ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054818080838114156105bc5761071e565b6101d46004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b6101ce60406000368082843790912090506105ae81610096565b6101ce60043560406000368082843790912090506103c981610096565b6101ce60043560406000368082843790912090506105a281610096565b6101ce60043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156101de57610260565b6101ce600435604060003680828437909120905061055181610096565b6101ce600435602435600060406000368082843790912090506102d381610096565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561026057815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b156102cc576102e1836100d4565b156102ec57506102ce565b73ffffffffffffffffffffffffffffffffffffffff841660009081526101026020526040812054925082141561032257506102ce565b6103445b6101045460005b81811015610873576101048054829081106108bb57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061026757005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b156103c4576103d7826100d4565b156103e257506103c6565b6103ea610326565b60015460fa90101515610401576103ff610418565b505b60015460fa9010151561044257506103c6565b6105095b600060015b60015481101561075e575b600154811080156107ba575060028161010081106107b357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061036957005b156102ce5773ffffffffffffffffffffffffffffffffffffffff83166000908152610102602052604081205492508214156104ad57506103c4565b60016001600050540360006000505411156104c857506103c4565b600060028361010081106104d857005b015573ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812055610414610326565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b156103c45760015482111561056657506103c6565b6000829055610573610326565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b156103c4575061010655565b156103c65760006101055550565b60008681526101036020526040812080549094509092508214156106475781548355600183810183905561010480549182018082558280158290116106d3578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b808211156106d15760008155600101610626565b6000918252602090912001555b506001820154600284900a9081166000141561071e5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a182546001901115156106ed57600086815261010360205261010480546040909220600201549091811061072757005b505b505050600284018190556101048054889290811061063a57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b600091825260208083209091018290558782526101039052604081208181556001818101839055600290910191909155945061071e565b5090565b01546000145b156107c757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b600180541180156107685750600154600290610100811061076257005b0154600014155b1561079657600101610428565b600154811080156107eb575060015460029061010081106107e457005b0154600014155b80156108065750600281610100811061080057005b01546000145b1561081f57600154600290610100811061082457005b01555b61041d565b0154600282610100811061083457005b0155806101026000600283610100811061084a57005b015481526020810191909152604001600090812091909155600154600290610100811061081c57005b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156102cc57600081556001016108a7565b600091825260208220015414151561090d57610104805461010391600091849081106108e357005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b60010161032d56", + "code" : "0x606060405236156100985760e060020a6000350463173825d9811461009a5780632f54bf6e146100f65780634123cb6b1461011a5780635c52c2f5146101235780637065cb4814610154578063746c917114610188578063b20d30a914610191578063b75c7dc6146101c5578063ba51a6df146101f5578063c2cf732614610229578063f00d4b5d14610269578063f1736d86146102a2575b005b6100986004356000600036436040518084848082843750505090910190815260405190819003602001902090506105b9815b600160a060020a0333166000908152610102602052604081205481808083811415610719576108b0565b6102ac6004355b600160a060020a0316600090815261010260205260408120541190565b6102ac60015481565b6100986000364360405180848480828437505050909101908152604051908190036020019020905061070b816100cc565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610531816100cc565b6102ac60005481565b610098600435600036436040518084848082843750505090910190815260405190819003602001902090506106ff816100cc565b610098600435600160a060020a03331660009081526101026020526040812054908080838114156102be57610340565b61009860043560003643604051808484808284375050509091019081526040519081900360200190209050610678816100cc565b6102ac600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156106d1576106f5565b6100986004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506103ca816100cc565b6102ac6101055481565b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a92908316819011156103405781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a038316600283610100811015610002570155600160a060020a0384811660008181526101026020908152604080832083905593871680835291849020869055835192835282015281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156103c3576103d8836100fd565b156103e357506103c5565b600160a060020a03841660009081526101026020526040812054925082141561040c57506103c5565b6103475b6101045460005b8181101561085f576101048054829081101561000257600091825260008051602061099483398151915201541461048a5761010480546101039160009184908110156100025760008051602061099483398151915201548252506020919091526040812081815560018101829055600201555b600101610417565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b1561052c5761053f826100fd565b1561054a575061052e565b610552610410565b60015460fa90106105675761056561057c565b505b60015460fa9010610492575061052e565b6106365b600060015b600154811015610899575b600154811080156105ac5750600281610100811015610002570154600014155b156108b95760010161058c565b156103c557600160a060020a0383166000908152610102602052604081205492508214156105e7575061052c565b6001600160005054036000600050541115610602575061052c565b600060028361010081101561000257508301819055600160a060020a03841681526101026020526040812055610578610410565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b1561052c5760015482111561068d575061052e565b600082905561069a610410565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156106f057600094506106f5565b600194505b5050505092915050565b1561052c575061010555565b1561052e5760006101065550565b60008681526101036020526040812080549094509092508214156107a2578154835560018381018390556101048054918201808255828015829011610771578183600052602060002091820191016107719190610885565b5050506002840181905561010480548892908110156100025760009190915260008051602061099483398151915201555b506001820154600284900a908116600014156108b05760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a182546001901161089d57600086815261010360205260409020600201546101048054909190811015610002576040600090812060008051602061099483398151915292909201819055808255600180830182905560029092015595506108b09050565b61010480546000808355919091526103c590600080516020610994833981519152908101905b808211156108995760008155600101610885565b5090565b8254600019018355600183018054821790555b50505050919050565b5b600180541180156108dc57506001546002906101008110156100025701546000145b156108f057600180546000190190556108ba565b600154811080156109135750600154600290610100811015610002570154600014155b801561092d57506002816101008110156100025701546000145b1561098e57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61058156004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", "0x01" : "0x01", - "0x0104" : "0x09", - "0x0105" : "0xff", + "0x0104" : "0x01", + "0x0105" : "0x02", + "0x0107" : "0x0c22e4", "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x6e369836487c234b9e553ef3f787c2d8865520739d340c67b3d251a33986e58d" : "0x01" } @@ -921,8 +966,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107557f9adeddf84386b336eb7b3e18e7a6099be08fd81ea5d5142f4d2b630f8d20cf0160006040a1610ee9806100716000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", - "gasLimit" : "10000000", + "data" : "6060604052604051602080611014833960806040818152925160016000818155818055600160a060020a03331660038190558152610102909452938320939093556201518042046101075582917f102d25c49d33fcdb8976a3f2744e0785c98d9e43b88364859e6aec4ae82eff5c91a250610f958061007f6000396000f300606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x12343f", "gasPrice" : "1", "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -950,8 +995,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107557f9adeddf84386b336eb7b3e18e7a6099be08fd81ea5d5142f4d2b630f8d20cf0160006040a1610ee9806100716000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", - "gasLimit" : "0x1165fb", + "data" : "6060604052604051602080611014833960806040818152925160016000818155818055600160a060020a03331660038190558152610102909452938320939093556201518042046101075582917f102d25c49d33fcdb8976a3f2744e0785c98d9e43b88364859e6aec4ae82eff5c91a250610f958061007f6000396000f300606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x12343e", "gasPrice" : "1", "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -979,8 +1024,8 @@ } }, "transaction" : { - "data" : "600160008181558180553373ffffffffffffffffffffffffffffffffffffffff16600381905581526101026020526040902055620151804204610107557f9adeddf84386b336eb7b3e18e7a6099be08fd81ea5d5142f4d2b630f8d20cf0160006040a1610ee9806100716000396000f3007c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", - "gasLimit" : "0x05bff3", + "data" : "6060604052604051602080611014833960806040818152925160016000818155818055600160a060020a03331660038190558152610102909452938320939093556201518042046101075582917f102d25c49d33fcdb8976a3f2744e0785c98d9e43b88364859e6aec4ae82eff5c91a250610f958061007f6000396000f300606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "gasLimit" : "0x0607d6", "gasPrice" : "1", "nonce" : "1", "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", @@ -1008,7 +1053,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1056,7 +1101,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1097,7 +1142,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1138,7 +1183,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1179,7 +1224,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1220,12 +1265,54 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", "0x01" : "0x01", - "0x0106" : "0x0c22e4", + "0x0105" : "0x04", + "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", + "0x6e369836487c234b9e553ef3f787c2d8865520739d340c67b3d251a33986e58d" : "0x01" + } + } + }, + "transaction" : { + "data" : "0xb61d27f6000000000000000000000000aaaf5374fce5edbc8e2a8697c15331677e6ebaaa00000000000000000000000000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000060", + "gasLimit" : "10000000", + "gasPrice" : "1", + "nonce" : "1", + "secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8", + "to" : "ec0e71ad0a90ffe1909d27dac207f7680abba42d", + "value" : "0" + } + }, + + "walletExecuteOverDailyLimitOnlyOneOwnerNew" : { + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "256", + "currentGasLimit" : "10000000", + "currentNumber" : "0", + "currentTimestamp" : "0xfffffffff", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "pre" : { + "a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : { + "balance" : "0x0de0b6b3a75ef08f", + "code" : "0x", + "nonce" : "0x01", + "storage" : { + } + }, + "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { + "balance" : "0x64", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", + "nonce" : "0x00", + "storage" : { + "0x00" : "0x01", + "0x01" : "0x01", + "0x0106" : "0x04", + "0x0107" : "0x0c22e4", "0x03" : "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b", "0x6e369836487c234b9e553ef3f787c2d8865520739d340c67b3d251a33986e58d" : "0x01" } @@ -1261,7 +1348,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x02", @@ -1310,7 +1397,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x02", @@ -1359,7 +1446,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1408,7 +1495,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1464,7 +1551,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1520,7 +1607,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", @@ -1576,7 +1663,7 @@ }, "ec0e71ad0a90ffe1909d27dac207f7680abba42d" : { "balance" : "0x64", - "code" : "0x7c01000000000000000000000000000000000000000000000000000000006000350463173825d981146100ed5780632f54bf6e1461013f5780635c52c2f5146101705780637065cb481461018a578063797af627146101a7578063b20d30a9146101ba578063b61d27f6146101d7578063b75c7dc6146101fe578063ba51a6df1461023b578063cbf0b0c014610258578063f00d4b5d146102755761029760003411156100eb5773ffffffffffffffffffffffffffffffffffffffff33166040908152346060527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9080a15b565b61029760043560006040600036808284379091209050610542815b73ffffffffffffffffffffffffffffffffffffffff33166000908152610102602052604081205481808083811415610a7c57610bde565b61029d6004355b73ffffffffffffffffffffffffffffffffffffffff16600090815261010260205260408120541190565b610297604060003680828437909120905061067e81610108565b610297600435604060003680828437909120905061049981610108565b61029d6004355b6000816108bb81610108565b610297600435604060003680828437909120905061067281610108565b61029d6004803590602480359160443591820191013560006106aa846000610d3333610146565b61029760043573ffffffffffffffffffffffffffffffffffffffff331660009081526101026020526040812054908080838114156102a757610329565b610297600435604060003680828437909120905061062181610108565b610297600435604060003680828437909120905061068c81610108565b6102976004356024356000604060003680828437909120905061039c81610108565b60006000f35b8060005260206000f35b5050506000828152610103602052604081206001810154600284900a929083168190111561032957815460018084018054919092018455849003905573ffffffffffffffffffffffffffffffffffffffff3316604090815260608690527fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b9080a15b5050505050565b015573ffffffffffffffffffffffffffffffffffffffff84811660008181526101026020526040808220829055928616808252908390208590559082526060527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9080a15b505b505050565b15610395576103aa83610146565b156103b55750610397565b73ffffffffffffffffffffffffffffffffffffffff84166000908152610102602052604081205492508214156103eb5750610397565b6104145b6101045460005b81811015610d9e5761010480546101089160009184908110610dbf57005b73ffffffffffffffffffffffffffffffffffffffff8316600283610100811061033057005b015560015473ffffffffffffffffffffffffffffffffffffffff831660008181526101026020908152604091829020939093559081527f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c39190a15b505b50565b15610494576104a782610146565b156104b25750610496565b6104ba6103ef565b60015460fa901015156104d1576104cf6104e8565b505b60015460fa901015156105125750610496565b6105d95b600060015b600154811015610c1e575b60015481108015610c7a57506002816101008110610c7357005b6001805481019081905573ffffffffffffffffffffffffffffffffffffffff831690600290610100811061043957005b156103975773ffffffffffffffffffffffffffffffffffffffff831660009081526101026020526040812054925082141561057d5750610494565b60016001600050540360006000505411156105985750610494565b600060028361010081106105a857005b015573ffffffffffffffffffffffffffffffffffffffff8316600090815261010260205260408120556104e46103ef565b5073ffffffffffffffffffffffffffffffffffffffff831660409081527f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da90602090a1505050565b15610494576001548211156106365750610496565b60008290556106436103ef565b60408281527facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da90602090a15050565b15610494575061010655565b156104965760006101055550565b15610494578173ffffffffffffffffffffffffffffffffffffffff16ff5b156107485773ffffffffffffffffffffffffffffffffffffffff3381166040526060859052851660805260a08290527f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd004838360c082828082843750505060800190506040a18473ffffffffffffffffffffffffffffffffffffffff16846000600060008787808284378201915050600084866185025a03f161076157005b604060003680828437909120915061076d9050816101ae565b50600091506108949050565b15801561079d57506000818152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff16145b1561089457600081815261010860209081526040822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001688178155600181018790556002018054858255818452928290209092601f0191909104810190849086821561089c579182015b8281111561089c57823582600050559160200191906001019061080a565b505050604081905273ffffffffffffffffffffffffffffffffffffffff3381166060526080859052851660a05260c08290527f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf32838360e0828280828437505060a0909101915060409050a15b949350505050565b5090505b8082111561082857600081556001016108a0565b505b919050565b156108b4576000838152610108602052604081205473ffffffffffffffffffffffffffffffffffffffff161415156108b45760406000908120805460018201546002909201805473ffffffffffffffffffffffffffffffffffffffff92909216939182918291801561094357915260208220825b81548152906001019060200180831161092f575b5050600084866185025a03f161095557005b505073ffffffffffffffffffffffffffffffffffffffff3381166040908152606085905260008581526101086020529081206001810154608052805490921660a0526002909101805460c08190527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a929060e090839080156109f357820191906000526020600020905b8154815290600101906020018083116109df575b5050915050604090036040a1600083815261010860209081526040822080547fffffffffffffffffffffffff000000000000000000000000000000000000000016815560018101839055600281018054848255908452828420919392601f91909101048101905b80821115610a6e5760008155600101610a5a565b5050505060019150506108b6565b6000868152610103602052604081208054909450909250821415610b07578154835560018381018390556101048054918201808255828015829011610b93578286527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe9081019082015b80821115610b915760008155600101610ae6565b6000918252602090912001555b506001820154600284900a90811660001415610bde5773ffffffffffffffffffffffffffffffffffffffff3316604090815260608790527fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda9080a18254600190111515610bad576000868152610103602052610104805460409092206002015490918110610be757005b505b5050506002840181905561010480548892908110610afa57005b82547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018355600183018054821790555b50505050919050565b6000918252602080832090910182905587825261010390526040812081815560018181018390556002909101919091559450610bde565b5090565b01546000145b15610c8757600180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190555b60018054118015610c2857506001546002906101008110610c2257005b0154600014155b15610c56576001016104f8565b60015481108015610cab57506001546002906101008110610ca457005b0154600014155b8015610cc657506002816101008110610cc057005b01546000145b15610cdf576001546002906101008110610ce457005b01555b6104ed565b01546002826101008110610cf457005b01558061010260006002836101008110610d0a57005b0154815260208101919091526040016000908120919091556001546002906101008110610cdc57005b156108b65761010754610d495b62015180420490565b1115610d6257600061010555610d5d610d40565b610107555b6101055480830110158015610d805750610105546101065490830111155b15610d96575061010580548201905560016108b6565b5060006108b6565b6104946101045460005b81811015610e4757610104805482908110610e8f57005b6000918252602080832090910154835282810193909352604091909101812080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155600181018290556002810180548382559083528383209193601f91909101048101905b80821115610e3b5760008155600101610e27565b505050506001016103f6565b61010480546000808355919091527f4c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe908101905b808211156103955760008155600101610e7b565b6000918252602082200154141515610ee15761010480546101039160009184908110610eb757005b60009182526020808320909101548352820192909252604001812081815560018101829055600201555b600101610da856", + "code" : "0x606060405236156100b95760e060020a6000350463173825d9811461010b5780632f54bf6e146101675780634123cb6b1461018f5780635c52c2f5146101985780637065cb48146101c9578063746c9171146101fd578063797af62714610206578063b20d30a914610219578063b61d27f61461024d578063b75c7dc61461026e578063ba51a6df1461029e578063c2cf7326146102d2578063cbf0b0c014610312578063f00d4b5d14610346578063f1736d861461037f575b61038960003411156101095760408051600160a060020a033316815234602082015281517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c929181900390910190a15b565b610389600435600060003643604051808484808284375050509091019081526040519081900360200190209050610693815b600160a060020a0333166000908152610102602052604081205481808083811415610c1357610d6c565b61038b6004355b600160a060020a03811660009081526101026020526040812054115b919050565b61038b60015481565b610389600036436040518084848082843750505090910190815260405190819003602001902090506107e58161013d565b6103896004356000364360405180848480828437505050909101908152604051908190036020019020905061060b8161013d565b61038b60005481565b61038b6004355b600081610a4b8161013d565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107d98161013d565b61038b6004803590602480359160443591820191013560006108043361016e565b610389600435600160a060020a033316600090815261010260205260408120549080808381141561039d5761041f565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107528161013d565b61038b600435602435600082815261010360209081526040808320600160a060020a0385168452610102909252822054829081818114156107ab576107cf565b610389600435600036436040518084848082843750505090910190815260405190819003602001902090506107f38161013d565b6103896004356024356000600036436040518084848082843750505090910190815260405190819003602001902090506104ac8161013d565b61038b6101055481565b005b60408051918252519081900360200190f35b5050506000828152610103602052604081206001810154600284900a929083168190111561041f5781546001838101805492909101845590849003905560408051600160a060020a03331681526020810187905281517fc7fb647e59b18047309aa15aad418e5d7ca96d173ad704f1031a2c3d7591734b929181900390910190a15b5050505050565b600160a060020a03831660028361010081101561000257508301819055600160a060020a03851660008181526101026020908152604080832083905584835291829020869055815192835282019290925281517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c929181900390910190a15b505b505050565b156104a5576104ba8361016e565b156104c557506104a7565b600160a060020a0384166000908152610102602052604081205492508214156104ee57506104a7565b6104265b6101045460005b81811015610eba57610104805461010891600091849081101561000257600080516020610f7583398151915201548252506020918252604081208054600160a060020a0319168155600181018290556002810180548382559083528383209193610f3f92601f9290920104810190610a33565b60018054810190819055600160a060020a038316906002906101008110156100025790900160005081905550600160005054610102600050600084600160a060020a03168152602001908152602001600020600050819055507f994a936646fe87ffe4f1e469d3d6aa417d6b855598397f323de5b449f765f0c3826040518082600160a060020a0316815260200191505060405180910390a15b505b50565b15610606576106198261016e565b156106245750610608565b61062c6104f2565b60015460fa90106106415761063f610656565b505b60015460fa901061056c5750610608565b6107105b600060015b600154811015610a47575b600154811080156106865750600281610100811015610002570154600014155b15610d7557600101610666565b156104a757600160a060020a0383166000908152610102602052604081205492508214156106c15750610606565b60016001600050540360006000505411156106dc5750610606565b600060028361010081101561000257508301819055600160a060020a038416815261010260205260408120556106526104f2565b5060408051600160a060020a038516815290517f58619076adf5bb0943d100ef88d52d7c3fd691b19d3a9071b555b651fbf418da9181900360200190a1505050565b15610606576001548211156107675750610608565b60008290556107746104f2565b6040805183815290517facbdb084c721332ac59f9b8e392196c9eb0e4932862da8eb9beaf0dad4f550da9181900360200190a15050565b506001830154600282900a908116600014156107ca57600094506107cf565b600194505b5050505092915050565b15610606575061010555565b156106085760006101065550565b156106065781600160a060020a0316ff5b15610a2357610818846000610e4f3361016e565b156108d4577f92ca3a80853e6663fa31fa10b99225f18d4902939b4c53a9caae9043f6efd00433858786866040518086600160a060020a0316815260200185815260200184600160a060020a031681526020018060200182810382528484828181526020019250808284378201915050965050505050505060405180910390a184600160a060020a03168484846040518083838082843750505090810191506000908083038185876185025a03f15060009350610a2392505050565b6000364360405180848480828437505050909101908152604051908190036020019020915061090490508161020d565b158015610927575060008181526101086020526040812054600160a060020a0316145b15610a235760008181526101086020908152604082208054600160a060020a03191688178155600181018790556002018054858255818452928290209092601f01919091048101908490868215610a2b579182015b82811115610a2b57823582600050559160200191906001019061097c565b50600050507f1733cbb53659d713b79580f79f3f9ff215f78a7c7aa45890f3b89fc5cddfbf328133868887876040518087815260200186600160a060020a0316815260200185815260200184600160a060020a03168152602001806020018281038252848482818152602001925080828437820191505097505050505050505060405180910390a15b949350505050565b5061099a9291505b80821115610a475760008155600101610a33565b5090565b15610c005760008381526101086020526040812054600160a060020a031614610c0057604080516000918220805460018201546002929092018054600160a060020a0392909216949293909291819084908015610acd57820191906000526020600020905b815481529060010190602001808311610ab057829003601f168201915b50509250505060006040518083038185876185025a03f1505050600084815261010860209081526040805181842080546001820154600160a060020a033381811686529685018c905294840181905293166060830181905260a06080840181815260029390930180549185018290527fe7c957c06e9a662c1a6c77366179f5b702b97651dc28eee7d5bf1dff6e40bb4a985095968b969294929390929160c083019085908015610ba257820191906000526020600020905b815481529060010190602001808311610b8557829003601f168201915b505097505050505050505060405180910390a160008381526101086020908152604082208054600160a060020a031916815560018101839055600281018054848255908452828420919392610c0692601f9290920104810190610a33565b50919050565b505050600191505061018a565b6000868152610103602052604081208054909450909250821415610c9c578154835560018381018390556101048054918201808255828015829011610c6b57818360005260206000209182019101610c6b9190610a33565b50505060028401819055610104805488929081101561000257600091909152600080516020610f7583398151915201555b506001820154600284900a90811660001415610d6c5760408051600160a060020a03331681526020810188905281517fe1c52dc63b719ade82e8bea94cc41a0d5d28e4aaf536adb5e9cccc9ff8c1aeda929181900390910190a1825460019011610d59576000868152610103602052604090206002015461010480549091908110156100025760406000908120600080516020610f758339815191529290920181905580825560018083018290556002909201559550610d6c9050565b8254600019018355600183018054821790555b50505050919050565b5b60018054118015610d9857506001546002906101008110156100025701546000145b15610dac5760018054600019019055610d76565b60015481108015610dcf5750600154600290610100811015610002570154600014155b8015610de957506002816101008110156100025701546000145b15610e4a57600154600290610100811015610002578101549082610100811015610002578101919091558190610102906000908361010081101561000257810154825260209290925260408120929092556001546101008110156100025701555b61065b565b1561018a5761010754610e655b62015180420490565b1115610e7e57600061010655610e79610e5c565b610107555b6101065480830110801590610e9c5750610106546101055490830111155b15610eb25750610106805482019055600161018a565b50600061018a565b6106066101045460005b81811015610f4a5761010480548290811015610002576000918252600080516020610f75833981519152015414610f3757610104805461010391600091849081101561000257600080516020610f7583398151915201548252506020919091526040812081815560018101829055600201555b600101610ec4565b5050506001016104f9565b61010480546000808355919091526104a790600080516020610f7583398151915290810190610a3356004c0be60200faa20559308cb7b5a1bb3255c16cb1cab91f525b5ae7a03d02fabe", "nonce" : "0x00", "storage" : { "0x00" : "0x01", diff --git a/test/libethereum/blockchain.cpp b/test/libethereum/blockchain.cpp index 0314de78b..20f60618f 100644 --- a/test/libethereum/blockchain.cpp +++ b/test/libethereum/blockchain.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include using namespace std; @@ -200,8 +201,8 @@ void doBlockchainTests(json_spirit::mValue& _v, bool _fillin) //get valid transactions Transactions txList; - for (auto const& txi: txs.transactions()) - txList.push_back(txi.second); + for (auto const& txi: txs.topTransactions(std::numeric_limits::max())) + txList.push_back(txi); blObj["transactions"] = writeTransactionsToJson(txList); BlockInfo current_BlockHeader = state.info(); @@ -836,6 +837,11 @@ BOOST_AUTO_TEST_CASE(bcBruncleTest) dev::test::executeTests("bcBruncleTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); } +BOOST_AUTO_TEST_CASE(bcBlockGasLimitTest) +{ + dev::test::executeTests("bcBlockGasLimitTest", "/BlockchainTests",dev::test::getFolder(__FILE__) + "/BlockchainTestsFiller", dev::test::doBlockchainTests); +} + BOOST_AUTO_TEST_CASE(bcWalletTest) { if (test::Options::get().wallet) diff --git a/test/libethereum/gaspricer.cpp b/test/libethereum/gaspricer.cpp index 105f4c2d7..ce49a4a20 100644 --- a/test/libethereum/gaspricer.cpp +++ b/test/libethereum/gaspricer.cpp @@ -20,10 +20,9 @@ */ #include -#include #include -#include -#include +#include +#include #include "../TestHelper.h" using namespace std; diff --git a/test/libethereum/state.cpp b/test/libethereum/state.cpp index a134d024f..45c2fa13e 100644 --- a/test/libethereum/state.cpp +++ b/test/libethereum/state.cpp @@ -129,11 +129,6 @@ BOOST_AUTO_TEST_CASE(stPreCompiledContracts) dev::test::executeTests("stPreCompiledContracts", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); } -BOOST_AUTO_TEST_CASE(stPreCompiledContractsTransaction) -{ - dev::test::executeTests("stPreCompiledContractsTransaction", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); -} - BOOST_AUTO_TEST_CASE(stLogTests) { dev::test::executeTests("stLogTests", "/StateTests",dev::test::getFolder(__FILE__) + "/StateTestsFiller", dev::test::doStateTests); diff --git a/test/libethereum/transactionqueue.cpp b/test/libethereum/transactionqueue.cpp new file mode 100644 index 000000000..aa76681c5 --- /dev/null +++ b/test/libethereum/transactionqueue.cpp @@ -0,0 +1,172 @@ +/* + 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 transactionqueue.cpp + * @author Christoph Jentzsch + * @date 2015 + * TransactionQueue test functions. + */ + +#include +#include "../TestHelper.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + +BOOST_AUTO_TEST_SUITE(TransactionQueue) + +BOOST_AUTO_TEST_CASE(maxNonce) +{ + + dev::eth::TransactionQueue txq; + + // from a94f5374fce5edbc8e2a8697c15331677e6ebf0b + const u256 gasCost = 10 * szabo; + const u256 gas = 25000; + Address dest = Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"); + Address to = Address("0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"); + Secret sec = Secret("0x45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8"); + Transaction tx0(0, gasCost, gas, dest, bytes(), 0, sec ); + Transaction tx0_1(1, gasCost, gas, dest, bytes(), 0, sec ); + Transaction tx1(0, gasCost, gas, dest, bytes(), 1, sec ); + Transaction tx2(0, gasCost, gas, dest, bytes(), 2, sec ); + Transaction tx9(0, gasCost, gas, dest, bytes(), 9, sec ); + + txq.import(tx0); + BOOST_CHECK(1 == txq.maxNonce(to)); + txq.import(tx0); + BOOST_CHECK(1 == txq.maxNonce(to)); + txq.import(tx0_1); + BOOST_CHECK(1 == txq.maxNonce(to)); + txq.import(tx1); + BOOST_CHECK(2 == txq.maxNonce(to)); + txq.import(tx9); + BOOST_CHECK(10 == txq.maxNonce(to)); + txq.import(tx2); + BOOST_CHECK(10 == txq.maxNonce(to)); + +} + +BOOST_AUTO_TEST_CASE(priority) +{ + dev::eth::TransactionQueue txq; + + const u256 gasCostCheap = 10 * szabo; + const u256 gasCostMed = 20 * szabo; + const u256 gasCostHigh = 30 * szabo; + const u256 gas = 25000; + Address dest = Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"); + Secret sender1 = Secret("0x3333333333333333333333333333333333333333333333333333333333333333"); + Secret sender2 = Secret("0x4444444444444444444444444444444444444444444444444444444444444444"); + Transaction tx0(0, gasCostCheap, gas, dest, bytes(), 0, sender1 ); + Transaction tx0_1(1, gasCostMed, gas, dest, bytes(), 0, sender1 ); + Transaction tx1(0, gasCostCheap, gas, dest, bytes(), 1, sender1 ); + Transaction tx2(0, gasCostHigh, gas, dest, bytes(), 0, sender2 ); + Transaction tx3(0, gasCostCheap + 1, gas, dest, bytes(), 1, sender2 ); + Transaction tx4(0, gasCostHigh, gas, dest, bytes(), 2, sender1 ); + Transaction tx5(0, gasCostMed, gas, dest, bytes(), 2, sender2 ); + + txq.import(tx0); + BOOST_CHECK(Transactions { tx0 } == txq.topTransactions(256)); + txq.import(tx0); + BOOST_CHECK(Transactions { tx0 } == txq.topTransactions(256)); + txq.import(tx0_1); + BOOST_CHECK(Transactions { tx0_1 } == txq.topTransactions(256)); + txq.import(tx1); + BOOST_CHECK((Transactions { tx0_1, tx1 }) == txq.topTransactions(256)); + txq.import(tx2); + BOOST_CHECK((Transactions { tx2, tx0_1, tx1 }) == txq.topTransactions(256)); + txq.import(tx3); + BOOST_CHECK((Transactions { tx2, tx0_1, tx1, tx3 }) == txq.topTransactions(256)); + txq.import(tx4); + BOOST_CHECK((Transactions { tx2, tx0_1, tx1, tx3, tx4 }) == txq.topTransactions(256)); + txq.import(tx5); + BOOST_CHECK((Transactions { tx2, tx0_1, tx1, tx3, tx5, tx4 }) == txq.topTransactions(256)); + + txq.drop(tx0_1.sha3()); + BOOST_CHECK((Transactions { tx2, tx1, tx3, tx5, tx4 }) == txq.topTransactions(256)); + txq.drop(tx1.sha3()); + BOOST_CHECK((Transactions { tx2, tx3, tx5, tx4 }) == txq.topTransactions(256)); + txq.drop(tx5.sha3()); + BOOST_CHECK((Transactions { tx2, tx3, tx4 }) == txq.topTransactions(256)); + + Transaction tx6(0, gasCostMed, gas, dest, bytes(), 20, sender1 ); + txq.import(tx6); + BOOST_CHECK((Transactions { tx2, tx3, tx4, tx6 }) == txq.topTransactions(256)); + + Transaction tx7(0, gasCostMed, gas, dest, bytes(), 2, sender2 ); + txq.import(tx7); + BOOST_CHECK((Transactions { tx2, tx3, tx4, tx6, tx7 }) == txq.topTransactions(256)); +} + +BOOST_AUTO_TEST_CASE(future) +{ + dev::eth::TransactionQueue txq; + + // from a94f5374fce5edbc8e2a8697c15331677e6ebf0b + const u256 gasCostMed = 20 * szabo; + const u256 gas = 25000; + Address dest = Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"); + Secret sender = Secret("0x3333333333333333333333333333333333333333333333333333333333333333"); + Transaction tx0(0, gasCostMed, gas, dest, bytes(), 0, sender ); + Transaction tx1(0, gasCostMed, gas, dest, bytes(), 1, sender ); + Transaction tx2(0, gasCostMed, gas, dest, bytes(), 2, sender ); + Transaction tx3(0, gasCostMed, gas, dest, bytes(), 3, sender ); + Transaction tx4(0, gasCostMed, gas, dest, bytes(), 4, sender ); + + txq.import(tx0); + txq.import(tx1); + txq.import(tx2); + txq.import(tx3); + txq.import(tx4); + BOOST_CHECK((Transactions { tx0, tx1, tx2, tx3, tx4 }) == txq.topTransactions(256)); + + txq.setFuture(tx2.sha3()); + BOOST_CHECK((Transactions { tx0, tx1 }) == txq.topTransactions(256)); + + Transaction tx2_2(1, gasCostMed, gas, dest, bytes(), 2, sender ); + txq.import(tx2_2); + BOOST_CHECK((Transactions { tx0, tx1, tx2_2, tx3, tx4 }) == txq.topTransactions(256)); +} + + +BOOST_AUTO_TEST_CASE(lmits) +{ + dev::eth::TransactionQueue txq(3, 3); + const u256 gasCostMed = 20 * szabo; + const u256 gas = 25000; + Address dest = Address("0x095e7baea6a6c7c4c2dfeb977efac326af552d87"); + Secret sender = Secret("0x3333333333333333333333333333333333333333333333333333333333333333"); + Secret sender2 = Secret("0x4444444444444444444444444444444444444444444444444444444444444444"); + Transaction tx0(0, gasCostMed, gas, dest, bytes(), 0, sender ); + Transaction tx1(0, gasCostMed, gas, dest, bytes(), 1, sender ); + Transaction tx2(0, gasCostMed, gas, dest, bytes(), 2, sender ); + Transaction tx3(0, gasCostMed, gas, dest, bytes(), 3, sender ); + Transaction tx4(0, gasCostMed, gas, dest, bytes(), 4, sender ); + Transaction tx5(0, gasCostMed + 1, gas, dest, bytes(), 0, sender2 ); + + txq.import(tx0); + txq.import(tx1); + txq.import(tx2); + txq.import(tx3); + txq.import(tx4); + txq.import(tx5); + BOOST_CHECK((Transactions { tx5, tx0, tx1 }) == txq.topTransactions(256)); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libp2p/peer.cpp b/test/libp2p/peer.cpp index 8f37ce164..e84e86027 100644 --- a/test/libp2p/peer.cpp +++ b/test/libp2p/peer.cpp @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(host) auto node2 = host2.id(); host2.start(); - while (!host2.isStarted()) + while (!host2.haveNetwork()) this_thread::sleep_for(chrono::milliseconds(20)); host1.addNode(node2, NodeIPEndpoint(bi::address::from_string("127.0.0.1"), host2prefs.listenPort, host2prefs.listenPort)); diff --git a/test/libp2p/rlpx.cpp b/test/libp2p/rlpx.cpp index 6d5e59733..8251e94e2 100644 --- a/test/libp2p/rlpx.cpp +++ b/test/libp2p/rlpx.cpp @@ -21,7 +21,6 @@ */ #include -#include #include #include #include diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index a2dbc35e6..ad2175461 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -564,20 +564,6 @@ BOOST_AUTO_TEST_CASE(strings) BOOST_CHECK(callContractFunction("pipeThrough(bytes2,bool)", string("\0\x02", 2), true) == encodeArgs(string("\0\x2", 2), true)); } -BOOST_AUTO_TEST_CASE(empty_string_on_stack) -{ - char const* sourceCode = R"( - contract test { - function run() external returns(bytes2 ret) { - var y = ""; - ret = y; - } - } - )"; - compileAndRun(sourceCode); - BOOST_CHECK(callContractFunction("run()") == encodeArgs(byte(0x00))); -} - BOOST_AUTO_TEST_CASE(inc_dec_operators) { char const* sourceCode = R"( @@ -4806,6 +4792,232 @@ BOOST_AUTO_TEST_CASE(memory_arrays_dynamic_index_access_write) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(0x20), u256(4), data)); } +BOOST_AUTO_TEST_CASE(memory_structs_read_write) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; uint8[2] a; } + S[5] data; + function testInit() returns (uint8 x, uint16 y, uint z, uint8 a, bool flag) { + S[2] memory d; + x = d[0].x; + y = d[0].y; + z = d[0].z; + a = d[0].a[1]; + flag = true; + } + function testCopyRead() returns (uint8 x, uint16 y, uint z, uint8 a) { + data[2].x = 1; + data[2].y = 2; + data[2].z = 3; + data[2].a[1] = 4; + S memory s = data[2]; + x = s.x; + y = s.y; + z = s.z; + a = s.a[1]; + } + function testAssign() returns (uint8 x, uint16 y, uint z, uint8 a) { + S memory s; + s.x = 1; + s.y = 2; + s.z = 3; + s.a[1] = 4; + x = s.x; + y = s.y; + z = s.z; + a = s.a[1]; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + BOOST_CHECK(callContractFunction("testInit()") == encodeArgs(u256(0), u256(0), u256(0), u256(0), true)); + BOOST_CHECK(callContractFunction("testCopyRead()") == encodeArgs(u256(1), u256(2), u256(3), u256(4))); + BOOST_CHECK(callContractFunction("testAssign()") == encodeArgs(u256(1), u256(2), u256(3), u256(4))); +} + +BOOST_AUTO_TEST_CASE(memory_structs_as_function_args) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; } + function test() returns (uint x, uint y, uint z) { + S memory data = combine(1, 2, 3); + x = extract(data, 0); + y = extract(data, 1); + z = extract(data, 2); + } + function extract(S s, uint which) internal returns (uint x) { + if (which == 0) return s.x; + else if (which == 1) return s.y; + else return s.z; + } + function combine(uint8 x, uint16 y, uint z) internal returns (S s) { + s.x = x; + s.y = y; + s.z = z; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(1), u256(2), u256(3))); +} + +BOOST_AUTO_TEST_CASE(memory_structs_nested) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; } + struct X { uint8 x; S s; } + function test() returns (uint a, uint x, uint y, uint z) { + X memory d = combine(1, 2, 3, 4); + a = extract(d, 0); + x = extract(d, 1); + y = extract(d, 2); + z = extract(d, 3); + } + function extract(X s, uint which) internal returns (uint x) { + if (which == 0) return s.x; + else if (which == 1) return s.s.x; + else if (which == 2) return s.s.y; + else return s.s.z; + } + function combine(uint8 a, uint8 x, uint16 y, uint z) internal returns (X s) { + s.x = a; + s.s.x = x; + s.s.y = y; + s.s.z = z; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(1), u256(2), u256(3), u256(4))); +} + +BOOST_AUTO_TEST_CASE(memory_structs_nested_load) +{ + char const* sourceCode = R"( + contract Test { + struct S { uint8 x; uint16 y; uint z; } + struct X { uint8 x; S s; uint8[2] a; } + X m_x; + function load() returns (uint a, uint x, uint y, uint z, uint a1, uint a2) { + m_x.x = 1; + m_x.s.x = 2; + m_x.s.y = 3; + m_x.s.z = 4; + m_x.a[0] = 5; + m_x.a[1] = 6; + X memory d = m_x; + a = d.x; + x = d.s.x; + y = d.s.y; + z = d.s.z; + a1 = d.a[0]; + a2 = d.a[1]; + } + function store() returns (uint a, uint x, uint y, uint z, uint a1, uint a2) { + X memory d; + d.x = 1; + d.s.x = 2; + d.s.y = 3; + d.s.z = 4; + d.a[0] = 5; + d.a[1] = 6; + m_x = d; + a = m_x.x; + x = m_x.s.x; + y = m_x.s.y; + z = m_x.s.z; + a1 = m_x.a[0]; + a2 = m_x.a[1]; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + + auto out = encodeArgs(u256(1), u256(2), u256(3), u256(4), u256(5), u256(6)); + BOOST_CHECK(callContractFunction("load()") == out); + BOOST_CHECK(callContractFunction("store()") == out); +} + +BOOST_AUTO_TEST_CASE(struct_constructor_nested) +{ + char const* sourceCode = R"( + contract C { + struct X { uint x1; uint x2; } + struct S { uint s1; uint[3] s2; X s3; } + S s; + function C() { + uint[3] memory s2; + s2[1] = 9; + s = S(1, s2, X(4, 5)); + } + function get() returns (uint s1, uint[3] s2, uint x1, uint x2) + { + s1 = s.s1; + s2 = s.s2; + x1 = s.s3.x1; + x2 = s.s3.x2; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + + auto out = encodeArgs(u256(1), u256(0), u256(9), u256(0), u256(4), u256(5)); + BOOST_CHECK(callContractFunction("get()") == out); +} + +BOOST_AUTO_TEST_CASE(struct_named_constructor) +{ + char const* sourceCode = R"( + contract C { + struct S { uint a; bool x; } + S public s; + function C() { + s = S({a: 1, x: true}); + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + + BOOST_CHECK(callContractFunction("s()") == encodeArgs(u256(1), true)); +} + +BOOST_AUTO_TEST_CASE(literal_strings) +{ + char const* sourceCode = R"( + contract Test { + string public long; + string public medium; + string public short; + string public empty; + function f() returns (string) { + long = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + medium = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; + short = "123"; + empty = ""; + return "Hello, World!"; + } + } + )"; + compileAndRun(sourceCode, 0, "Test"); + string longStr = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678900123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789001234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + string medium = "01234567890123456789012345678901234567890123456789012345678901234567890123456789"; + string shortStr = "123"; + string hello = "Hello, World!"; + + BOOST_CHECK(callContractFunction("f()") == encodeDyn(hello)); + BOOST_CHECK(callContractFunction("long()") == encodeDyn(longStr)); + BOOST_CHECK(callContractFunction("medium()") == encodeDyn(medium)); + BOOST_CHECK(callContractFunction("short()") == encodeDyn(shortStr)); + BOOST_CHECK(callContractFunction("empty()") == encodeDyn(string())); +} + + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 4914ef975..1e40ee4f6 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -283,7 +283,7 @@ BOOST_AUTO_TEST_CASE(large_string_literal) char const* text = "contract test {\n" " function f() { var x = \"123456789012345678901234567890123\"; }" "}\n"; - BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); } BOOST_AUTO_TEST_CASE(balance) @@ -2056,6 +2056,60 @@ BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable) BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError); } +BOOST_AUTO_TEST_CASE(struct_constructor) +{ + char const* sourceCode = R"( + contract C { + struct S { uint a; bool x; } + function f() { + S memory s = S(1, true); + } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); +} + +BOOST_AUTO_TEST_CASE(struct_constructor_nested) +{ + char const* sourceCode = R"( + contract C { + struct X { uint x1; uint x2; } + struct S { uint s1; uint[3] s2; X s3; } + function f() { + uint[3] memory s2; + S memory s = S(1, s2, X(4, 5)); + } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); +} + +BOOST_AUTO_TEST_CASE(struct_named_constructor) +{ + char const* sourceCode = R"( + contract C { + struct S { uint a; bool x; } + function f() { + S memory s = S({a: 1, x: true}); + } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode)); +} + +BOOST_AUTO_TEST_CASE(literal_strings) +{ + char const* text = R"( + contract Foo { + function f() { + string memory long = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + string memory short = "123"; + } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityWallet.cpp b/test/libsolidity/SolidityWallet.cpp index ba8f198f8..1c296b9f7 100644 --- a/test/libsolidity/SolidityWallet.cpp +++ b/test/libsolidity/SolidityWallet.cpp @@ -47,12 +47,18 @@ static char const* walletCode = R"DELIMITER( // some number (specified in constructor) of the set of owners (specified in the constructor, modifiable) before the // interior is executed. contract multiowned { + + // TYPES + // struct for the status of a pending operation. struct PendingState { uint yetNeeded; uint ownersDone; uint index; } + + // EVENTS + // this contract only has five types of events: it can accept a confirmation, in which case // we record owner and operation (hash) alongside it. event Confirmation(address owner, bytes32 operation); @@ -63,14 +69,9 @@ contract multiowned { event OwnerRemoved(address oldOwner); // the last one is emitted if the required signatures change event RequirementChanged(uint newRequirement); - // constructor is given number of sigs required to do protected "onlymanyowners" transactions - // as well as the selection of addresses capable of confirming them. - function multiowned() { - m_required = 1; - m_numOwners = 1; - m_owners[m_numOwners] = uint(msg.sender); - m_ownerIndex[uint(msg.sender)] = m_numOwners; - } + + // MODIFIERS + // simple single-sig function modifier. modifier onlyowner { if (isOwner(msg.sender)) @@ -80,9 +81,21 @@ contract multiowned { // that later attempts can be realised as the same underlying operation and // thus count as confirmations. modifier onlymanyowners(bytes32 _operation) { - if (confirmed(_operation)) + if (confirmAndCheck(_operation)) _ } + + // METHODS + + // constructor is given number of sigs required to do protected "onlymanyowners" transactions + // as well as the selection of addresses capable of confirming them. + function multiowned() { + m_required = 1; + m_numOwners = 1; + m_owners[m_numOwners] = uint(msg.sender); + m_ownerIndex[uint(msg.sender)] = m_numOwners; + } + // Revokes a prior confirmation of the given operation function revoke(bytes32 _operation) external { uint ownerIndex = m_ownerIndex[uint(msg.sender)]; @@ -96,7 +109,75 @@ contract multiowned { Revoke(msg.sender, _operation); } } - function confirmed(bytes32 _operation) internal returns (bool) { + + // Replaces an owner `_from` with another `_to`. + function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data, block.number)) external { + if (isOwner(_to)) return; + uint ownerIndex = m_ownerIndex[uint(_from)]; + if (ownerIndex == 0) return; + + clearPending(); + m_owners[ownerIndex] = uint(_to); + m_ownerIndex[uint(_from)] = 0; + m_ownerIndex[uint(_to)] = ownerIndex; + OwnerChanged(_from, _to); + } + function addOwner(address _owner) onlymanyowners(sha3(msg.data, block.number)) external { + if (isOwner(_owner)) return; + + clearPending(); + if (m_numOwners >= c_maxOwners) + reorganizeOwners(); + if (m_numOwners >= c_maxOwners) + return; + m_numOwners++; + m_owners[m_numOwners] = uint(_owner); + m_ownerIndex[uint(_owner)] = m_numOwners; + OwnerAdded(_owner); + } + + function removeOwner(address _owner) onlymanyowners(sha3(msg.data, block.number)) external { + uint ownerIndex = m_ownerIndex[uint(_owner)]; + if (ownerIndex == 0) return; + if (m_required > m_numOwners - 1) return; + + m_owners[ownerIndex] = 0; + m_ownerIndex[uint(_owner)] = 0; + clearPending(); + reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot + OwnerRemoved(_owner); + } + + function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data, block.number)) external { + if (_newRequired > m_numOwners) return; + m_required = _newRequired; + clearPending(); + RequirementChanged(_newRequired); + } + + function isOwner(address _addr) returns (bool) { + return m_ownerIndex[uint(_addr)] > 0; + } + + function hasConfirmed(bytes32 _operation, address _owner) constant returns (bool) { + var pending = m_pending[_operation]; + uint ownerIndex = m_ownerIndex[uint(_owner)]; + + // make sure they're an owner + if (ownerIndex == 0) return false; + + // determine the bit to set for this owner. + uint ownerIndexBit = 2**ownerIndex; + if (pending.ownersDone & ownerIndexBit == 0) { + return false; + } else { + return true; + } + } + + // INTERNAL METHODS + + function confirmAndCheck(bytes32 _operation) internal returns (bool) { // determine what index the present sender is: uint ownerIndex = m_ownerIndex[uint(msg.sender)]; // make sure they're an owner @@ -132,42 +213,7 @@ contract multiowned { } } } - // Replaces an owner `_from` with another `_to`. - function changeOwner(address _from, address _to) onlymanyowners(sha3(msg.data)) external { - if (isOwner(_to)) return; - uint ownerIndex = m_ownerIndex[uint(_from)]; - if (ownerIndex == 0) return; - clearPending(); - m_owners[ownerIndex] = uint(_to); - m_ownerIndex[uint(_from)] = 0; - m_ownerIndex[uint(_to)] = ownerIndex; - OwnerChanged(_from, _to); - } - function addOwner(address _owner) onlymanyowners(sha3(msg.data)) external { - if (isOwner(_owner)) return; - - clearPending(); - if (m_numOwners >= c_maxOwners) - reorganizeOwners(); - if (m_numOwners >= c_maxOwners) - return; - m_numOwners++; - m_owners[m_numOwners] = uint(_owner); - m_ownerIndex[uint(_owner)] = m_numOwners; - OwnerAdded(_owner); - } - function removeOwner(address _owner) onlymanyowners(sha3(msg.data)) external { - uint ownerIndex = m_ownerIndex[uint(_owner)]; - if (ownerIndex == 0) return; - if (m_required > m_numOwners - 1) return; - - m_owners[ownerIndex] = 0; - m_ownerIndex[uint(_owner)] = 0; - clearPending(); - reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot - OwnerRemoved(_owner); - } function reorganizeOwners() private returns (bool) { uint free = 1; while (free < m_numOwners) @@ -182,6 +228,7 @@ contract multiowned { } } } + function clearPending() internal { uint length = m_pendingIndex.length; for (uint i = 0; i < length; ++i) @@ -189,46 +236,54 @@ contract multiowned { delete m_pending[m_pendingIndex[i]]; delete m_pendingIndex; } - function changeRequirement(uint _newRequired) onlymanyowners(sha3(msg.data)) external { - if (_newRequired > m_numOwners) return; - m_required = _newRequired; - clearPending(); - RequirementChanged(_newRequired); - } - function isOwner(address _addr) returns (bool) { - return m_ownerIndex[uint(_addr)] > 0; - } + + // FIELDS // the number of owners that must confirm the same operation before it is run. uint public m_required; // pointer used to find a free slot in m_owners uint public m_numOwners; + // list of owners - uint[256] public m_owners; + uint[256] m_owners; uint constant c_maxOwners = 250; // index on the list of owners to allow reverse lookup - mapping(uint => uint) public m_ownerIndex; + mapping(uint => uint) m_ownerIndex; // the ongoing operations. - mapping(bytes32 => PendingState) public m_pending; - bytes32[] public m_pendingIndex; + mapping(bytes32 => PendingState) m_pending; + bytes32[] m_pendingIndex; } // inheritable "property" contract that enables methods to be protected by placing a linear limit (specifiable) // on a particular resource per calendar day. is multiowned to allow the limit to be altered. resource that method // uses is specified in the modifier. contract daylimit is multiowned { + + // MODIFIERS + + // simple modifier for daily limit. + modifier limitedDaily(uint _value) { + if (underLimit(_value)) + _ + } + + // METHODS + // constructor - just records the present day's index. function daylimit() { m_lastDay = today(); } // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today. - function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data)) external { + function setDailyLimit(uint _newLimit) onlymanyowners(sha3(msg.data, block.number)) external { m_dailyLimit = _newLimit; } // (re)sets the daily limit. needs many of the owners to confirm. doesn't alter the amount already spent today. - function resetSpentToday() onlymanyowners(sha3(msg.data)) external { + function resetSpentToday() onlymanyowners(sha3(msg.data, block.number)) external { m_spentToday = 0; } + + // INTERNAL METHODS + // checks to see if there is at least `_value` left from the daily limit today. if there is, subtracts it and // returns true. otherwise just returns false. function underLimit(uint _value) internal onlyowner returns (bool) { @@ -244,60 +299,76 @@ contract daylimit is multiowned { } return false; } - // simple modifier for daily limit. - modifier limitedDaily(uint _value) { - if (underLimit(_value)) - _ - } // determines today's index. function today() private constant returns (uint) { return now / 1 days; } - uint public m_spentToday; + + // FIELDS + uint public m_dailyLimit; - uint public m_lastDay; + uint m_spentToday; + uint m_lastDay; } + // interface contract for multisig proxy contracts; see below for docs. contract multisig { + + // EVENTS + + // logged events: + // Funds has arrived into the wallet (record how much). event Deposit(address from, uint value); + // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going). event SingleTransact(address owner, uint value, address to, bytes data); + // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going). event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data); + // Confirmation still needed for a transaction. event ConfirmationNeeded(bytes32 operation, address initiator, uint value, address to, bytes data); + + // FUNCTIONS + + // TODO: document function changeOwner(address _from, address _to) external; function execute(address _to, uint _value, bytes _data) external returns (bytes32); function confirm(bytes32 _h) returns (bool); } + // usage: // bytes32 h = Wallet(w).from(oneOwner).transact(to, value, data); // Wallet(w).from(anotherOwner).confirm(h); contract Wallet is multisig, multiowned, daylimit { + + // TYPES + // Transaction structure to remember details of transaction lest it need be saved for a later call. struct Transaction { address to; uint value; bytes data; } - /* - // logged events: - // Funds has arrived into the wallet (record how much). - event Deposit(address from, uint value); - // Single transaction going out of the wallet (record who signed for it, how much, and to whom it's going). - event SingleTransact(address owner, uint value, address to, bytes data); - // Multi-sig transaction going out of the wallet (record who signed for it last, the operation hash, how much, and to whom it's going). - event MultiTransact(address owner, bytes32 operation, uint value, address to, bytes data);*/ + + // EVENTS + + event Created(bytes32 indexed identifier); + + // METHODS + // constructor - just pass on the owner arra to the multiowned. - event Created(); - function Wallet() { - Created(); + function Wallet(bytes32 identifier) { + Created(identifier); } + // kills the contract sending everything to `_to`. - function kill(address _to) onlymanyowners(sha3(msg.data)) external { + function kill(address _to) onlymanyowners(sha3(msg.data, block.number)) external { suicide(_to); } + // gets called when no other function matches function() { // just being sent some cash? if (msg.value > 0) Deposit(msg.sender, msg.value); } + // Outside-visible transact entry point. Executes transacion immediately if below daily spend limit. // If not, goes into multisig process. We provide a hash on return to allow the sender to provide // shortcuts for the other confirmations (allowing them to avoid replicating the _to, _value @@ -311,7 +382,7 @@ contract Wallet is multisig, multiowned, daylimit { return 0; } // determine our operation hash. - _r = sha3(msg.data); + _r = sha3(msg.data, block.number); if (!confirm(_r) && m_txs[_r].to == 0) { m_txs[_r].to = _to; m_txs[_r].value = _value; @@ -319,6 +390,7 @@ contract Wallet is multisig, multiowned, daylimit { ConfirmationNeeded(_r, msg.sender, _value, _to, _data); } } + // confirm a transaction through just the hash. we use the previous transactions map, m_txs, in order // to determine the body of the transaction from the hash provided. function confirm(bytes32 _h) onlymanyowners(_h) returns (bool) { @@ -329,20 +401,20 @@ contract Wallet is multisig, multiowned, daylimit { return true; } } + + // INTERNAL METHODS + function clearPending() internal { uint length = m_pendingIndex.length; for (uint i = 0; i < length; ++i) delete m_txs[m_pendingIndex[i]]; super.clearPending(); } - // // internally confirm transaction with all of the info. returns true iff confirmed good and executed. - // function confirmVerbose(bytes32 _h, address _to, uint _value, bytes _data) private onlymanyowners(_h) returns (bool) { - // _to.call.value(_value)(_data); - // MultiTransact("out", msg.sender, _h, _value, _to); - // return true; - // } + + // FIELDS + // pending transactions we have at present. - mapping (bytes32 => Transaction) public m_txs; + mapping (bytes32 => Transaction) m_txs; } )DELIMITER"; @@ -443,7 +515,7 @@ BOOST_AUTO_TEST_CASE(multisig_value_transfer) // 4 owners, set required to 3 BOOST_REQUIRE(callContractFunction("changeRequirement(uint256)", u256(3)) == encodeArgs()); // check that balance is and stays zero at destination address - h256 opHash("f916231db11c12e0142dc51f23632bc655de87c63f83fc928c443e90f7aa364a"); + h256 opHash("8f27f478ebcfaf28b0c354f4809ace8087000d668b89c8bc3b1b608bfdbe6654"); BOOST_CHECK_EQUAL(m_state.balance(Address(0x05)), 0); m_sender = Address(0x12); BOOST_REQUIRE(callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00) == encodeArgs(opHash)); diff --git a/test/libsolidity/solidityExecutionFramework.h b/test/libsolidity/solidityExecutionFramework.h index 200940a43..03a201c72 100644 --- a/test/libsolidity/solidityExecutionFramework.h +++ b/test/libsolidity/solidityExecutionFramework.h @@ -145,6 +145,12 @@ public: { return bytes(); } + //@todo might be extended in the future + template + static bytes encodeDyn(Arg const& _arg) + { + return encodeArgs(u256(0x20), u256(_arg.size()), _arg); + } private: template diff --git a/test/libweb3jsonrpc/webthreestubclient.h b/test/libweb3jsonrpc/webthreestubclient.h index fbef7a62a..6578921ef 100644 --- a/test/libweb3jsonrpc/webthreestubclient.h +++ b/test/libweb3jsonrpc/webthreestubclient.h @@ -302,6 +302,16 @@ class WebThreeStubClient : public jsonrpc::Client else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } + Json::Value eth_getTransactionReceipt(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getTransactionReceipt",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) { Json::Value p; diff --git a/test/libwhisper/bloomFilter.cpp b/test/libwhisper/bloomFilter.cpp index 814990d52..d7d4bd849 100644 --- a/test/libwhisper/bloomFilter.cpp +++ b/test/libwhisper/bloomFilter.cpp @@ -28,7 +28,7 @@ using namespace dev; using namespace dev::shh; using TopicBloomFilterShort = TopicBloomFilterBase<4>; -using TopicBloomFilterTest = TopicBloomFilterBase; +using TopicBloomFilterTest = TopicBloomFilterBase; void testAddNonExisting(TopicBloomFilterShort& _f, AbridgedTopic const& _h) { @@ -61,7 +61,7 @@ void testRemoveExistingBloom(TopicBloomFilterShort& _f, AbridgedTopic const& _h) double calculateExpected(TopicBloomFilterTest const& f, int n) { int const m = f.size * 8; // number of bits in the bloom - int const k = f.BitsPerBloom; // number of hash functions (e.g. bits set to 1 in every bloom) + int const k = BitsPerBloom; // number of hash functions (e.g. bits set to 1 in every bloom) double singleBitSet = 1.0 / m; // probability of any bit being set after inserting a single bit double singleBitNotSet = (1.0 - singleBitSet); @@ -244,4 +244,64 @@ BOOST_AUTO_TEST_CASE(bloomFilterRaw) BOOST_REQUIRE(!f.contains(b00110111)); } +static const unsigned DistributionTestSize = TopicBloomFilterSize; +static const unsigned TestArrSize = 8 * DistributionTestSize; + +void updateDistribution(FixedHash const& _h, array& _distribution) +{ + unsigned bits = 0; + for (unsigned i = 0; i < DistributionTestSize; ++i) + if (_h[i]) + for (unsigned j = 0; j < 8; ++j) + if (_h[i] & c_powerOfTwoBitMmask[j]) + { + _distribution[i * 8 + j]++; + if (++bits >= BitsPerBloom) + return; + } +} + +BOOST_AUTO_TEST_CASE(distributionRate) +{ + cnote << "Testing Bloom Filter Distribution Rate..."; + + array distribution; + for (unsigned i = 0; i < TestArrSize; ++i) + distribution[i] = 0; + + Topic x(0xC0FFEE); // deterministic pseudorandom value + + for (unsigned i = 0; i < 26000; ++i) + { + x = sha3(x); + FixedHash h = TopicBloomFilter::bloom(abridge(x)); + updateDistribution(h, distribution); + } + + unsigned average = 0; + for (unsigned i = 0; i < TestArrSize; ++i) + average += distribution[i]; + + average /= TestArrSize; + unsigned deviation = average / 3; + unsigned maxAllowed = average + deviation; + unsigned minAllowed = average - deviation; + + unsigned maximum = 0; + unsigned minimum = 0xFFFFFFFF; + + for (unsigned i = 0; i < TestArrSize; ++i) + { + unsigned const& z = distribution[i]; + if (z > maximum) + maximum = z; + else if (z < minimum) + minimum = z; + } + + cnote << minimum << average << maximum; + BOOST_REQUIRE(minimum > minAllowed); + BOOST_REQUIRE(maximum < maxAllowed); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libwhisper/whisperMessage.cpp b/test/libwhisper/whisperMessage.cpp index 343573713..f0c0aedc9 100644 --- a/test/libwhisper/whisperMessage.cpp +++ b/test/libwhisper/whisperMessage.cpp @@ -89,4 +89,24 @@ BOOST_AUTO_TEST_CASE(seal) sealAndOpenSingleMessage(i); } +BOOST_AUTO_TEST_CASE(work) +{ + VerbosityHolder setTemporaryLevel(10); + cnote << "Testing proof of work..."; + + Secret zero; + unsigned r = 0xC0DEFEED; + + for (int i = 0; i < 20; ++i) + { + Topics topics = createRandomTopics(++r); + bytes const payload = createRandomPayload(++r); + Message m(payload); + Envelope e = m.seal(zero, topics, 1, 50); + unsigned x = e.workProved(); + //cnote << x; + BOOST_REQUIRE(x > 4); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libwhisper/whisperTopic.cpp b/test/libwhisper/whisperTopic.cpp index 82825c5d0..8d0f603bb 100644 --- a/test/libwhisper/whisperTopic.cpp +++ b/test/libwhisper/whisperTopic.cpp @@ -78,7 +78,6 @@ BOOST_AUTO_TEST_CASE(topic) } this_thread::sleep_for(chrono::milliseconds(50)); } - }); Host host2("Test", NetworkPreferences("127.0.0.1", 30300, false)); @@ -384,4 +383,39 @@ BOOST_AUTO_TEST_CASE(topicAdvertising) whost2->uninstallWatch(w2); } +BOOST_AUTO_TEST_CASE(selfAddressed) +{ + VerbosityHolder setTemporaryLevel(10); + cnote << "Testing self-addressed messaging with bloom filter matching..."; + + char const* text = "deterministic pseudorandom test"; + BuildTopicMask mask(text); + + Host host("first", NetworkPreferences("127.0.0.1", 30305, false)); + auto wh = host.registerCapability(new WhisperHost()); + auto watch = wh->installWatch(BuildTopicMask(text)); + + unsigned const sample = 0xFEED; + KeyPair us = KeyPair::create(); + wh->post(us.sec(), RLPStream().append(sample).out(), BuildTopic(text)); + + TopicBloomFilterHash f = wh->bloom(); + Envelope e = Message(RLPStream().append(sample).out()).seal(us.sec(), BuildTopic(text), 50, 50); + bool ok = e.matchesBloomFilter(f); + BOOST_REQUIRE(ok); + + this_thread::sleep_for(chrono::milliseconds(50)); + + unsigned single = 0; + unsigned result = 0; + for (auto j: wh->checkWatch(watch)) + { + Message msg = wh->envelope(j).open(wh->fullTopics(watch)); + single = RLP(msg.payload()).toInt(); + result += single; + } + + BOOST_REQUIRE_EQUAL(sample, result); +} + BOOST_AUTO_TEST_SUITE_END()