diff --git a/.gitignore b/.gitignore index b6abc22a3..8d8974809 100644 --- a/.gitignore +++ b/.gitignore @@ -65,7 +65,6 @@ DerivedData project.pbxproj -evmjit doc/html *.autosave node_modules/ diff --git a/CMakeLists.txt b/CMakeLists.txt index f1246e152..9bab77585 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,9 +124,7 @@ include(EthExecutableHelper) createBuildInfo() if (EVMJIT) - # Workaround for Ubuntu broken LLVM package - link_directories(/usr/lib/llvm-3.5/lib) - + set(EVMJIT_CPP TRUE) # include CPP-JIT connector add_subdirectory(evmjit) endif() diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 2ce00b0e3..97ed31aa9 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -95,8 +95,8 @@ - - + + about:blank @@ -1212,8 +1212,8 @@ 0 - - + + about:blank @@ -2035,7 +2035,7 @@ font-size: 14pt - false + true Claim Ether Presale &Wallet... diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 6a44a2b24..7a28948f4 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -60,6 +60,11 @@ using namespace dev::p2p; using namespace dev::eth; namespace js = json_spirit; +#define Small "font-size: small; " +#define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; " +#define Div(S) "
" +#define Span(S) "" + static void initUnits(QComboBox* _b) { for (auto n = (unsigned)units().size(); n-- != 0; ) @@ -447,7 +452,7 @@ void Main::eval(QString const& _js) else s = "unknown type"; m_consoleHistory.push_back(qMakePair(_js, s)); - s = "
"; + s = "" Div(Mono "position: absolute; bottom: 0; border: 0px; margin: 0px; width: 100%"); for (auto const& i: m_consoleHistory) s += "
>" + i.first.toHtmlEscaped() + "
" "
 " + i.second + "
"; @@ -750,7 +755,7 @@ void Main::on_importKey_triggered() void Main::on_importKeyFile_triggered() { - QString s = QFileDialog::getOpenFileName(this, "Import Account", QDir::homePath(), "JSON Files (*.json);;All Files (*)"); + QString s = QFileDialog::getOpenFileName(this, "Claim Account Contents", QDir::homePath(), "JSON Files (*.json);;All Files (*)"); try { js::mValue val; @@ -780,8 +785,12 @@ void Main::on_importKeyFile_triggered() if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) { - m_myKeys.append(k); - keysChanged(); + if (m_myKeys.empty()) + { + m_myKeys.push_back(KeyPair::create()); + keysChanged(); + } + ethereum()->transact(k.sec(), ethereum()->balanceAt(k.address()) - gasPrice() * c_txGas, m_myKeys.back().address(), {}, c_txGas, gasPrice()); } else QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account."); @@ -1087,7 +1096,7 @@ void Main::refreshBlockChain() auto b = bc.block(h); for (auto const& i: RLP(b)[1]) { - Transaction t(i.data()); + Transaction t(i.data(), CheckSignature::Sender); if (bm || transactionMatch(filter, t)) { QString s = t.receiveAddress() ? @@ -1273,12 +1282,12 @@ void Main::on_transactionQueue_currentItemChanged() if (tx.data().size()) s << dev::memDump(tx.data(), 16, true); } - s << "
Hex: " << toHex(tx.rlp()) << "
"; + s << "
Hex: " Span(Mono) << toHex(tx.rlp()) << "
"; s << "
"; s << "
Log Bloom: " << receipt.bloom() << "
"; auto r = receipt.rlp(); s << "
Receipt: " << toString(RLP(r)) << "
"; - s << "
Receipt-Hex: " << toHex(receipt.rlp()) << "
"; + s << "
Receipt-Hex: " Span(Mono) << toHex(receipt.rlp()) << "
"; s << renderDiff(ethereum()->diff(i, 0)); // s << "Pre: " << fs.rootHash() << "
"; // s << "Post: " << ts.rootHash() << ""; @@ -1369,13 +1378,13 @@ void Main::on_blocks_currentItemChanged() for (auto const& i: block[1]) s << "
" << sha3(i.data()).abridged();// << ": " << i[1].toHash() << " [" << i[2].toInt() << " used]"; s << "
Post: " << info.stateRoot << ""; - s << "
Dump: " << toHex(block[0].data()) << ""; - s << "
Receipts-Hex: " << toHex(ethereum()->blockChain().receipts(h).rlp()) << "
"; + s << "
Dump: " Span(Mono) << toHex(block[0].data()) << ""; + s << "
Receipts-Hex: " Span(Mono) << toHex(ethereum()->blockChain().receipts(h).rlp()) << "
"; } else { unsigned txi = item->data(Qt::UserRole + 1).toInt(); - Transaction tx(block[1][txi].data()); + Transaction tx(block[1][txi].data(), CheckSignature::Sender); auto ss = tx.safeSender(); h256 th = sha3(rlpList(ss, tx.nonce())); TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi]; @@ -1404,12 +1413,12 @@ void Main::on_blocks_currentItemChanged() if (tx.data().size()) s << dev::memDump(tx.data(), 16, true); } - s << "
Hex: " << toHex(block[1][txi].data()) << "
"; + s << "
Hex: " Span(Mono) << toHex(block[1][txi].data()) << "
"; s << "
"; s << "
Log Bloom: " << receipt.bloom() << "
"; auto r = receipt.rlp(); s << "
Receipt: " << toString(RLP(r)) << "
"; - s << "
Receipt-Hex: " << toHex(receipt.rlp()) << "
"; + s << "
Receipt-Hex: " Span(Mono) << toHex(receipt.rlp()) << "
"; s << renderDiff(ethereum()->diff(txi, h)); ui->debugCurrent->setEnabled(true); ui->debugDumpState->setEnabled(true); @@ -1528,6 +1537,7 @@ void Main::on_contracts_currentItemChanged() for (auto const& i: storage) s << "@" << showbase << hex << prettyU256(i.first).toStdString() << "    " << showbase << hex << prettyU256(i.second).toStdString() << "
"; s << "

Body Code

" << disassemble(ethereum()->codeAt(address)); + s << Div(Mono) << toHex(ethereum()->codeAt(address)) << "
"; ui->contractInfo->appendHtml(QString::fromStdString(s.str())); } catch (dev::InvalidTrie) @@ -1637,13 +1647,18 @@ static shh::Topic topicFromText(QString _s) return ret; } - bool Main::sourceIsSolidity(string const& _source) { // TODO: Improve this heuristic return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol"); } +static bool sourceIsSerpent(string const& _source) +{ + // TODO: Improve this heuristic + return (_source.substr(0, 5) == "//ser"); +} + string const Main::getFunctionHashes(dev::solidity::CompilerStack const &_compiler, string const& _contractName) { @@ -1678,6 +1693,7 @@ void Main::on_data_textChanged() dev::solidity::CompilerStack compiler; try { +// compiler.addSources(dev::solidity::StandardSources); m_data = compiler.compile(src, m_enableOptimizer); solidity = "

Solidity

"; solidity += "
" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + "
"; @@ -1695,23 +1711,23 @@ void Main::on_data_textChanged() solidity = "

Solidity

Uncaught exception.
"; } } - else + else if (sourceIsSerpent(src)) { - m_data = compileLLL(src, m_enableOptimizer, &errors); - if (errors.size()) + try { - try - { - m_data = dev::asBytes(::compile(src)); - for (auto& i: errors) - i = "(LLL " + i + ")"; - } - catch (string err) - { - errors.push_back("Serpent " + err); - } + m_data = dev::asBytes(::compile(src)); + for (auto& i: errors) + i = "(LLL " + i + ")"; } - else + catch (string err) + { + errors.push_back("Serpent " + err); + } + } + else + { + m_data = compileLLL(src, m_enableOptimizer, &errors); + if (errors.empty()) { auto asmcode = compileLLLToAsm(src, false); lll = "

Pre

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; @@ -1729,7 +1745,7 @@ void Main::on_data_textChanged() for (auto const& i: errors) errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); } - ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped()); + ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "

Hex

" Div(Mono) + QString::fromStdString(toHex(m_data)) + "
"); ui->gas->setMinimum((qint64)Client::txGas(m_data, 0)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); @@ -1962,9 +1978,24 @@ void Main::on_debug_clicked() } } +bool beginsWith(Address _a, bytes const& _b) +{ + for (unsigned i = 0; i < min(20, _b.size()); ++i) + if (_a[i] != _b[i]) + return false; + return true; +} + void Main::on_create_triggered() { - m_myKeys.append(KeyPair::create()); + bool ok = true; + QString s = QInputDialog::getText(this, "Special Beginning?", "If you want a special key, enter some hex digits that it should begin with.\nNOTE: The more you enter, the longer generation will take.", QLineEdit::Normal, QString(), &ok); + if (!ok) + return; + KeyPair p; + while (!beginsWith(p.address(), asBytes(s.toStdString()))) + p = KeyPair::create(); + m_myKeys.append(p); keysChanged(); } diff --git a/evmjit/.gitignore b/evmjit/.gitignore new file mode 100644 index 000000000..84c048a73 --- /dev/null +++ b/evmjit/.gitignore @@ -0,0 +1 @@ +/build/ diff --git a/evmjit/CMakeLists.txt b/evmjit/CMakeLists.txt index 18601b921..519346007 100644 --- a/evmjit/CMakeLists.txt +++ b/evmjit/CMakeLists.txt @@ -4,8 +4,18 @@ project(evmjit) set_property(GLOBAL PROPERTY USE_FOLDERS ON) +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") +else() + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -fPIC") +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + # Do not allow unresovled symbols in shared library (default on linux) + set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined") +endif() + # LLVM -if(LLVM_DIR) # local LLVM build +if(LLVM_DIR OR APPLE) # local LLVM build find_package(LLVM REQUIRED CONFIG) message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") @@ -18,11 +28,19 @@ else() execute_process(COMMAND llvm-config-3.5 --includedir OUTPUT_VARIABLE LLVM_INCLUDE_DIRS) message(STATUS "LLVM include dirs: ${LLVM_INCLUDE_DIRS}") set(LLVM_LIBS "-lLLVMBitWriter -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMX86AsmParser -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMMCJIT -lLLVMTarget -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser -lLLVMBitReader -lLLVMExecutionEngine -lLLVMMC -lLLVMCore -lLLVMSupport -lz -lpthread -lffi -ltinfo -ldl -lm") + add_definitions(-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS) + link_directories(/usr/lib/llvm-3.5/lib) endif() # Boost find_package(Boost REQUIRED) add_subdirectory(libevmjit) -add_subdirectory(libevmjit-cpp) -add_subdirectory(evmcc) + +if(EVMJIT_CPP) + add_subdirectory(libevmjit-cpp) +endif() + +if(EVMJIT_TOOLS) + add_subdirectory(evmcc) +endif() diff --git a/evmjit/libevmjit-cpp/Env.cpp b/evmjit/libevmjit-cpp/Env.cpp index 6320aa222..90474c7e4 100644 --- a/evmjit/libevmjit-cpp/Env.cpp +++ b/evmjit/libevmjit-cpp/Env.cpp @@ -89,7 +89,7 @@ extern "C" *o_hash = hash; } - EXPORT byte const* env_getExtCode(ExtVMFace* _env, h256* _addr256, uint64_t* o_size) + EXPORT byte const* env_extcode(ExtVMFace* _env, h256* _addr256, uint64_t* o_size) { auto addr = right160(*_addr256); auto& code = _env->codeAt(addr); diff --git a/evmjit/libevmjit/BasicBlock.h b/evmjit/libevmjit/BasicBlock.h index 7a5364a4e..cda4f89bd 100644 --- a/evmjit/libevmjit/BasicBlock.h +++ b/evmjit/libevmjit/BasicBlock.h @@ -57,7 +57,7 @@ public: explicit BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest); BasicBlock(const BasicBlock&) = delete; - void operator=(const BasicBlock&) = delete; + BasicBlock& operator=(const BasicBlock&) = delete; llvm::BasicBlock* llvm() { return m_llvmBB; } @@ -66,6 +66,9 @@ public: bool isJumpDest() const { return m_isJumpDest; } + llvm::Value* getJumpTarget() const { return m_jumpTarget; } + void setJumpTarget(llvm::Value* _jumpTarget) { m_jumpTarget = _jumpTarget; } + LocalStack& localStack() { return m_stack; } /// Optimization: propagates values between local stacks in basic blocks @@ -112,6 +115,9 @@ private: /// Is the basic block a valid jump destination. /// JUMPDEST is the first instruction of the basic block. bool const m_isJumpDest = false; + + /// If block finishes with dynamic jump target index is stored here + llvm::Value* m_jumpTarget = nullptr; }; } diff --git a/evmjit/libevmjit/CMakeLists.txt b/evmjit/libevmjit/CMakeLists.txt index 7c35169a7..c1acfc409 100644 --- a/evmjit/libevmjit/CMakeLists.txt +++ b/evmjit/libevmjit/CMakeLists.txt @@ -2,23 +2,24 @@ set(TARGET_NAME evmjit) file(GLOB SOURCES "*.cpp") file(GLOB HEADERS "*.h") +set(INTERFACE_HEADERS interface.h) source_group("" FILES ${HEADERS}) source_group("" FILES ${SOURCES}) if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # Disable rtti for Cache as LLVM has no rtti set_source_files_properties(Cache.cpp PROPERTIES COMPILE_FLAGS -fno-rtti) -endif () +endif() -add_library(${TARGET_NAME} ${SOURCES} ${HEADERS}) +add_library(${TARGET_NAME} SHARED ${SOURCES} ${HEADERS}) set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "libs") include_directories(${LLVM_INCLUDE_DIRS}) include_directories(${Boost_INCLUDE_DIRS}) -target_link_libraries(${TARGET_NAME} ${LLVM_LIBS}) +target_link_libraries(${TARGET_NAME} PRIVATE ${LLVM_LIBS}) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") -#install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) -#install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) +install(TARGETS ${TARGET_NAME} LIBRARY DESTINATION lib) +install(FILES ${INTERFACE_HEADERS} DESTINATION include/${TARGET_NAME}) diff --git a/evmjit/libevmjit/Cache.cpp b/evmjit/libevmjit/Cache.cpp index 0b725bc24..0e6fb517a 100644 --- a/evmjit/libevmjit/Cache.cpp +++ b/evmjit/libevmjit/Cache.cpp @@ -36,6 +36,20 @@ std::unique_ptr Cache::getObject(std::string const& id) llvm::sys::path::system_temp_directory(false, cachePath); llvm::sys::path::append(cachePath, "evm_objs", id); +#if defined(__GNUC__) && !defined(NDEBUG) + llvm::sys::fs::file_status st; + auto err = llvm::sys::fs::status(cachePath.str(), st); + if (err) + return nullptr; + auto mtime = st.getLastModificationTime().toEpochTime(); + + std::tm tm; + strptime(__DATE__ __TIME__, " %b %d %Y %H:%M:%S", &tm); + auto btime = (uint64_t)std::mktime(&tm); + if (btime > mtime) + return nullptr; +#endif + if (auto r = llvm::MemoryBuffer::getFile(cachePath.str(), -1, false)) lastObject = llvm::MemoryBuffer::getMemBufferCopy(r.get()->getBuffer()); else if (r.getError() != std::make_error_code(std::errc::no_such_file_or_directory)) diff --git a/evmjit/libevmjit/Compiler.cpp b/evmjit/libevmjit/Compiler.cpp index 26c78b4ca..1d00fd225 100644 --- a/evmjit/libevmjit/Compiler.cpp +++ b/evmjit/libevmjit/Compiler.cpp @@ -100,7 +100,7 @@ llvm::BasicBlock* Compiler::getJumpTableBlock() m_jumpTableBlock.reset(new BasicBlock("JumpTable", m_mainFunc, m_builder, true)); InsertPointGuard g{m_builder}; m_builder.SetInsertPoint(m_jumpTableBlock->llvm()); - auto dest = m_jumpTableBlock->localStack().pop(); + auto dest = m_builder.CreatePHI(Type::Word, 8, "target"); auto switchInstr = m_builder.CreateSwitch(dest, getBadJumpBlock()); for (auto&& p : m_basicBlocks) { @@ -165,6 +165,26 @@ std::unique_ptr Compiler::compile(bytes const& _bytecode, std::str removeDeadBlocks(); + // Link jump table target index + if (m_jumpTableBlock) + { + auto phi = llvm::cast(&m_jumpTableBlock->llvm()->getInstList().front()); + for (auto predIt = llvm::pred_begin(m_jumpTableBlock->llvm()); predIt != llvm::pred_end(m_jumpTableBlock->llvm()); ++predIt) + { + BasicBlock* pred = nullptr; + for (auto&& p : m_basicBlocks) + { + if (p.second.llvm() == *predIt) + { + pred = &p.second; + break; + } + } + + phi->addIncoming(pred->getJumpTarget(), pred->llvm()); + } + } + dumpCFGifRequired("blocks-init.dot"); if (m_options.optimizeStack) @@ -394,7 +414,8 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode value = Endianness::toBE(m_builder, value); auto bytes = m_builder.CreateBitCast(value, llvm::VectorType::get(Type::Byte, 32), "bytes"); - auto byte = m_builder.CreateExtractElement(bytes, byteNum, "byte"); + 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"); value = m_builder.CreateZExt(byte, Type::Word); auto byteNumValid = m_builder.CreateICmpULT(byteNum, Constant::get(32)); @@ -564,7 +585,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode } else { - stack.push(target); + _basicBlock.setJumpTarget(target); m_builder.CreateBr(getJumpTableBlock()); } } @@ -580,7 +601,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode } else { - stack.push(target); + _basicBlock.setJumpTarget(target); m_builder.CreateCondBr(cond, getJumpTableBlock(), _nextBasicBlock); } } diff --git a/evmjit/libevmjit/ExecutionEngine.cpp b/evmjit/libevmjit/ExecutionEngine.cpp index 7e99932c3..b6b140fd5 100644 --- a/evmjit/libevmjit/ExecutionEngine.cpp +++ b/evmjit/libevmjit/ExecutionEngine.cpp @@ -19,7 +19,12 @@ #include "Compiler.h" #include "Cache.h" -extern "C" void env_sha3(dev::eth::jit::byte const* _begin, uint64_t _size, std::array* o_hash); +#if defined(NDEBUG) +#define DEBUG_ENV_OPTION(name) false +#else +#include +#define DEBUG_ENV_OPTION(name) (std::getenv(#name) != nullptr) +#endif namespace dev { @@ -49,14 +54,17 @@ ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime) std::string codeHash(bytes const& _code) { - std::array binHash; - env_sha3(_code.data(), _code.size(), &binHash); - - std::ostringstream os; - for (auto i: binHash) - os << std::hex << std::setfill('0') << std::setw(2) << (int)(std::make_unsigned::type)i; - - return os.str(); + uint32_t hash = 0; + for (auto b : _code) + { + hash += b; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + return std::to_string(hash); } } @@ -64,6 +72,8 @@ std::string codeHash(bytes const& _code) ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env) { static std::unique_ptr ee; // TODO: Use Managed Objects from LLVM? + static auto debugDumpModule = DEBUG_ENV_OPTION(EVMJIT_DUMP_MODULE); + static bool objectCacheEnabled = !DEBUG_ENV_OPTION(EVMJIT_CACHE_OFF); auto mainFuncName = codeHash(_code); EntryFuncPtr entryFuncPtr{}; @@ -74,14 +84,14 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en } else { - bool objectCacheEnabled = true; auto objectCache = objectCacheEnabled ? Cache::getObjectCache() : nullptr; std::unique_ptr module; if (objectCache) module = Cache::getObject(mainFuncName); if (!module) module = Compiler({}).compile(_code, mainFuncName); - //module->dump(); + if (debugDumpModule) + module->dump(); if (!ee) { llvm::InitializeNativeTarget(); @@ -92,7 +102,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en builder.setUseMCJIT(true); std::unique_ptr memoryManager(new llvm::SectionMemoryManager); builder.setMCJITMemoryManager(memoryManager.get()); - builder.setOptLevel(llvm::CodeGenOpt::Default); + builder.setOptLevel(llvm::CodeGenOpt::None); auto triple = llvm::Triple(llvm::sys::getProcessTriple()); if (triple.getOS() == llvm::Triple::OSType::Win32) diff --git a/evmjit/libevmjit/Ext.cpp b/evmjit/libevmjit/Ext.cpp index aae68f43a..a37a6fe99 100644 --- a/evmjit/libevmjit/Ext.cpp +++ b/evmjit/libevmjit/Ext.cpp @@ -5,9 +5,6 @@ #include #include -//#include -//#include - #include "RuntimeManager.h" #include "Memory.h" #include "Type.h" @@ -23,12 +20,9 @@ namespace jit Ext::Ext(RuntimeManager& _runtimeManager, Memory& _memoryMan): RuntimeHelper(_runtimeManager), m_memoryMan(_memoryMan) -#ifdef __MSCVER - , - m_funcs({}), // The only std::array initialization that works in both Visual Studio & GCC - m_argAllocas({}) -#endif { + m_funcs = decltype(m_funcs)(); + m_argAllocas = decltype(m_argAllocas)(); m_size = m_builder.CreateAlloca(Type::Size, nullptr, "env.size"); } @@ -74,7 +68,6 @@ llvm::Value* Ext::getArgAlloca() getBuilder().SetInsertPoint(getMainFunction()->front().getFirstNonPHI()); a = getBuilder().CreateAlloca(Type::Word, nullptr, "arg"); } - return a; } diff --git a/evmjit/libevmjit/Runtime.h b/evmjit/libevmjit/Runtime.h index 8cc5b7968..f97efa128 100644 --- a/evmjit/libevmjit/Runtime.h +++ b/evmjit/libevmjit/Runtime.h @@ -34,7 +34,7 @@ public: Runtime(RuntimeData* _data, Env* _env); Runtime(const Runtime&) = delete; - void operator=(const Runtime&) = delete; + Runtime& operator=(const Runtime&) = delete; StackImpl& getStack() { return m_stack; } MemoryImpl& getMemory() { return m_memory; } diff --git a/evmjit/libevmjit/interface.cpp b/evmjit/libevmjit/interface.cpp new file mode 100644 index 000000000..eef92d00f --- /dev/null +++ b/evmjit/libevmjit/interface.cpp @@ -0,0 +1,34 @@ +#include "interface.h" +#include +#include "ExecutionEngine.h" + +extern "C" +{ + +evmjit_result evmjit_run(void* _data, void* _env) +{ + using namespace dev::eth::jit; + + auto data = static_cast(_data); + + ExecutionEngine engine; + + auto codePtr = data->code; + auto codeSize = data->elems[RuntimeData::CodeSize].a; + bytes bytecode; + bytecode.insert(bytecode.end(), codePtr, codePtr + codeSize); + + auto returnCode = engine.run(bytecode, data, static_cast(_env)); + evmjit_result result = {static_cast(returnCode), 0, nullptr}; + if (returnCode == ReturnCode::Return && !engine.returnData.empty()) + { + // TODO: Optimized returning data. Allocating memory on client side by callback function might be a good idea + result.returnDataSize = engine.returnData.size(); + result.returnData = std::malloc(result.returnDataSize); + std::memcpy(result.returnData, engine.returnData.data(), result.returnDataSize); + } + + return result; +} + +} diff --git a/evmjit/libevmjit/interface.c b/evmjit/libevmjit/interface.h similarity index 76% rename from evmjit/libevmjit/interface.c rename to evmjit/libevmjit/interface.h index 47589578b..5d9307ab2 100644 --- a/evmjit/libevmjit/interface.c +++ b/evmjit/libevmjit/interface.h @@ -1,5 +1,20 @@ +#include #include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct evmjit_result +{ + int32_t returnCode; + uint64_t returnDataSize; + void* returnData; + +} evmjit_result; + +evmjit_result evmjit_run(void* _data, void* _env); + // JIT object opaque type typedef struct evm_jit evm_jit; @@ -9,6 +24,11 @@ typedef int evm_jit_return_code; // Host-endian 256-bit integer type typedef struct i256 i256; +struct i256 +{ + char b[33]; +}; + // Big-endian right aligned 256-bit hash typedef struct h256 h256; @@ -28,3 +48,7 @@ evm_jit_return_code evm_jit_execute(evm_jit* _jit); void evm_jit_get_return_data(evm_jit* _jit, char* _return_data_offset, size_t* _return_data_size); void evm_jit_destroy(evm_jit* _jit); + +#ifdef __cplusplus +} +#endif diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h index 2573995c5..dada9dd5d 100644 --- a/libdevcore/CommonData.h +++ b/libdevcore/CommonData.h @@ -124,6 +124,10 @@ inline bytes toCompactBigEndian(_T _val, unsigned _min = 0) toBigEndian(_val, ret); return ret; } +inline bytes toCompactBigEndian(byte _val, unsigned _min = 0) +{ + return (_min || _val) ? bytes{ _val } : bytes{}; +} /// Convenience function for toBigEndian. /// @returns a string just big enough to represent @a _val. diff --git a/libdevcore/Exceptions.h b/libdevcore/Exceptions.h index 061f181b3..e13d41476 100644 --- a/libdevcore/Exceptions.h +++ b/libdevcore/Exceptions.h @@ -31,7 +31,7 @@ namespace dev { // base class for all exceptions -struct Exception: virtual std::exception, virtual boost::exception {}; +struct Exception: virtual std::exception, virtual boost::exception { mutable std::string m_message; }; struct BadHexCharacter: virtual Exception {}; struct RLPException: virtual Exception {}; diff --git a/libethcore/Exceptions.cpp b/libethcore/Exceptions.cpp index b0aff4551..9b07743c5 100644 --- a/libethcore/Exceptions.cpp +++ b/libethcore/Exceptions.cpp @@ -27,14 +27,13 @@ using namespace std; using namespace dev; using namespace dev::eth; -#if ALL_COMPILERS_ARE_CPP11_COMPLIANT +#if ALL_COMPILERS_ARE_CPP11 #define ETH_RETURN_STRING(S) thread_local static string s_what; s_what = S; return s_what.c_str(); +#elsif USE_BOOST_TLS +static boost::thread_specific_ptr g_exceptionMessage; +#define ETH_RETURN_STRING(S) if (!g_exceptionMessage.get()); g_exceptionMessage.reset(new string); *g_exceptionMessage.get() = S; return g_exceptionMessage.get()->c_str(); #else -#define ETH_RETURN_STRING(S) \ - static boost::thread_specific_ptr s_what; \ - if (!s_what.get()) \ - s_what.reset(new string); \ - *s_what = S; return s_what->c_str(); +#define ETH_RETURN_STRING(S) m_message = S; return m_message.c_str(); #endif const char* InvalidBlockFormat::what() const noexcept { ETH_RETURN_STRING("Invalid block format: Bad field " + toString(m_f) + " (" + toHex(m_d) + ")"); } diff --git a/libethereum/Account.h b/libethereum/Account.h index 7e2fc38ab..3f3a5d548 100644 --- a/libethereum/Account.h +++ b/libethereum/Account.h @@ -140,7 +140,8 @@ 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(bytesConstRef _code) { assert(isFreshCode()); m_codeCache = _code.toBytes(); } + void setCode(bytes&& _code) { assert(isFreshCode()); m_codeCache = _code; } + void setCode(bytes const& _code) { assert(isFreshCode()); m_codeCache = _code; } /// @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(); } diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp index b1938d54d..45d79701a 100644 --- a/libethereum/BlockChain.cpp +++ b/libethereum/BlockChain.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include "State.h" #include "Defaults.h" using namespace std; @@ -56,6 +57,7 @@ std::map const& dev::eth::genesisState() { static std::map s_ret; if (s_ret.empty()) + { // Initialise. for (auto i: vector({ "51ba59315b3a95761d0863b05ccc7a7f54703d99", @@ -68,6 +70,7 @@ std::map const& dev::eth::genesisState() "e4157b34ea9615cfbde6b4fda419828124b70c78" })) s_ret[Address(fromHex(i))] = Account(u256(1) << 200, Account::NormalCreation); + } return s_ret; } diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 41f0bcfbc..fcc18c2d1 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -642,7 +642,7 @@ Transaction Client::transaction(h256 _blockHash, unsigned _i) const { auto bl = m_bc.block(_blockHash); RLP b(bl); - return Transaction(b[1][_i].data()); + return Transaction(b[1][_i].data(), CheckSignature::Range); } BlockInfo Client::uncle(h256 _blockHash, unsigned _i) const diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 4eed2b284..dc2e62824 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -53,7 +53,7 @@ void Executive::accrueSubState(SubState& _parentContext) bool Executive::setup(bytesConstRef _rlp) { // Entry point for a user-executed transaction. - m_t = Transaction(_rlp); + m_t = Transaction(_rlp, CheckSignature::Sender); // Avoid invalid transactions. auto nonceReq = m_s.transactionsFrom(m_t.sender()); @@ -197,7 +197,7 @@ bool Executive::go(OnOpFunc const& _onOp) m_endGas -= m_out.size() * c_createDataGas; else m_out.reset(); - m_s.m_cache[m_newAddress].setCode(m_out); + m_s.m_cache[m_newAddress].setCode(m_out.toBytes()); } } catch (StepsDone const&) diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 9ed9a3a3a..5232144c2 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -395,7 +395,7 @@ bool State::cull(TransactionQueue& _tq) const { try { - Transaction t(i.second); + Transaction t(i.second, CheckSignature::Sender); if (t.nonce() <= transactionsFrom(t.sender())) { _tq.drop(i.first); diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index 24c56930e..345e379af 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -30,7 +30,7 @@ using namespace dev::eth; #define ETH_ADDRESS_DEBUG 0 -Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender) +Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig) { int field = 0; RLP rlp(_rlpData); @@ -46,8 +46,14 @@ Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender) 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(BadRLP() << errinfo_comment("to many fields in the transaction RLP")); + m_vrs = SignatureStruct{ r, s, v }; - if (_checkSender) + if (_checkSig >= CheckSignature::Range && !m_vrs.isValid()) + BOOST_THROW_EXCEPTION(InvalidSignature()); + if (_checkSig == CheckSignature::Sender) m_sender = sender(); } catch (Exception& _e) diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 490a2ac68..0f88a4bc0 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -37,6 +37,13 @@ enum IncludeSignature WithSignature = 1, ///< Do include a signature. }; +enum class CheckSignature +{ + None, + Range, + Sender +}; + /// Encodes a transaction, ready to be exported to or freshly imported from RLP. class Transaction { @@ -57,10 +64,10 @@ public: Transaction(u256 _value, u256 _gasPrice, u256 _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {} /// Constructs a transaction from the given RLP. - explicit Transaction(bytesConstRef _rlp, bool _checkSender = false); + explicit Transaction(bytesConstRef _rlp, CheckSignature _checkSig); /// Constructs a transaction from the given RLP. - explicit Transaction(bytes const& _rlp, bool _checkSender = false): Transaction(&_rlp, _checkSender) {} + explicit Transaction(bytes const& _rlp, CheckSignature _checkSig): Transaction(&_rlp, _checkSig) {} /// Checks equality of transactions. diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 6248f38c9..5701fc4a5 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -42,7 +42,7 @@ bool TransactionQueue::import(bytesConstRef _transactionRLP) // 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). - Transaction t(_transactionRLP, true); + Transaction t(_transactionRLP, CheckSignature::Sender); UpgradeGuard ul(l); // If valid, append to blocks. @@ -69,14 +69,14 @@ void TransactionQueue::setFuture(std::pair const& _t) if (m_current.count(_t.first)) { m_current.erase(_t.first); - m_unknown.insert(make_pair(Transaction(_t.second).sender(), _t)); + m_unknown.insert(make_pair(Transaction(_t.second, CheckSignature::Sender).sender(), _t)); } } void TransactionQueue::noteGood(std::pair const& _t) { WriteGuard l(m_lock); - auto r = m_unknown.equal_range(Transaction(_t.second).sender()); + auto r = m_unknown.equal_range(Transaction(_t.second, CheckSignature::Sender).sender()); for (auto it = r.first; it != r.second; ++it) m_current.insert(it->second); m_unknown.erase(r.first, r.second); diff --git a/libevm/VM.cpp b/libevm/VM.cpp index aa3caff44..45017db9c 100644 --- a/libevm/VM.cpp +++ b/libevm/VM.cpp @@ -38,10 +38,12 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps) if (m_jumpDests.empty()) for (unsigned i = 0; i < _ext.code.size(); ++i) + { if (_ext.code[i] == (byte)Instruction::JUMPDEST) m_jumpDests.insert(i); else if (_ext.code[i] >= (byte)Instruction::PUSH1 && _ext.code[i] <= (byte)Instruction::PUSH32) i += _ext.code[i] - (unsigned)Instruction::PUSH1 + 1; + } u256 nextPC = m_curPC + 1; auto osteps = _steps; for (bool stopped = false; !stopped && _steps--; m_curPC = nextPC, nextPC = m_curPC + 1) diff --git a/libjsqrc/bignumber.min.js b/libjsqrc/bignumber.min.js new file mode 100644 index 000000000..c1627d780 --- /dev/null +++ b/libjsqrc/bignumber.min.js @@ -0,0 +1,2 @@ +/*! bignumber.js v2.0.0 https://github.com/MikeMcl/bignumber.js/LICENCE */ +(function(n){"use strict";function t(n,i){var b,a,l,p,o,w,s=this;if(!(s instanceof t))return new t(n,i);if(n instanceof t){if(i==null){u=0;s.s=n.s;s.e=n.e;s.c=(n=n.c)?n.slice():n;return}n+=""}else if(p=(o=typeof n)=="number"){if(i==null&&n===~~n){for(s.s=1/n<0?(n=-n,-1):1,a=u=0,l=n;l>=10;l/=10,a++);s.e=a;s.c=[n];return}n=n===0&&1/n<0?"-0":n+""}else o!="string"&&(n+="");if(o=n,i==null&&ft.test(o))s.s=o.charCodeAt(0)===45?(o=o.slice(1),-1):1;else{if(i==10)return s=new t(o),y(s,c+s.e+1,h);if(o=lt.call(o).replace(/^\+(?!-)/,""),s.s=o.charCodeAt(0)===45?(o=o.replace(/^-(?!-)/,""),-1):1,i!=null?i!=~~i&&d||(e=!(i>=2&&i<65))?(f(i,2),w=ft.test(o)):(b="["+ut.slice(0,i=i|0)+"]+",o=o.replace(/\.$/,"").replace(/^\./,"0."),(w=new RegExp("^"+b+"(?:\\."+b+")?$",i<37?"i":"").test(o))?(p&&(o.replace(/^0\.0*|\./,"").length>15&&f(n,0),p=!p),o=ct(o,10,i,s.s)):o!="Infinity"&&o!="NaN"&&(f(n,1,i),n="NaN")):w=ft.test(o),!w){s.c=s.e=null;o!="Infinity"&&(o!="NaN"&&f(n,3),s.s=null);u=0;return}}for((a=o.indexOf("."))>-1&&(o=o.replace(".","")),(l=o.search(/e/i))>0?(a<0&&(a=l),a+=+o.slice(l+1),o=o.substring(0,l)):a<0&&(a=o.length),l=0;o.charCodeAt(l)===48;l++);for(i=o.length;o.charCodeAt(--i)===48;);if(o=o.slice(l,i+1),o)if(i=o.length,p&&i>15&&f(n,0),a=a-l-1,a>v)s.c=s.e=null;else if(a=10;u/=10,f++);return(i=f+i*r-1)>v?n.c=n.e=null:ii-1&&(r[u+1]==null&&(r[u+1]=0),r[u+1]+=r[u]/i|0,r[u]%=i)}return r.reverse()}function ct(n,i,r,u){var l,e,v,y,s,f,w,o=n.indexOf("."),p=h;for(r<37&&(n=n.toLowerCase()),o>=0&&(n=n.replace(".",""),w=new t(r),s=w.pow(n.length-o),w.c=ht(s.toFixed(),10,i),w.e=w.c.length),f=ht(n,r,i),e=v=f.length;f[--v]==0;f.pop());if(!f[0])return"0";if(o<0?--e:(s.c=f,s.e=e,s.s=u,s=a(s,w,c,p,i),f=s.c,y=s.r,e=s.e),l=e+c+1,o=f[l],v=i/2,y=y||l<0||f[l+1]!=null,y=p<4?(o!=null||y)&&(p==0||p==(s.s<0?3:2)):o>v||o==v&&(p==4||y||p==6&&f[l-1]&1||p==(s.s<0?8:7)),l<1||!f[0])f.length=1,v=0,y?(f[0]=1,e=-c):e=f[0]=0;else{if(f.length=l,y)for(--i;++f[--l]>i;)f[l]=0,l||(++e,f.unshift(1));for(v=f.length;!f[--v];);}for(o=0,n="";o<=v;n+=ut.charAt(f[o++]));if(e<0){for(;++e;n="0"+n);n="0."+n}else if(o=n.length,++e>o)for(e-=o;e--;n+="0");else e1&&(u=u.charAt(0)+"."+u.slice(1));u+=(f<0?"e":"e+")+f}else{if(r=u.length,f<0){for(e=o-r;++f;u="0"+u);u="0."+u}else if(++f>r){for(e=o-f,f-=r;f--;u+="0");e>0&&(u+=".")}else e=o-r,f0&&(u+=".");if(e>0)for(;e--;u+="0");}return n.s<0&&n.c[0]?"-"+u:u}function f(n,t,i,r,f,o){if(d){var c,s=["new BigNumber","cmp","div","eq","gt","gte","lt","lte","minus","mod","plus","times","toFraction","divToInt"][u?u<0?-u:u:1/u<0?1:0]+"()",h=e?" out of range":" not a"+(f?" non-zero":"n")+" integer";h=([s+" number type has more than 15 significant digits",s+" not a base "+i+" number",s+" base"+h,s+" not a number"][t]||i+"() "+t+(o?" not a boolean or binary digit":h+(r?" or not ["+(e?" negative, positive":" integer, integer")+" ]":"")))+": "+n;e=u=0;c=new Error(h);c.name="BigNumber Error";throw c;}}function y(n,t,i,u){var c,o,e,s,a,h,p,f,y=st;if(f=n.c){n:{for(c=1,s=f[0];s>=10;s/=10,c++);if(o=t-c,o<0)o+=r,e=t,a=f[h=0],p=a/y[c-e-1]%10|0;else if(h=Math.ceil((o+1)/r),h>=f.length)if(u){for(;f.length<=h;f.push(0));a=p=0;c=1;o%=r;e=o-r+1}else break n;else{for(a=s=f[h],c=1;s>=10;s/=10,c++);o%=r;e=o-r+c;p=e<0?0:a/y[c-e-1]%10|0}if(u=u||t<0||f[h+1]!=null||(e<0?a:a%y[c-e-1]),u=i<4?(p||u)&&(i==0||i==(n.s<0?3:2)):p>5||p==5&&(i==4||u||i==6&&(o>0?e>0?a/y[c-e]:0:f[h-1])%10&1||i==(n.s<0?8:7)),t<1||!f[0])return f.length=0,u?(t-=n.e+1,f[0]=y[t%r],n.e=-t||0):f[0]=n.e=0,n;if(o==0?(f.length=h,s=1,h--):(f.length=h+1,s=y[r-o],f[h]=e>0?g(a/y[c-e]%y[e])*s:0),u)for(;;)if(h==0){for(o=1,e=f[0];e>=10;e/=10,o++);for(e=f[0]+=s,s=1;e>=10;e/=10,s++);o!=s&&(n.e++,f[0]==l&&(f[0]=1));break}else{if(f[h]+=s,f[h]!=l)break;f[h--]=0;s=1}for(o=f.length;f[--o]===0;f.pop());}n.e>v?n.c=n.e=null:n.ei)||w(n)!=n&&n!==0)},l=a&&typeof a=="object"?function(){if(a.hasOwnProperty(t))return(n=a[t])!=null}:function(){if(y.length>g)return(n=y[g++])!=null};if(l(t="DECIMAL_PLACES")&&(r(n,0,o)?c=n|0:f(n,t,s)),i[t]=c,l(t="ROUNDING_MODE")&&(r(n,0,8)?h=n|0:f(n,t,s)),i[t]=h,l(t="EXPONENTIAL_AT")&&(r(n,-o,o)?p=-(k=~~(n<0?-n:+n)):!e&&n&&r(n[0],-o,0)&&r(n[1],0,o)?(p=~~n[0],k=~~n[1]):f(n,t,s,1)),i[t]=[p,k],l(t="RANGE")&&(r(n,-o,o)&&~~n?nt=-(v=~~(n<0?-n:+n)):!e&&n&&r(n[0],-o,-1)&&r(n[1],1,o)?(nt=~~n[0],v=~~n[1]):f(n,t,s,1,1)),i[t]=[nt,v],l(t="ERRORS")&&(n===!!n||n===1||n===0?(e=u=0,w=(d=!!n)?parseInt:parseFloat):f(n,t,s,0,0,1)),i[t]=d,l(t="FORMAT"))if(typeof n=="object")b=n;else if(d){i=new Error(s+"() "+t+" not an object: "+n);i.name="BigNumber Error";throw i;}return i[t]=b,i};a=function(){function n(n,t,i){var f,e,o,h,r=0,u=n.length,c=t%s,l=t/s|0;for(n=n.slice();u--;)o=n[u]%s,h=n[u]/s|0,f=l*o+h*c,e=c*o+f%s*s+r,r=(e/i|0)+(f/s|0)+l*h,n[u]=e%i;return r&&n.unshift(r),n}function i(n,t,i,r){var u,f;if(i!=r)f=i>r?1:-1;else for(u=f=0;ut[u]?1:-1;break}return f}function u(n,t,i,r){for(var u=0;i--;)n[i]-=u,u=n[i]1;n.shift());}return function(f,e,o,s,h){var nt,ut,a,ot,p,tt,ft,it,et,v,w,st,ht,rt,lt,k,ct,d=f.s==e.s?1:-1,b=f.c,c=e.c;if(!b||!b[0]||!c||!c[0])return new t(!f.s||!e.s||(b?c&&b[0]==c[0]:!c)?NaN:b&&b[0]==0||!c?d*0:d/0);for(it=new t(d),et=it.c=[],ut=f.e-e.e,d=o+ut+1,h||(h=l,ut=(rt=f.e/r,a=rt|0,rt>0||rt===a?a:a-1)-(k=e.e/r,a=k|0,k>0||k===a?a:a-1),d=d/r|0),a=0;c[a]==(b[a]||0);a++);if(c[a]>(b[a]||0)&&ut--,d<0)et.push(1),ot=!0;else{for(rt=b.length,k=c.length,a=0,d+=2,p=g(h/(c[0]+1)),p>1&&(c=n(c,p,h),b=n(b,p,h),k=c.length,rt=b.length),ht=k,v=b.slice(0,k),w=v.length;w=h/2&<++;do p=0,nt=i(c,v,k,w),nt<0?(st=v[0],k!=w&&(st=st*h+(v[1]||0)),p=g(st/lt),p>1?(p>=h&&(p=h-1),tt=n(c,p,h),ft=tt.length,w=v.length,nt=i(tt,v,ft,w),nt==1&&(p--,u(tt,k=10;d/=10,a++);y(it,o+(it.e=a+ut*r-1)+1,s,ot)}else it.e=ut,it.r=+ot;return it}}();i.absoluteValue=i.abs=function(){var n=new t(this);return n.s<0&&(n.s=1),n};i.ceil=function(){return y(new t(this),this.e+1,2)};i.comparedTo=i.cmp=function(n,i){var f,l=this,e=l.c,o=(u=-u,n=new t(n,i)).c,r=l.s,c=n.s,s=l.e,h=n.e;if(!r||!c)return null;if(f=e&&!e[0],i=o&&!o[0],f||i)return f?i?0:-c:r;if(r!=c)return r;if(f=r<0,i=s==h,!e||!o)return i?0:!e^f?1:-1;if(!i)return s>h^f?1:-1;for(r=-1,c=(s=e.length)<(h=o.length)?s:h;++ro[r]^f?1:-1;return s==h?0:s>h^f?1:-1};i.decimalPlaces=i.dp=function(){var n,t,i=this.c;if(!i)return null;if(n=((t=i.length-1)-g(this.e/r))*r,t=i[t])for(;t%10==0;t/=10,n--);return n<0&&(n=0),n};i.dividedBy=i.div=function(n,i){return u=2,a(this,new t(n,i),c,h)};i.dividedToIntegerBy=i.divToInt=function(n,i){return u=13,a(this,new t(n,i),0,1)};i.equals=i.eq=function(n,t){return u=3,this.cmp(n,t)===0};i.floor=function(){return y(new t(this),this.e+1,3)};i.greaterThan=i.gt=function(n,t){return u=4,this.cmp(n,t)>0};i.greaterThanOrEqualTo=i.gte=function(n,t){return u=5,(t=this.cmp(n,t))==1||t===0};i.isFinite=function(){return!!this.c};i.isInteger=i.isInt=function(){return!!this.c&&g(this.e/r)>this.c.length-2};i.isNaN=function(){return!this.s};i.isNegative=i.isNeg=function(){return this.s<0};i.isZero=function(){return!!this.c&&this.c[0]==0};i.lessThan=i.lt=function(n,t){return u=6,this.cmp(n,t)<0};i.lessThanOrEqualTo=i.lte=function(n,t){return u=7,(t=this.cmp(n,t))==-1||t===0};i.minus=function(n,i){var e,c,v,w,p=this,s=p.s;if(u=8,n=new t(n,i),i=n.s,!s||!i)return new t(NaN);if(s!=i)return n.s=-i,p.plus(n);var y=p.e/r,a=n.e/r,f=p.c,o=n.c;if(!y||!a){if(!f||!o)return f?(n.s=-i,n):new t(o?p:NaN);if(!f[0]||!o[0])return o[0]?(n.s=-i,n):new t(f[0]?p:h==3?-0:0)}if(e=y|0,y=y>0||y===e?e:e-1,e=a|0,a=a>0||a===e?e:e-1,f=f.slice(),s=y-a){for((w=s<0)?(s=-s,v=f):(a=y,v=o),v.reverse(),i=s;i--;v.push(0));v.reverse()}else for(c=(w=(s=f.length)<(i=o.length))?s:i,s=i=0;i0)for(;i--;f[e++]=0);for(i=l-1;c>s;){if(f[--c]0||c===f?f:f-1,f=o|0,o=o>0||o===f?f:f-1,e=e.slice(),f=c-o){for(f>0?(o=c,h=s):(f=-f,h=e),h.reverse();f--;h.push(0));h.reverse()}for(f=e.length,i=s.length,f-i<0&&(h=s,s=e,e=h,i=f),f=0;i;)f=(e[--i]=e[i]+s[i]+f)/l|0,e[i]%=l;return f&&(e.unshift(f),++o),et(n,e,o)};i.round=function(n,i){return n=n==null||((e=n<0||n>o)||w(n)!=n)&&!f(n,"decimal places","round")?0:n|0,i=i==null||((e=i<0||i>8)||w(i)!=i&&i!==0)&&!f(i,"mode","round")?h:i|0,y(new t(this),n+this.e+1,i)};i.squareRoot=i.sqrt=function(){var v,i,r,s,f,e=this,o=e.c,n=e.s,u=e.e,l=c+4,p=new t("0.5");if(n!==1||!o||!o[0])return new t(!n||n<0&&(!o||o[0])?NaN:o?e:1/0);if(n=Math.sqrt(+e),n==0||n==1/0?(i=tt(o),(i.length+u)%2==0&&(i+="0"),n=Math.sqrt(i),u=g((u+1)/2)-(u<0||u%2),n==1/0?i="1e"+u:(i=n.toExponential(),i=i.slice(0,i.indexOf("e")+1)+u),r=new t(i)):r=new t(n.toString()),r.c[0])for(u=r.e,n=u+l,n<3&&(n=0);;)if(f=r,r=p.times(f.plus(a(e,f,l,1))),tt(f.c).slice(0,n)===(i=tt(r.c)).slice(0,n))if(r.e0||c===e?e:e-1)+(e=f|0,f>0||f===e?e:e-1),v=o.length,i=h.length,v=0;){for(p=0,f=v+c,w=v,d=h[c]%s,g=h[c]/s|0;f>c;)y=o[--w]%s,k=o[w]/s|0,b=g*y+k*d,y=d*y+b%s*s+a[f]+p,p=(y/l|0)+(b/s|0)+g*k,a[f--]=y%l;a[f]=p}return p?++e:a.shift(),et(n,a,e)};i.toExponential=function(n){var t=this;return t.c?rt(t,n==null||((e=n<0||n>o)||w(n)!=n&&n!==0)&&!f(n,"decimal places","toExponential")?null:n|0,1):t.toString()};i.toFixed=function(n){var t,i=this,r=p,u=k;return n=n==null||((e=n<0||n>o)||w(n)!=n&&n!==0)&&!f(n,"decimal places","toFixed")?null:i.e+(n|0),p=-(k=1/0),n!=null&&i.c?(t=rt(i,n),i.s<0&&i.c&&(i.c[0]?t.indexOf("-")<0&&(t="-"+t):t=t.replace("-",""))):t=i.toString(),p=r,k=u,t};i.toFormat=function(n){var f=this;if(!f.c)return f.toString();var t,h=f.s<0,c=b.groupSeparator,r=+b.groupSize,u=+b.secondaryGroupSize,l=f.toFixed(n).split("."),i=l[0],s=l[1],e=h?i.slice(1):i,o=e.length;if(u&&(t=r,r=u,u=t,o-=t),r>0&&o>0){for(t=o%r||r,i=e.substr(0,t);t0&&(i+=c+e.slice(t));h&&(i="-"+i)}return s?i+b.decimalSeparator+((u=+b.fractionGroupSize)?s.replace(new RegExp("\\d{"+u+"}\\B","g"),"$&"+b.fractionGroupSeparator):s):i};i.toFraction=function(n){var ut,c,i,w,k,o,s,nt,rt,l=c=new t(it),y=s=new t(it),b=this,ft=b.c,p=new t(it);if(!ft)return b.toString();for(rt=tt(ft),w=p.e=rt.length-b.e-1,p.c[0]=st[(k=w%r)<0?r+k:k],(n==null||(!(u=12,o=new t(n)).s||(e=o.cmp(l)<0||!o.c)||d&&g(o.e/r)0)&&(n=w>0?p:l),k=v,v=1/0,o=new t(rt),s.c[0]=0;;){if(nt=a(o,p,0,1),i=c.plus(nt.times(y)),i.cmp(n)==1)break;c=y;y=i;l=s.plus(nt.times(i=l));s=i;p=o.minus(nt.times(i=p));o=i}return i=a(n.minus(c),y,0,1),s=s.plus(i.times(l)),c=c.plus(i.times(y)),s.s=l.s=b.s,w*=2,ut=a(l,y,w,h).minus(b).abs().cmp(a(s,c,w,h).minus(b).abs())<1?[l.toString(),y.toString()]:[s.toString(),c.toString()],v=k,ut};i.toNumber=function(){var n=this;return+n||(n.s?0*n.s:NaN)};i.toPower=i.pow=function(n){var i=n*0==0?~~n:n,r=new t(this),u=new t(it);if(((e=n<-ot||n>ot)&&(i=n/0)||w(n)!=n&&n!==0&&!(i=NaN))&&!f(n,"exponent","pow")||!i)return new t(Math.pow(+r,i));for(i=i<0?-i:i;;){if(i&1&&(u=u.times(r)),i>>=1,!i)break;r=r.times(r)}return n<0?it.div(u):u};i.toPrecision=function(n){var t=this;return n==null||((e=n<1||n>o)||w(n)!=n)&&!f(n,"precision","toPrecision")||!t.c?t.toString():rt(t,--n|0,2)};i.toString=function(n){var r,t,o,u=this,i=u.e;if(i===null)t=u.s?"Infinity":"NaN";else{if(n==r&&(i<=p||i>=k))return rt(u,r,1);if(t=tt(u.c),i<0){for(;++i;t="0"+t);t="0."+t}else if(o=t.length,i>0)if(++i>o)for(i-=o;i--;t+="0");else i1)t=r+"."+t.slice(1);else if(r=="0")return r;if(n!=null)if((e=!(n>=2&&n<65))||n!=~~n&&d)f(n,"base","toS");else if(t=ct(t,n|0,10,u.s),t=="0")return t}return u.s<0?"-"+t:t};i.valueOf=i.toJSON=function(){return this.toString()};typeof module!="undefined"&&module.exports?module.exports=t:typeof define=="function"&&define.amd?define(function(){return t}):n.BigNumber=t})(this) \ No newline at end of file diff --git a/libjsqrc/ethereumjs/README.md b/libjsqrc/ethereumjs/README.md index f18d382bd..bb6967ce0 100644 --- a/libjsqrc/ethereumjs/README.md +++ b/libjsqrc/ethereumjs/README.md @@ -66,16 +66,16 @@ sudo apt-get install npm sudo apt-get install nodejs-legacy ``` -## Building +### Building (gulp) -```bash (gulp) +```bash npm run-script build ``` -### Testing +### Testing (mocha) -```bash (mocha) +```bash npm test ``` diff --git a/libjsqrc/ethereumjs/bower.json b/libjsqrc/ethereumjs/bower.json index cedae9023..3c5d2d33e 100644 --- a/libjsqrc/ethereumjs/bower.json +++ b/libjsqrc/ethereumjs/bower.json @@ -1,11 +1,12 @@ { "name": "ethereum.js", "namespace": "ethereum", - "version": "0.0.3", + "version": "0.0.8", "description": "Ethereum Compatible JavaScript API", "main": ["./dist/ethereum.js", "./dist/ethereum.min.js"], "dependencies": { - "es6-promise": "#master" + "es6-promise": "#master", + "bignumber.js": ">=2.0.0" }, "repository": { "type": "git", @@ -48,4 +49,4 @@ "index.js", "**/*.txt" ] -} \ No newline at end of file +} diff --git a/libjsqrc/ethereumjs/dist/ethereum.js b/libjsqrc/ethereumjs/dist/ethereum.js index a8ee64111..1dbb42d89 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js +++ b/libjsqrc/ethereumjs/dist/ethereum.js @@ -24,18 +24,19 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ // TODO: is these line is supposed to be here? if ("build" !== 'build') {/* - var web3 = require('./web3'); // jshint ignore:line + var BigNumber = require('bignumber.js'); // jshint ignore:line */} -// TODO: make these be actually accurate instead of falling back onto JS's doubles. -var hexToDec = function (hex) { - return parseInt(hex, 16).toString(); -}; +var web3 = require('./web3'); // jshint ignore:line -var decToHex = function (dec) { - return parseInt(dec).toString(16); -}; +BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN }); + +var ETH_PADDING = 32; +/// Finds first index of array element matching pattern +/// @param array +/// @param callback pattern +/// @returns index of element var findIndex = function (array, callback) { var end = false; var i = 0; @@ -45,106 +46,114 @@ var findIndex = function (array, callback) { return end ? i - 1 : -1; }; +/// @returns a function that is used as a pattern for 'findIndex' var findMethodIndex = function (json, methodName) { return findIndex(json, function (method) { return method.name === methodName; }); }; -var padLeft = function (string, chars) { - return new Array(chars - string.length + 1).join("0") + string; +/// @param string string to be padded +/// @param number of characters that result string should have +/// @param sign, by default 0 +/// @returns right aligned string +var padLeft = function (string, chars, sign) { + return new Array(chars - string.length + 1).join(sign ? sign : "0") + string; }; -var calcBitPadding = function (type, expected) { - var value = type.slice(expected.length); - if (value === "") { - return 32; - } - return parseInt(value) / 8; +/// @param expected type prefix (string) +/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false +var prefixedType = function (prefix) { + return function (type) { + return type.indexOf(prefix) === 0; + }; }; -var calcBytePadding = function (type, expected) { - var value = type.slice(expected.length); - if (value === "") { - return 32; - } - return parseInt(value); +/// @param expected type name (string) +/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false +var namedType = function (name) { + return function (type) { + return name === type; + }; }; -var calcRealPadding = function (type, expected) { - var value = type.slice(expected.length); - if (value === "") { - return 32; - } - var sizes = value.split('x'); - for (var padding = 0, i = 0; i < sizes; i++) { - padding += (sizes[i] / 8); - } - return padding; +var arrayType = function (type) { + return type.slice(-2) === '[]'; }; -var setupInputTypes = function () { - - // convert from int, decimal-string, prefixed hex string whatever into a bare hex string. - var formatStandard = function (value) { - if (typeof value === "number") - return value.toString(16); - else if (typeof value === "string" && value.indexOf('0x') === 0) - return value.substr(2); -// else if (typeof value === "string") -// return web3.toHex(value); - else - return (+value).toString(16); - }; - - var prefixedType = function (prefix, calcPadding) { - return function (type, value) { - var expected = prefix; - if (type.indexOf(expected) !== 0) { - return false; - } - - var padding = calcPadding(type, expected); - if (padding > 32) - return false; // not allowed to be so big. - padding = 32; // override as per the new ABI. - - if (prefix === "string") - return web3.fromAscii(value, padding).substr(2); - return padLeft(formatStandard(value), padding * 2); - }; - }; +/// Formats input value to byte representation of int +/// If value is negative, return it's two's complement +/// If the value is floating point, round it down +/// @returns right-aligned byte representation of int +var formatInputInt = function (value) { + var padding = ETH_PADDING * 2; + if (value instanceof BigNumber || typeof value === 'number') { + if (typeof value === 'number') + value = new BigNumber(value); + value = value.round(); + + if (value.lessThan(0)) + value = new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(value).plus(1); + value = value.toString(16); + } + else if (value.indexOf('0x') === 0) + value = value.substr(2); + else if (typeof value === 'string') + value = formatInputInt(new BigNumber(value)); + else + value = (+value).toString(16); + return padLeft(value, padding); +}; - var namedType = function (name, padding, formatter) { - return function (type, value) { - if (type !== name) { - return false; - } +/// Formats input value to byte representation of string +/// @returns left-algined byte representation of string +var formatInputString = function (value) { + return web3.fromAscii(value, ETH_PADDING).substr(2); +}; - padding = 32; //override as per the new ABI. +/// Formats input value to byte representation of bool +/// @returns right-aligned byte representation bool +var formatInputBool = function (value) { + return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0'); +}; - return padLeft(formatter ? formatter(value) : value, padding * 2); - }; - }; +/// Formats input value to byte representation of real +/// Values are multiplied by 2^m and encoded as integers +/// @returns byte representation of real +var formatInputReal = function (value) { + return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); +}; - var formatBool = function (value) { - return value ? '01' : '00'; - }; +var dynamicTypeBytes = function (type, value) { + // TODO: decide what to do with array of strings + if (arrayType(type) || prefixedType('string')(type)) + return formatInputInt(value.length); + return ""; +}; +/// Setups input formatters for solidity types +/// @returns an array of input formatters +var setupInputTypes = function () { + return [ - prefixedType('uint', calcBitPadding), - prefixedType('int', calcBitPadding), - prefixedType('hash', calcBitPadding), - prefixedType('string', calcBytePadding), - prefixedType('real', calcRealPadding), - prefixedType('ureal', calcRealPadding), - namedType('address', 20, formatStandard), - namedType('bool', 1, formatBool), + { type: prefixedType('uint'), format: formatInputInt }, + { type: prefixedType('int'), format: formatInputInt }, + { type: prefixedType('hash'), format: formatInputInt }, + { type: prefixedType('string'), format: formatInputString }, + { type: prefixedType('real'), format: formatInputReal }, + { type: prefixedType('ureal'), format: formatInputReal }, + { type: namedType('address'), format: formatInputInt }, + { type: namedType('bool'), format: formatInputBool } ]; }; var inputTypes = setupInputTypes(); +/// Formats input params to bytes +/// @param contract json abi +/// @param name of the method that we want to use +/// @param array of params that will be formatted to bytes +/// @returns bytes representation of input params var toAbiInput = function (json, methodName, params) { var bytes = ""; var index = findMethodIndex(json, methodName); @@ -154,74 +163,120 @@ var toAbiInput = function (json, methodName, params) { } var method = json[index]; + var padding = ETH_PADDING * 2; + + /// first we iterate in search for dynamic + method.inputs.forEach(function (input, index) { + bytes += dynamicTypeBytes(input.type, params[index]); + }); - for (var i = 0; i < method.inputs.length; i++) { - var found = false; - for (var j = 0; j < inputTypes.length && !found; j++) { - found = inputTypes[j](method.inputs[i].type, params[i]); + method.inputs.forEach(function (input, i) { + var typeMatch = false; + for (var j = 0; j < inputTypes.length && !typeMatch; j++) { + typeMatch = inputTypes[j].type(method.inputs[i].type, params[i]); } - if (!found) { - console.error('unsupported json type: ' + method.inputs[i].type); + if (!typeMatch) { + console.error('input parser does not support type: ' + method.inputs[i].type); } - bytes += found; - } + + var formatter = inputTypes[j - 1].format; + var toAppend = ""; + + if (arrayType(method.inputs[i].type)) + toAppend = params[i].reduce(function (acc, curr) { + return acc + formatter(curr); + }, ""); + else + toAppend = formatter(params[i]); + + bytes += toAppend; + }); return bytes; }; -var setupOutputTypes = function () { +/// Check if input value is negative +/// @param value is hex format +/// @returns true if it is negative, otherwise false +var signedIsNegative = function (value) { + return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1'; +}; - var prefixedType = function (prefix, calcPadding) { - return function (type) { - var expected = prefix; - if (type.indexOf(expected) !== 0) { - return -1; - } +/// Formats input right-aligned input bytes to int +/// @returns right-aligned input bytes formatted to int +var formatOutputInt = function (value) { + // check if it's negative number + // it it is, return two's complement + if (signedIsNegative(value)) { + return new BigNumber(value, 16).minus(new BigNumber('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 16)).minus(1); + } + return new BigNumber(value, 16); +}; - var padding = calcPadding(type, expected); - if (padding > 32) - return -1; // not allowed to be so big. - padding = 32; // override as per the new ABI. - return padding * 2; - }; - }; +/// Formats big right-aligned input bytes to uint +/// @returns right-aligned input bytes formatted to uint +var formatOutputUInt = function (value) { + return new BigNumber(value, 16); +}; - var namedType = function (name, padding) { - return function (type) { - padding = 32; // override as per the new ABI. - return name === type ? padding * 2 : -1; - }; - }; +/// @returns input bytes formatted to real +var formatOutputReal = function (value) { + return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); +}; - var formatInt = function (value) { - return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value); - }; +/// @returns input bytes formatted to ureal +var formatOutputUReal = function (value) { + return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); +}; - var formatHash = function (value) { - return "0x" + value; - }; +/// @returns right-aligned input bytes formatted to hex +var formatOutputHash = function (value) { + return "0x" + value; +}; - var formatBool = function (value) { - return value === '1' ? true : false; - }; +/// @returns right-aligned input bytes formatted to bool +var formatOutputBool = function (value) { + return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false; +}; - var formatString = function (value) { - return web3.toAscii(value); - }; +/// @returns left-aligned input bytes formatted to ascii string +var formatOutputString = function (value) { + return web3.toAscii(value); +}; + +/// @returns right-aligned input bytes formatted to address +var formatOutputAddress = function (value) { + return "0x" + value.slice(value.length - 40, value.length); +}; + +var dynamicBytesLength = function (type) { + if (arrayType(type) || prefixedType('string')(type)) + return ETH_PADDING * 2; + return 0; +}; + +/// Setups output formaters for solidity types +/// @returns an array of output formatters +var setupOutputTypes = function () { return [ - { padding: prefixedType('uint', calcBitPadding), format: formatInt }, - { padding: prefixedType('int', calcBitPadding), format: formatInt }, - { padding: prefixedType('hash', calcBitPadding), format: formatHash }, - { padding: prefixedType('string', calcBytePadding), format: formatString }, - { padding: prefixedType('real', calcRealPadding), format: formatInt }, - { padding: prefixedType('ureal', calcRealPadding), format: formatInt }, - { padding: namedType('address', 20) }, - { padding: namedType('bool', 1), format: formatBool } + { type: prefixedType('uint'), format: formatOutputUInt }, + { type: prefixedType('int'), format: formatOutputInt }, + { type: prefixedType('hash'), format: formatOutputHash }, + { type: prefixedType('string'), format: formatOutputString }, + { type: prefixedType('real'), format: formatOutputReal }, + { type: prefixedType('ureal'), format: formatOutputUReal }, + { type: namedType('address'), format: formatOutputAddress }, + { type: namedType('bool'), format: formatOutputBool } ]; }; var outputTypes = setupOutputTypes(); +/// Formats output bytes back to param list +/// @param contract json abi +/// @param name of the method that we want to use +/// @param bytes representtion of output +/// @returns array of output params var fromAbiOutput = function (json, methodName, output) { var index = findMethodIndex(json, methodName); @@ -233,25 +288,51 @@ var fromAbiOutput = function (json, methodName, output) { var result = []; var method = json[index]; - for (var i = 0; i < method.outputs.length; i++) { - var padding = -1; - for (var j = 0; j < outputTypes.length && padding === -1; j++) { - padding = outputTypes[j].padding(method.outputs[i].type); + var padding = ETH_PADDING * 2; + + var dynamicPartLength = method.outputs.reduce(function (acc, curr) { + return acc + dynamicBytesLength(curr.type); + }, 0); + + var dynamicPart = output.slice(0, dynamicPartLength); + output = output.slice(dynamicPartLength); + + method.outputs.forEach(function (out, i) { + var typeMatch = false; + for (var j = 0; j < outputTypes.length && !typeMatch; j++) { + typeMatch = outputTypes[j].type(method.outputs[i].type); } - if (padding === -1) { - // not found output parsing - continue; + if (!typeMatch) { + console.error('output parser does not support type: ' + method.outputs[i].type); } - var res = output.slice(0, padding); + var formatter = outputTypes[j - 1].format; - result.push(formatter ? formatter(res) : ("0x" + res)); - output = output.slice(padding); - } + if (arrayType(method.outputs[i].type)) { + var size = formatOutputUInt(dynamicPart.slice(0, padding)); + dynamicPart = dynamicPart.slice(padding); + var array = []; + for (var k = 0; k < size; k++) { + array.push(formatter(output.slice(0, padding))); + output = output.slice(padding); + } + result.push(array); + } + else if (prefixedType('string')(method.outputs[i].type)) { + dynamicPart = dynamicPart.slice(padding); + result.push(formatter(output.slice(0, padding))); + output = output.slice(padding); + } else { + result.push(formatter(output.slice(0, padding))); + output = output.slice(padding); + } + }); return result; }; +/// @param json abi for contract +/// @returns input parser object for given json abi var inputParser = function (json) { var parser = {}; json.forEach(function (method) { @@ -264,6 +345,8 @@ var inputParser = function (json) { return parser; }; +/// @param json abi for contract +/// @returns output parser for given json abi var outputParser = function (json) { var parser = {}; json.forEach(function (method) { @@ -275,6 +358,9 @@ var outputParser = function (json) { return parser; }; +/// @param json abi for contract +/// @param method name for which we want to get method signature +/// @returns (promise) contract method signature for method with given name var methodSignature = function (json, name) { var method = json[findMethodIndex(json, name)]; var result = name + '('; @@ -294,7 +380,7 @@ module.exports = { }; -},{}],2:[function(require,module,exports){ +},{"./web3":8}],2:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -324,12 +410,21 @@ module.exports = { * if it fails, it uses HttpRpcProvider */ -// TODO: is these line is supposed to be here? +var web3 = require('./web3'); // jshint ignore:line if ("build" !== 'build') {/* var WebSocket = require('ws'); // jshint ignore:line - var web3 = require('./web3'); // jshint ignore:line */} +/** + * AutoProvider object prototype is implementing 'provider protocol' + * Automatically tries to setup correct provider(Qt, WebSockets or HttpRpc) + * First it checkes if we are ethereum browser (if navigator.qt object is available) + * if yes, we are using QtProvider + * if no, we check if it is possible to establish websockets connection with ethereum (ws://localhost:40404/eth is default) + * if it's not possible, we are using httprpc provider (http://localhost:8080) + * The constructor allows you to specify uris on which we are trying to connect over http or websockets + * You can do that by passing objects with fields httrpc and websockets + */ var AutoProvider = function (userOptions) { if (web3.haveProvider()) { return; @@ -360,7 +455,7 @@ var AutoProvider = function (userOptions) { self.poll = self.provider.poll.bind(self.provider); } self.sendQueue.forEach(function (payload) { - self.provider(payload); + self.provider.send(payload); }); self.onmessageQueue.forEach(function (handler) { self.provider.onmessage = handler; @@ -378,6 +473,8 @@ var AutoProvider = function (userOptions) { }; }; +/// Sends message forward to the provider, that is being used +/// if provider is not yet set, enqueues the message AutoProvider.prototype.send = function (payload) { if (this.provider) { this.provider.send(payload); @@ -386,6 +483,7 @@ AutoProvider.prototype.send = function (payload) { this.sendQueue.push(payload); }; +/// On incoming message sends the message to the provider that is currently being used Object.defineProperty(AutoProvider.prototype, 'onmessage', { set: function (handler) { if (this.provider) { @@ -398,7 +496,7 @@ Object.defineProperty(AutoProvider.prototype, 'onmessage', { module.exports = AutoProvider; -},{}],3:[function(require,module,exports){ +},{"./web3":8}],3:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -421,16 +519,32 @@ module.exports = AutoProvider; * @date 2014 */ -// TODO: is these line is supposed to be here? -if ("build" !== 'build') {/* - var web3 = require('./web3'); // jshint ignore:line -*/} - +var web3 = require('./web3'); // jshint ignore:line var abi = require('./abi'); -// method signature length in bytes +/// method signature length in bytes var ETH_METHOD_SIGNATURE_LENGTH = 4; +/** + * This method should be called when we want to call / transact some solidity method from javascript + * it returns an object which has same methods available as solidity contract description + * usage example: + * + * var abi = [{ + * name: 'myMethod', + * inputs: [{ name: 'a', type: 'string' }], + * outputs: [{name: 'd', type: 'string' }] + * }]; // contract abi + * + * var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object + * + * myContract.myMethod('this is test string param for call').call(); // myMethod call + * myContract.myMethod('this is test string param for transact').transact() // myMethod transact + * + * @param address - address of the contract, which should be called + * @param desc - abi json description of the contract, which is being created + * @returns contract object + */ var contract = function (address, desc) { var inputParser = abi.inputParser(desc); var outputParser = abi.outputParser(desc); @@ -472,7 +586,96 @@ var contract = function (address, desc) { module.exports = contract; -},{"./abi":1}],4:[function(require,module,exports){ + +},{"./abi":1,"./web3":8}],4:[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 filter.js + * @authors: + * Jeffrey Wilcke + * Marek Kotewicz + * Marian Oancea + * Gav Wood + * @date 2014 + */ + +var web3 = require('./web3'); // jshint ignore:line + +/// should be used when we want to watch something +/// it's using inner polling mechanism and is notified about changes +var Filter = function(options, impl) { + this.impl = impl; + this.callbacks = []; + + var self = this; + this.promise = impl.newFilter(options); + this.promise.then(function (id) { + self.id = id; + web3.on(impl.changed, id, self.trigger.bind(self)); + web3.provider.startPolling({call: impl.changed, args: [id]}, id); + }); +}; + +/// alias for changed* +Filter.prototype.arrived = function(callback) { + this.changed(callback); +}; + +/// gets called when there is new eth/shh message +Filter.prototype.changed = function(callback) { + var self = this; + this.promise.then(function(id) { + self.callbacks.push(callback); + }); +}; + +/// trigger calling new message from people +Filter.prototype.trigger = function(messages) { + for(var i = 0; i < this.callbacks.length; i++) { + this.callbacks[i].call(this, messages); + } +}; + +/// should be called to uninstall current filter +Filter.prototype.uninstall = function() { + var self = this; + this.promise.then(function (id) { + self.impl.uninstallFilter(id); + web3.provider.stopPolling(id); + web3.off(impl.changed, id); + }); +}; + +/// should be called to manually trigger getting latest messages from the client +Filter.prototype.messages = function() { + var self = this; + return this.promise.then(function (id) { + return self.impl.getMessages(id); + }); +}; + +/// alias for messages +Filter.prototype.logs = function () { + return this.messages(); +}; + +module.exports = Filter; + +},{"./web3":8}],5:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -501,11 +704,21 @@ if ("build" !== 'build') {/* var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line */} +/** + * HttpRpcProvider object prototype is implementing 'provider protocol' + * Should be used when we want to connect to ethereum backend over http && jsonrpc + * It's compatible with cpp client + * The contructor allows to specify host uri + * This provider is using in-browser polling mechanism + */ var HttpRpcProvider = function (host) { this.handlers = []; this.host = host; }; +/// Transforms inner message to proper jsonrpc object +/// @param inner message object +/// @returns jsonrpc object function formatJsonRpcObject(object) { return { jsonrpc: '2.0', @@ -515,6 +728,9 @@ function formatJsonRpcObject(object) { }; } +/// Transforms jsonrpc object to inner message +/// @param incoming jsonrpc message +/// @returns inner message object function formatJsonRpcMessage(message) { var object = JSON.parse(message); @@ -525,6 +741,10 @@ function formatJsonRpcMessage(message) { }; } +/// Prototype object method +/// Asynchronously sends request to server +/// @param payload is inner message object +/// @param cb is callback which is being called when response is comes back HttpRpcProvider.prototype.sendRequest = function (payload, cb) { var data = formatJsonRpcObject(payload); @@ -538,6 +758,11 @@ HttpRpcProvider.prototype.sendRequest = function (payload, cb) { }; }; +/// Prototype object method +/// Should be called when we want to send single api request to server +/// Asynchronous +/// On response it passes message to handlers +/// @param payload is inner message object HttpRpcProvider.prototype.send = function (payload) { var self = this; this.sendRequest(payload, function (request) { @@ -547,6 +772,13 @@ HttpRpcProvider.prototype.send = function (payload) { }); }; +/// Prototype object method +/// Should be called only for polling requests +/// Asynchronous +/// On response it passege message to handlers, but only if message's result is true or not empty array +/// Otherwise response is being silently ignored +/// @param payload is inner message object +/// @id is id of poll that we are calling HttpRpcProvider.prototype.poll = function (payload, id) { var self = this; this.sendRequest(payload, function (request) { @@ -560,6 +792,8 @@ HttpRpcProvider.prototype.poll = function (payload, id) { }); }; +/// Prototype object property +/// Should be used to set message handlers for this provider Object.defineProperty(HttpRpcProvider.prototype, "onmessage", { set: function (handler) { this.handlers.push(handler); @@ -568,7 +802,129 @@ Object.defineProperty(HttpRpcProvider.prototype, "onmessage", { module.exports = HttpRpcProvider; -},{}],5:[function(require,module,exports){ + +},{}],6:[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 providermanager.js + * @authors: + * Jeffrey Wilcke + * Marek Kotewicz + * Marian Oancea + * Gav Wood + * @date 2014 + */ + +var web3 = require('./web3'); // jshint ignore:line + +/** + * Provider manager object prototype + * It's responsible for passing messages to providers + * If no provider is set it's responsible for queuing requests + * It's also responsible for polling the ethereum node for incoming messages + * Default poll timeout is 12 seconds + * If we are running ethereum.js inside ethereum browser, there are backend based tools responsible for polling, + * and provider manager polling mechanism is not used + */ +var ProviderManager = function() { + this.queued = []; + this.polls = []; + this.ready = false; + this.provider = undefined; + this.id = 1; + + var self = this; + var poll = function () { + if (self.provider && self.provider.poll) { + self.polls.forEach(function (data) { + data.data._id = self.id; + self.id++; + self.provider.poll(data.data, data.id); + }); + } + setTimeout(poll, 12000); + }; + poll(); +}; + +/// sends outgoing requests, if provider is not available, enqueue the request +ProviderManager.prototype.send = function(data, cb) { + data._id = this.id; + if (cb) { + web3._callbacks[data._id] = cb; + } + + data.args = data.args || []; + this.id++; + + if(this.provider !== undefined) { + this.provider.send(data); + } else { + console.warn("provider is not set"); + this.queued.push(data); + } +}; + +/// setups provider, which will be used for sending messages +ProviderManager.prototype.set = function(provider) { + if(this.provider !== undefined && this.provider.unload !== undefined) { + this.provider.unload(); + } + + this.provider = provider; + this.ready = true; +}; + +/// resends queued messages +ProviderManager.prototype.sendQueued = function() { + for(var i = 0; this.queued.length; i++) { + // Resend + this.send(this.queued[i]); + } +}; + +/// @returns true if the provider i properly set +ProviderManager.prototype.installed = function() { + return this.provider !== undefined; +}; + +/// this method is only used, when we do not have native qt bindings and have to do polling on our own +/// should be callled, on start watching for eth/shh changes +ProviderManager.prototype.startPolling = function (data, pollId) { + if (!this.provider || !this.provider.poll) { + return; + } + this.polls.push({data: data, id: pollId}); +}; + +/// should be called to stop polling for certain watch changes +ProviderManager.prototype.stopPolling = function (pollId) { + for (var i = this.polls.length; i--;) { + var poll = this.polls[i]; + if (poll.id === pollId) { + this.polls.splice(i, 1); + } + } +}; + +module.exports = ProviderManager; + + +},{"./web3":8}],7:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -592,6 +948,11 @@ module.exports = HttpRpcProvider; * @date 2014 */ +/** + * QtProvider object prototype is implementing 'provider protocol' + * Should be used inside ethereum browser. It's compatible with cpp and go clients. + * It uses navigator.qt object to pass the messages to native bindings + */ var QtProvider = function() { this.handlers = []; @@ -603,10 +964,17 @@ var QtProvider = function() { }; }; +/// Prototype object method +/// Should be called when we want to send single api request to native bindings +/// Asynchronous +/// Response will be received by navigator.qt.onmessage method and passed to handlers +/// @param payload is inner message object QtProvider.prototype.send = function(payload) { navigator.qt.postMessage(JSON.stringify(payload)); }; +/// Prototype object property +/// Should be used to set message handlers for this provider Object.defineProperty(QtProvider.prototype, "onmessage", { set: function(handler) { this.handlers.push(handler); @@ -615,7 +983,7 @@ Object.defineProperty(QtProvider.prototype, "onmessage", { module.exports = QtProvider; -},{}],6:[function(require,module,exports){ +},{}],8:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -632,7 +1000,7 @@ module.exports = QtProvider; You should have received a copy of the GNU Lesser General Public License along with ethereum.js. If not, see . */ -/** @file main.js +/** @file web3.js * @authors: * Jeffrey Wilcke * Marek Kotewicz @@ -641,6 +1009,9 @@ module.exports = QtProvider; * @date 2014 */ +/// Recursively resolves all promises in given object and replaces the resolved values with promises +/// @param any object/array/promise/anything else.. +/// @returns (resolves) object with replaced promises with their result function flattenPromise (obj) { if (obj instanceof Promise) { return Promise.resolve(obj); @@ -680,12 +1051,14 @@ function flattenPromise (obj) { return Promise.resolve(obj); } +/// @returns an array of objects describing web3 api methods var web3Methods = function () { return [ { name: 'sha3', call: 'web3_sha3' } ]; }; +/// @returns an array of objects describing web3.eth api methods var ethMethods = function () { var blockCall = function (args) { return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber"; @@ -719,6 +1092,7 @@ var ethMethods = function () { return methods; }; +/// @returns an array of objects describing web3.eth api properties var ethProperties = function () { return [ { name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' }, @@ -733,6 +1107,7 @@ var ethProperties = function () { ]; }; +/// @returns an array of objects describing web3.db api methods var dbMethods = function () { return [ { name: 'put', call: 'db_put' }, @@ -742,6 +1117,7 @@ var dbMethods = function () { ]; }; +/// @returns an array of objects describing web3.shh api methods var shhMethods = function () { return [ { name: 'post', call: 'shh_post' }, @@ -752,6 +1128,7 @@ var shhMethods = function () { ]; }; +/// @returns an array of objects describing web3.eth.watch api methods var ethWatchMethods = function () { var newFilter = function (args) { return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter'; @@ -764,6 +1141,7 @@ var ethWatchMethods = function () { ]; }; +/// @returns an array of objects describing web3.shh.watch api methods var shhWatchMethods = function () { return [ { name: 'newFilter', call: 'shh_newFilter' }, @@ -772,6 +1150,8 @@ var shhWatchMethods = function () { ]; }; +/// creates methods in a given object based on method description on input +/// setups api calls for these methods var setupMethods = function (obj, methods) { methods.forEach(function (method) { obj[method.name] = function () { @@ -795,6 +1175,8 @@ var setupMethods = function (obj, methods) { }); }; +/// creates properties in a given object based on properties description on input +/// setups api calls for these properties var setupProperties = function (obj, properties) { properties.forEach(function (property) { var proto = {}; @@ -839,7 +1221,7 @@ var decToHex = function (dec) { return parseInt(dec).toString(16); }; - +/// setups web3 object, and it's in-browser executed methods var web3 = { _callbacks: {}, _events: {}, @@ -855,6 +1237,7 @@ var web3 = { return hex; }, + /// @returns ascii string representation of hex value prefixed with 0x toAscii: function(hex) { // Find termination var str = ""; @@ -862,17 +1245,18 @@ var web3 = { if (hex.substring(0, 2) === '0x') i = 2; for(; i < l; i+=2) { - var code = hex.charCodeAt(i); + var code = parseInt(hex.substr(i, 2), 16); if(code === 0) { break; } - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + str += String.fromCharCode(code); } return str; }, + /// @returns hex representation (prefixed by 0x) of ascii string fromAscii: function(str, pad) { pad = pad === undefined ? 0 : pad; var hex = this.toHex(str); @@ -881,14 +1265,17 @@ var web3 = { return "0x" + hex; }, + /// @returns decimal representaton of hex value prefixed by 0x toDecimal: function (val) { return hexToDec(val.substring(2)); }, + /// @returns hex representation (prefixed by 0x) of decimal value fromDecimal: function (val) { return "0x" + decToHex(val); }, + /// used to transform value/string to eth string toEth: function(str) { var val = typeof str === "string" ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str; var unit = 0; @@ -912,24 +1299,24 @@ var web3 = { return s + ' ' + units[unit]; }, + /// eth object prototype eth: { - prototype: Object(), // jshint ignore:line watch: function (params) { - return new Filter(params, ethWatch); + return new web3.filter(params, ethWatch); } }, - db: { - prototype: Object() // jshint ignore:line - }, + /// db object prototype + db: {}, + /// shh object prototype shh: { - prototype: Object(), // jshint ignore:line watch: function (params) { - return new Filter(params, shhWatch); + return new web3.filter(params, shhWatch); } }, + /// used by filter to register callback with given id on: function(event, id, cb) { if(web3._events[event] === undefined) { web3._events[event] = {}; @@ -939,6 +1326,7 @@ var web3 = { return this; }, + /// used by filter to unregister callback with given id off: function(event, id) { if(web3._events[event] !== undefined) { delete web3._events[event][id]; @@ -947,6 +1335,7 @@ var web3 = { return this; }, + /// used to trigger callback registered by filter trigger: function(event, id, data) { var callbacks = web3._events[event]; if (!callbacks || !callbacks[id]) { @@ -954,9 +1343,15 @@ var web3 = { } var cb = callbacks[id]; cb(data); + }, + + /// @returns true if provider is installed + haveProvider: function() { + return !!web3.provider.provider; } }; +/// setups all api methods setupMethods(web3, web3Methods()); setupMethods(web3.eth, ethMethods()); setupProperties(web3.eth, ethProperties()); @@ -966,87 +1361,14 @@ setupMethods(web3.shh, shhMethods()); var ethWatch = { changed: 'eth_changed' }; + setupMethods(ethWatch, ethWatchMethods()); + var shhWatch = { changed: 'shh_changed' }; -setupMethods(shhWatch, shhWatchMethods()); - -var ProviderManager = function() { - this.queued = []; - this.polls = []; - this.ready = false; - this.provider = undefined; - this.id = 1; - - var self = this; - var poll = function () { - if (self.provider && self.provider.poll) { - self.polls.forEach(function (data) { - data.data._id = self.id; - self.id++; - self.provider.poll(data.data, data.id); - }); - } - setTimeout(poll, 12000); - }; - poll(); -}; - -ProviderManager.prototype.send = function(data, cb) { - data._id = this.id; - if (cb) { - web3._callbacks[data._id] = cb; - } - - data.args = data.args || []; - this.id++; - - if(this.provider !== undefined) { - this.provider.send(data); - } else { - console.warn("provider is not set"); - this.queued.push(data); - } -}; - -ProviderManager.prototype.set = function(provider) { - if(this.provider !== undefined && this.provider.unload !== undefined) { - this.provider.unload(); - } - - this.provider = provider; - this.ready = true; -}; - -ProviderManager.prototype.sendQueued = function() { - for(var i = 0; this.queued.length; i++) { - // Resend - this.send(this.queued[i]); - } -}; - -ProviderManager.prototype.installed = function() { - return this.provider !== undefined; -}; - -ProviderManager.prototype.startPolling = function (data, pollId) { - if (!this.provider || !this.provider.poll) { - return; - } - this.polls.push({data: data, id: pollId}); -}; - -ProviderManager.prototype.stopPolling = function (pollId) { - for (var i = this.polls.length; i--;) { - var poll = this.polls[i]; - if (poll.id === pollId) { - this.polls.splice(i, 1); - } - } -}; -web3.provider = new ProviderManager(); +setupMethods(shhWatch, shhWatchMethods()); web3.setProvider = function(provider) { provider.onmessage = messageHandler; @@ -1054,60 +1376,7 @@ web3.setProvider = function(provider) { web3.provider.sendQueued(); }; -web3.haveProvider = function() { - return !!web3.provider.provider; -}; - -var Filter = function(options, impl) { - this.impl = impl; - this.callbacks = []; - - var self = this; - this.promise = impl.newFilter(options); - this.promise.then(function (id) { - self.id = id; - web3.on(impl.changed, id, self.trigger.bind(self)); - web3.provider.startPolling({call: impl.changed, args: [id]}, id); - }); -}; - -Filter.prototype.arrived = function(callback) { - this.changed(callback); -}; - -Filter.prototype.changed = function(callback) { - var self = this; - this.promise.then(function(id) { - self.callbacks.push(callback); - }); -}; - -Filter.prototype.trigger = function(messages) { - for(var i = 0; i < this.callbacks.length; i++) { - this.callbacks[i].call(this, messages); - } -}; - -Filter.prototype.uninstall = function() { - var self = this; - this.promise.then(function (id) { - self.impl.uninstallFilter(id); - web3.provider.stopPolling(id); - web3.off(impl.changed, id); - }); -}; - -Filter.prototype.messages = function() { - var self = this; - return this.promise.then(function (id) { - return self.impl.getMessages(id); - }); -}; - -Filter.prototype.logs = function () { - return this.messages(); -}; - +/// callled when there is new incoming message function messageHandler(data) { if(data._event !== undefined) { web3.trigger(data._event, data._id, data.data); @@ -1123,10 +1392,10 @@ function messageHandler(data) { } } -if (typeof(module) !== "undefined") - module.exports = web3; +module.exports = web3; -},{}],7:[function(require,module,exports){ + +},{}],9:[function(require,module,exports){ /* This file is part of ethereum.js. @@ -1156,9 +1425,17 @@ if ("build" !== 'build') {/* var WebSocket = require('ws'); // jshint ignore:line */} +/** + * WebSocketProvider object prototype is implementing 'provider protocol' + * Should be used when we want to connect to ethereum backend over websockets + * It's compatible with go client + * The constructor allows to specify host uri + */ var WebSocketProvider = function(host) { + // onmessage handlers this.handlers = []; + // queue will be filled with messages if send is invoked before the ws is ready this.queued = []; this.ready = false; @@ -1175,15 +1452,20 @@ var WebSocketProvider = function(host) { this.ws.onopen = function() { self.ready = true; - for(var i = 0; i < self.queued.length; i++) { + for (var i = 0; i < self.queued.length; i++) { // Resend self.send(self.queued[i]); } }; }; +/// Prototype object method +/// Should be called when we want to send single api request to server +/// Asynchronous, it's using websockets +/// Response for the call will be received by ws.onmessage +/// @param payload is inner message object WebSocketProvider.prototype.send = function(payload) { - if(this.ready) { + if (this.ready) { var data = JSON.stringify(payload); this.ws.send(data); @@ -1192,13 +1474,20 @@ WebSocketProvider.prototype.send = function(payload) { } }; +/// Prototype object method +/// Should be called to add handlers WebSocketProvider.prototype.onMessage = function(handler) { this.handlers.push(handler); }; +/// Prototype object method +/// Should be called to close websockets connection WebSocketProvider.prototype.unload = function() { this.ws.close(); }; + +/// Prototype object property +/// Should be used to set message handlers for this provider Object.defineProperty(WebSocketProvider.prototype, "onmessage", { set: function(provider) { this.onMessage(provider); } }); @@ -1208,15 +1497,18 @@ if (typeof(module) !== "undefined") },{}],"web3":[function(require,module,exports){ var web3 = require('./lib/web3'); +var ProviderManager = require('./lib/providermanager'); +web3.provider = new ProviderManager(); +web3.filter = require('./lib/filter'); web3.providers.WebSocketProvider = require('./lib/websocket'); web3.providers.HttpRpcProvider = require('./lib/httprpc'); web3.providers.QtProvider = require('./lib/qt'); web3.providers.AutoProvider = require('./lib/autoprovider'); -web3.contract = require('./lib/contract'); +web3.eth.contract = require('./lib/contract'); module.exports = web3; -},{"./lib/autoprovider":2,"./lib/contract":3,"./lib/httprpc":4,"./lib/qt":5,"./lib/web3":6,"./lib/websocket":7}]},{},["web3"]) +},{"./lib/autoprovider":2,"./lib/contract":3,"./lib/filter":4,"./lib/httprpc":5,"./lib/providermanager":6,"./lib/qt":7,"./lib/web3":8,"./lib/websocket":9}]},{},["web3"]) //# sourceMappingURL=ethereum.js.map \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/ethereum.js.map b/libjsqrc/ethereumjs/dist/ethereum.js.map index 7c500f07c..c850654d7 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.js.map +++ b/libjsqrc/ethereumjs/dist/ethereum.js.map @@ -5,25 +5,29 @@ "lib/abi.js", "lib/autoprovider.js", "lib/contract.js", + "lib/filter.js", "lib/httprpc.js", + "lib/providermanager.js", "lib/qt.js", "lib/web3.js", "lib/websocket.js", "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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;AC7CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;;AC9EA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5XA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;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;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1ZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClGA;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/** @file abi.js\n * @authors:\n * Marek Kotewicz \n * Gav Wood \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var web3 = require('./web3'); // jshint ignore:line\n*/}\n\n// TODO: make these be actually accurate instead of falling back onto JS's doubles.\nvar hexToDec = function (hex) {\n return parseInt(hex, 16).toString();\n};\n\nvar decToHex = function (dec) {\n return parseInt(dec).toString(16);\n};\n\nvar findIndex = function (array, callback) {\n var end = false;\n var i = 0;\n for (; i < array.length && !end; i++) {\n end = callback(array[i]);\n }\n return end ? i - 1 : -1;\n};\n\nvar findMethodIndex = function (json, methodName) {\n return findIndex(json, function (method) {\n return method.name === methodName;\n });\n};\n\nvar padLeft = function (string, chars) {\n return new Array(chars - string.length + 1).join(\"0\") + string;\n};\n\nvar calcBitPadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n return parseInt(value) / 8;\n};\n\nvar calcBytePadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n return parseInt(value);\n};\n\nvar calcRealPadding = function (type, expected) {\n var value = type.slice(expected.length);\n if (value === \"\") {\n return 32;\n }\n var sizes = value.split('x');\n for (var padding = 0, i = 0; i < sizes; i++) {\n padding += (sizes[i] / 8);\n }\n return padding;\n};\n\nvar setupInputTypes = function () {\n \n // convert from int, decimal-string, prefixed hex string whatever into a bare hex string.\n var formatStandard = function (value) {\n if (typeof value === \"number\")\n return value.toString(16);\n else if (typeof value === \"string\" && value.indexOf('0x') === 0)\n return value.substr(2);\n// else if (typeof value === \"string\")\n// return web3.toHex(value);\n else\n return (+value).toString(16);\n };\n\n var prefixedType = function (prefix, calcPadding) {\n return function (type, value) {\n var expected = prefix;\n if (type.indexOf(expected) !== 0) {\n return false;\n }\n\n var padding = calcPadding(type, expected);\n if (padding > 32)\n return false; // not allowed to be so big.\n padding = 32; // override as per the new ABI.\n\n if (prefix === \"string\")\n return web3.fromAscii(value, padding).substr(2);\n return padLeft(formatStandard(value), padding * 2);\n };\n };\n\n var namedType = function (name, padding, formatter) {\n return function (type, value) {\n if (type !== name) {\n return false;\n }\n\n padding = 32; //override as per the new ABI.\n\n return padLeft(formatter ? formatter(value) : value, padding * 2);\n };\n };\n\n var formatBool = function (value) {\n return value ? '01' : '00';\n };\n\n return [\n prefixedType('uint', calcBitPadding),\n prefixedType('int', calcBitPadding),\n prefixedType('hash', calcBitPadding),\n prefixedType('string', calcBytePadding),\n prefixedType('real', calcRealPadding),\n prefixedType('ureal', calcRealPadding),\n namedType('address', 20, formatStandard),\n namedType('bool', 1, formatBool),\n ];\n};\n\nvar inputTypes = setupInputTypes();\n\nvar toAbiInput = function (json, methodName, params) {\n var bytes = \"\";\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n var method = json[index];\n\n for (var i = 0; i < method.inputs.length; i++) {\n var found = false;\n for (var j = 0; j < inputTypes.length && !found; j++) {\n found = inputTypes[j](method.inputs[i].type, params[i]);\n }\n if (!found) {\n console.error('unsupported json type: ' + method.inputs[i].type);\n }\n bytes += found;\n }\n return bytes;\n};\n\nvar setupOutputTypes = function () {\n\n var prefixedType = function (prefix, calcPadding) {\n return function (type) {\n var expected = prefix;\n if (type.indexOf(expected) !== 0) {\n return -1;\n }\n\n var padding = calcPadding(type, expected);\n if (padding > 32)\n return -1; // not allowed to be so big.\n padding = 32; // override as per the new ABI.\n return padding * 2;\n };\n };\n\n var namedType = function (name, padding) {\n return function (type) {\n padding = 32; // override as per the new ABI.\n return name === type ? padding * 2 : -1;\n };\n };\n\n var formatInt = function (value) {\n return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value);\n };\n\n var formatHash = function (value) {\n return \"0x\" + value;\n };\n\n var formatBool = function (value) {\n return value === '1' ? true : false;\n };\n\n var formatString = function (value) {\n return web3.toAscii(value);\n };\n\n return [\n { padding: prefixedType('uint', calcBitPadding), format: formatInt },\n { padding: prefixedType('int', calcBitPadding), format: formatInt },\n { padding: prefixedType('hash', calcBitPadding), format: formatHash },\n { padding: prefixedType('string', calcBytePadding), format: formatString },\n { padding: prefixedType('real', calcRealPadding), format: formatInt },\n { padding: prefixedType('ureal', calcRealPadding), format: formatInt },\n { padding: namedType('address', 20) },\n { padding: namedType('bool', 1), format: formatBool }\n ];\n};\n\nvar outputTypes = setupOutputTypes();\n\nvar fromAbiOutput = function (json, methodName, output) {\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n output = output.slice(2);\n\n var result = [];\n var method = json[index];\n for (var i = 0; i < method.outputs.length; i++) {\n var padding = -1;\n for (var j = 0; j < outputTypes.length && padding === -1; j++) {\n padding = outputTypes[j].padding(method.outputs[i].type);\n }\n\n if (padding === -1) {\n // not found output parsing\n continue;\n }\n var res = output.slice(0, padding);\n var formatter = outputTypes[j - 1].format;\n result.push(formatter ? formatter(res) : (\"0x\" + res));\n output = output.slice(padding);\n }\n\n return result;\n};\n\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function () {\n var params = Array.prototype.slice.call(arguments);\n return toAbiInput(json, method.name, params);\n };\n });\n\n return parser;\n};\n\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function (output) {\n return fromAbiOutput(json, method.name, output);\n };\n });\n\n return parser;\n};\n\nvar methodSignature = function (json, name) {\n var method = json[findMethodIndex(json, name)];\n var result = name + '(';\n var inputTypes = method.inputs.map(function (inp) {\n return inp.type;\n });\n result += inputTypes.join(',');\n result += ')';\n\n return web3.sha3(web3.fromAscii(result));\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n methodSignature: methodSignature\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 autoprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n/*\n * @brief if qt object is available, uses QtProvider,\n * if not tries to connect over websockets\n * if it fails, it uses HttpRpcProvider\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var WebSocket = require('ws'); // jshint ignore:line\n var web3 = require('./web3'); // jshint ignore:line\n*/}\n\nvar AutoProvider = function (userOptions) {\n if (web3.haveProvider()) {\n return;\n }\n\n // before we determine what provider we are, we have to cache request\n this.sendQueue = [];\n this.onmessageQueue = [];\n\n if (navigator.qt) {\n this.provider = new web3.providers.QtProvider();\n return;\n }\n\n userOptions = userOptions || {};\n var options = {\n httprpc: userOptions.httprpc || 'http://localhost:8080',\n websockets: userOptions.websockets || 'ws://localhost:40404/eth'\n };\n\n var self = this;\n var closeWithSuccess = function (success) {\n ws.close();\n if (success) {\n self.provider = new web3.providers.WebSocketProvider(options.websockets);\n } else {\n self.provider = new web3.providers.HttpRpcProvider(options.httprpc);\n self.poll = self.provider.poll.bind(self.provider);\n }\n self.sendQueue.forEach(function (payload) {\n self.provider(payload);\n });\n self.onmessageQueue.forEach(function (handler) {\n self.provider.onmessage = handler;\n });\n };\n\n var ws = new WebSocket(options.websockets);\n\n ws.onopen = function() {\n closeWithSuccess(true);\n };\n\n ws.onerror = function() {\n closeWithSuccess(false);\n };\n};\n\nAutoProvider.prototype.send = function (payload) {\n if (this.provider) {\n this.provider.send(payload);\n return;\n }\n this.sendQueue.push(payload);\n};\n\nObject.defineProperty(AutoProvider.prototype, 'onmessage', {\n set: function (handler) {\n if (this.provider) {\n this.provider.onmessage = handler;\n return;\n }\n this.onmessageQueue.push(handler);\n }\n});\n\nmodule.exports = AutoProvider;\n", - "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file contract.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var web3 = require('./web3'); // jshint ignore:line\n*/}\n\nvar abi = require('./abi');\n\n// method signature length in bytes\nvar ETH_METHOD_SIGNATURE_LENGTH = 4;\n\nvar contract = function (address, desc) {\n var inputParser = abi.inputParser(desc);\n var outputParser = abi.outputParser(desc);\n\n var contract = {};\n\n desc.forEach(function (method) {\n contract[method.name] = function () {\n var params = Array.prototype.slice.call(arguments);\n var parsed = inputParser[method.name].apply(null, params);\n\n var onSuccess = function (result) {\n return outputParser[method.name](result);\n };\n\n return {\n call: function (extra) {\n extra = extra || {};\n extra.to = address;\n return abi.methodSignature(desc, method.name).then(function (signature) {\n extra.data = signature.slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2) + parsed;\n return web3.eth.call(extra).then(onSuccess);\n });\n },\n transact: function (extra) {\n extra = extra || {};\n extra.to = address;\n return abi.methodSignature(desc, method.name).then(function (signature) {\n extra.data = signature.slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2) + parsed;\n return web3.eth.transact(extra).then(onSuccess);\n });\n }\n };\n };\n });\n\n return contract;\n};\n\nmodule.exports = contract;\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 httprpc.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\n*/}\n\nvar HttpRpcProvider = function (host) {\n this.handlers = [];\n this.host = host;\n};\n\nfunction formatJsonRpcObject(object) {\n return {\n jsonrpc: '2.0',\n method: object.call,\n params: object.args,\n id: object._id\n };\n}\n\nfunction formatJsonRpcMessage(message) {\n var object = JSON.parse(message);\n\n return {\n _id: object.id,\n data: object.result,\n error: object.error\n };\n}\n\nHttpRpcProvider.prototype.sendRequest = function (payload, cb) {\n var data = formatJsonRpcObject(payload);\n\n var request = new XMLHttpRequest();\n request.open(\"POST\", this.host, true);\n request.send(JSON.stringify(data));\n request.onreadystatechange = function () {\n if (request.readyState === 4 && cb) {\n cb(request);\n }\n };\n};\n\nHttpRpcProvider.prototype.send = function (payload) {\n var self = this;\n this.sendRequest(payload, function (request) {\n self.handlers.forEach(function (handler) {\n handler.call(self, formatJsonRpcMessage(request.responseText));\n });\n });\n};\n\nHttpRpcProvider.prototype.poll = function (payload, id) {\n var self = this;\n this.sendRequest(payload, function (request) {\n var parsed = JSON.parse(request.responseText);\n if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {\n return;\n }\n self.handlers.forEach(function (handler) {\n handler.call(self, {_event: payload.call, _id: id, data: parsed.result});\n });\n });\n};\n\nObject.defineProperty(HttpRpcProvider.prototype, \"onmessage\", {\n set: function (handler) {\n this.handlers.push(handler);\n }\n});\n\nmodule.exports = HttpRpcProvider;\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 qt.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * @date 2014\n */\n\nvar QtProvider = function() {\n this.handlers = [];\n\n var self = this;\n navigator.qt.onmessage = function (message) {\n self.handlers.forEach(function (handler) {\n handler.call(self, JSON.parse(message.data));\n });\n };\n};\n\nQtProvider.prototype.send = function(payload) {\n navigator.qt.postMessage(JSON.stringify(payload));\n};\n\nObject.defineProperty(QtProvider.prototype, \"onmessage\", {\n set: function(handler) {\n this.handlers.push(handler);\n }\n});\n\nmodule.exports = QtProvider;\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 main.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Gav Wood \n * @date 2014\n */\n\nfunction flattenPromise (obj) {\n if (obj instanceof Promise) {\n return Promise.resolve(obj);\n }\n\n if (obj instanceof Array) {\n return new Promise(function (resolve) {\n var promises = obj.map(function (o) {\n return flattenPromise(o);\n });\n\n return Promise.all(promises).then(function (res) {\n for (var i = 0; i < obj.length; i++) {\n obj[i] = res[i];\n }\n resolve(obj);\n });\n });\n }\n\n if (obj instanceof Object) {\n return new Promise(function (resolve) {\n var keys = Object.keys(obj);\n var promises = keys.map(function (key) {\n return flattenPromise(obj[key]);\n });\n\n return Promise.all(promises).then(function (res) {\n for (var i = 0; i < keys.length; i++) {\n obj[keys[i]] = res[i];\n }\n resolve(obj);\n });\n });\n }\n\n return Promise.resolve(obj);\n}\n\nvar web3Methods = function () {\n return [\n { name: 'sha3', call: 'web3_sha3' }\n ];\n};\n\nvar ethMethods = function () {\n var blockCall = function (args) {\n return typeof args[0] === \"string\" ? \"eth_blockByHash\" : \"eth_blockByNumber\";\n };\n\n var transactionCall = function (args) {\n return typeof args[0] === \"string\" ? 'eth_transactionByHash' : 'eth_transactionByNumber';\n };\n\n var uncleCall = function (args) {\n return typeof args[0] === \"string\" ? 'eth_uncleByHash' : 'eth_uncleByNumber';\n };\n\n var methods = [\n { name: 'balanceAt', call: 'eth_balanceAt' },\n { name: 'stateAt', call: 'eth_stateAt' },\n { name: 'storageAt', call: 'eth_storageAt' },\n { name: 'countAt', call: 'eth_countAt'},\n { name: 'codeAt', call: 'eth_codeAt' },\n { name: 'transact', call: 'eth_transact' },\n { name: 'call', call: 'eth_call' },\n { name: 'block', call: blockCall },\n { name: 'transaction', call: transactionCall },\n { name: 'uncle', call: uncleCall },\n { name: 'compilers', call: 'eth_compilers' },\n { name: 'lll', call: 'eth_lll' },\n { name: 'solidity', call: 'eth_solidity' },\n { name: 'serpent', call: 'eth_serpent' },\n { name: 'logs', call: 'eth_logs' }\n ];\n return methods;\n};\n\nvar ethProperties = function () {\n return [\n { name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },\n { name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },\n { name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },\n { name: 'gasPrice', getter: 'eth_gasPrice' },\n { name: 'account', getter: 'eth_account' },\n { name: 'accounts', getter: 'eth_accounts' },\n { name: 'peerCount', getter: 'eth_peerCount' },\n { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },\n { name: 'number', getter: 'eth_number'}\n ];\n};\n\nvar dbMethods = function () {\n return [\n { name: 'put', call: 'db_put' },\n { name: 'get', call: 'db_get' },\n { name: 'putString', call: 'db_putString' },\n { name: 'getString', call: 'db_getString' }\n ];\n};\n\nvar shhMethods = function () {\n return [\n { name: 'post', call: 'shh_post' },\n { name: 'newIdentity', call: 'shh_newIdentity' },\n { name: 'haveIdentity', call: 'shh_haveIdentity' },\n { name: 'newGroup', call: 'shh_newGroup' },\n { name: 'addToGroup', call: 'shh_addToGroup' }\n ];\n};\n\nvar ethWatchMethods = function () {\n var newFilter = function (args) {\n return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';\n };\n\n return [\n { name: 'newFilter', call: newFilter },\n { name: 'uninstallFilter', call: 'eth_uninstallFilter' },\n { name: 'getMessages', call: 'eth_filterLogs' }\n ];\n};\n\nvar shhWatchMethods = function () {\n return [\n { name: 'newFilter', call: 'shh_newFilter' },\n { name: 'uninstallFilter', call: 'shh_uninstallFilter' },\n { name: 'getMessage', call: 'shh_getMessages' }\n ];\n};\n\nvar setupMethods = function (obj, methods) {\n methods.forEach(function (method) {\n obj[method.name] = function () {\n return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) {\n var call = typeof method.call === \"function\" ? method.call(args) : method.call;\n return {call: call, args: args};\n }).then(function (request) {\n return new Promise(function (resolve, reject) {\n web3.provider.send(request, function (err, result) {\n if (!err) {\n resolve(result);\n return;\n }\n reject(err);\n });\n });\n }).catch(function(err) {\n console.error(err);\n });\n };\n });\n};\n\nvar setupProperties = function (obj, properties) {\n properties.forEach(function (property) {\n var proto = {};\n proto.get = function () {\n return new Promise(function(resolve, reject) {\n web3.provider.send({call: property.getter}, function(err, result) {\n if (!err) {\n resolve(result);\n return;\n }\n reject(err);\n });\n });\n };\n if (property.setter) {\n proto.set = function (val) {\n return flattenPromise([val]).then(function (args) {\n return new Promise(function (resolve) {\n web3.provider.send({call: property.setter, args: args}, function (err, result) {\n if (!err) {\n resolve(result);\n return;\n }\n reject(err);\n });\n });\n }).catch(function (err) {\n console.error(err);\n });\n };\n }\n Object.defineProperty(obj, property.name, proto);\n });\n};\n\n// TODO: import from a dependency, don't duplicate.\nvar hexToDec = function (hex) {\n return parseInt(hex, 16).toString();\n};\n\nvar decToHex = function (dec) {\n return parseInt(dec).toString(16);\n};\n\n\nvar web3 = {\n _callbacks: {},\n _events: {},\n providers: {},\n\n toHex: 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 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 for(; i < l; i+=2) {\n var code = hex.charCodeAt(i);\n if(code === 0) {\n break;\n }\n\n str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));\n }\n\n return str;\n },\n\n fromAscii: function(str, pad) {\n pad = pad === undefined ? 0 : pad;\n var hex = this.toHex(str);\n while(hex.length < pad*2)\n hex += \"00\";\n return \"0x\" + hex;\n },\n\n toDecimal: function (val) {\n return hexToDec(val.substring(2));\n },\n\n fromDecimal: function (val) {\n return \"0x\" + decToHex(val);\n },\n\n toEth: function(str) {\n var val = typeof str === \"string\" ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;\n var unit = 0;\n var units = [ 'wei', 'Kwei', 'Mwei', 'Gwei', 'szabo', 'finney', 'ether', 'grand', 'Mether', 'Gether', 'Tether', 'Pether', 'Eether', 'Zether', 'Yether', 'Nether', 'Dether', 'Vether', 'Uether' ];\n while (val > 3000 && unit < units.length - 1)\n {\n val /= 1000;\n unit++;\n }\n var s = val.toString().length < val.toFixed(2).length ? val.toString() : val.toFixed(2);\n var replaceFunction = function($0, $1, $2) {\n return $1 + ',' + $2;\n };\n\n while (true) {\n var o = s;\n s = s.replace(/(\\d)(\\d\\d\\d[\\.\\,])/, replaceFunction);\n if (o === s)\n break;\n }\n return s + ' ' + units[unit];\n },\n\n eth: {\n prototype: Object(), // jshint ignore:line\n watch: function (params) {\n return new Filter(params, ethWatch);\n }\n },\n\n db: {\n prototype: Object() // jshint ignore:line\n },\n\n shh: {\n prototype: Object(), // jshint ignore:line\n watch: function (params) {\n return new Filter(params, shhWatch);\n }\n },\n\n on: function(event, id, cb) {\n if(web3._events[event] === undefined) {\n web3._events[event] = {};\n }\n\n web3._events[event][id] = cb;\n return this;\n },\n\n off: function(event, id) {\n if(web3._events[event] !== undefined) {\n delete web3._events[event][id];\n }\n\n return this;\n },\n\n trigger: function(event, id, data) {\n var callbacks = web3._events[event];\n if (!callbacks || !callbacks[id]) {\n return;\n }\n var cb = callbacks[id];\n cb(data);\n }\n};\n\nsetupMethods(web3, web3Methods());\nsetupMethods(web3.eth, ethMethods());\nsetupProperties(web3.eth, ethProperties());\nsetupMethods(web3.db, dbMethods());\nsetupMethods(web3.shh, shhMethods());\n\nvar ethWatch = {\n changed: 'eth_changed'\n};\nsetupMethods(ethWatch, ethWatchMethods());\nvar shhWatch = {\n changed: 'shh_changed'\n};\nsetupMethods(shhWatch, shhWatchMethods());\n\nvar ProviderManager = function() {\n this.queued = [];\n this.polls = [];\n this.ready = false;\n this.provider = undefined;\n this.id = 1;\n\n var self = this;\n var poll = function () {\n if (self.provider && self.provider.poll) {\n self.polls.forEach(function (data) {\n data.data._id = self.id;\n self.id++;\n self.provider.poll(data.data, data.id);\n });\n }\n setTimeout(poll, 12000);\n };\n poll();\n};\n\nProviderManager.prototype.send = function(data, cb) {\n data._id = this.id;\n if (cb) {\n web3._callbacks[data._id] = cb;\n }\n\n data.args = data.args || [];\n this.id++;\n\n if(this.provider !== undefined) {\n this.provider.send(data);\n } else {\n console.warn(\"provider is not set\");\n this.queued.push(data);\n }\n};\n\nProviderManager.prototype.set = function(provider) {\n if(this.provider !== undefined && this.provider.unload !== undefined) {\n this.provider.unload();\n }\n\n this.provider = provider;\n this.ready = true;\n};\n\nProviderManager.prototype.sendQueued = function() {\n for(var i = 0; this.queued.length; i++) {\n // Resend\n this.send(this.queued[i]);\n }\n};\n\nProviderManager.prototype.installed = function() {\n return this.provider !== undefined;\n};\n\nProviderManager.prototype.startPolling = function (data, pollId) {\n if (!this.provider || !this.provider.poll) {\n return;\n }\n this.polls.push({data: data, id: pollId});\n};\n\nProviderManager.prototype.stopPolling = function (pollId) {\n for (var i = this.polls.length; i--;) {\n var poll = this.polls[i];\n if (poll.id === pollId) {\n this.polls.splice(i, 1);\n }\n }\n};\n\nweb3.provider = new ProviderManager();\n\nweb3.setProvider = function(provider) {\n provider.onmessage = messageHandler;\n web3.provider.set(provider);\n web3.provider.sendQueued();\n};\n\nweb3.haveProvider = function() {\n return !!web3.provider.provider;\n};\n\nvar Filter = function(options, impl) {\n this.impl = impl;\n this.callbacks = [];\n\n var self = this;\n this.promise = impl.newFilter(options);\n this.promise.then(function (id) {\n self.id = id;\n web3.on(impl.changed, id, self.trigger.bind(self));\n web3.provider.startPolling({call: impl.changed, args: [id]}, id);\n });\n};\n\nFilter.prototype.arrived = function(callback) {\n this.changed(callback);\n};\n\nFilter.prototype.changed = function(callback) {\n var self = this;\n this.promise.then(function(id) {\n self.callbacks.push(callback);\n });\n};\n\nFilter.prototype.trigger = function(messages) {\n for(var i = 0; i < this.callbacks.length; i++) {\n this.callbacks[i].call(this, messages);\n }\n};\n\nFilter.prototype.uninstall = function() {\n var self = this;\n this.promise.then(function (id) {\n self.impl.uninstallFilter(id);\n web3.provider.stopPolling(id);\n web3.off(impl.changed, id);\n });\n};\n\nFilter.prototype.messages = function() {\n var self = this;\n return this.promise.then(function (id) {\n return self.impl.getMessages(id);\n });\n};\n\nFilter.prototype.logs = function () {\n return this.messages();\n};\n\nfunction messageHandler(data) {\n if(data._event !== undefined) {\n web3.trigger(data._event, data._id, data.data);\n return;\n }\n\n if(data._id) {\n var cb = web3._callbacks[data._id];\n if (cb) {\n cb.call(this, data.error, data.data);\n delete web3._callbacks[data._id];\n }\n }\n}\n\nif (typeof(module) !== \"undefined\")\n module.exports = web3;\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 websocket.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var WebSocket = require('ws'); // jshint ignore:line\n*/}\n\nvar WebSocketProvider = function(host) {\n // onmessage handlers\n this.handlers = [];\n // queue will be filled with messages if send is invoked before the ws is ready\n this.queued = [];\n this.ready = false;\n\n this.ws = new WebSocket(host);\n\n var self = this;\n this.ws.onmessage = function(event) {\n for(var i = 0; i < self.handlers.length; i++) {\n self.handlers[i].call(self, JSON.parse(event.data), event);\n }\n };\n\n this.ws.onopen = function() {\n self.ready = true;\n\n for(var i = 0; i < self.queued.length; i++) {\n // Resend\n self.send(self.queued[i]);\n }\n };\n};\n\nWebSocketProvider.prototype.send = function(payload) {\n if(this.ready) {\n var data = JSON.stringify(payload);\n\n this.ws.send(data);\n } else {\n this.queued.push(payload);\n }\n};\n\nWebSocketProvider.prototype.onMessage = function(handler) {\n this.handlers.push(handler);\n};\n\nWebSocketProvider.prototype.unload = function() {\n this.ws.close();\n};\nObject.defineProperty(WebSocketProvider.prototype, \"onmessage\", {\n set: function(provider) { this.onMessage(provider); }\n});\n\nif (typeof(module) !== \"undefined\")\n module.exports = WebSocketProvider;\n", - "var web3 = require('./lib/web3');\nweb3.providers.WebSocketProvider = require('./lib/websocket');\nweb3.providers.HttpRpcProvider = require('./lib/httprpc');\nweb3.providers.QtProvider = require('./lib/qt');\nweb3.providers.AutoProvider = require('./lib/autoprovider');\nweb3.contract = require('./lib/contract');\n\nmodule.exports = web3;\n" + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file abi.js\n * @authors:\n * Marek Kotewicz \n * Gav Wood \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var BigNumber = require('bignumber.js'); // jshint ignore:line\n*/}\n\nvar web3 = require('./web3'); // jshint ignore:line\n\nBigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN });\n\nvar ETH_PADDING = 32;\n\n/// Finds first index of array element matching pattern\n/// @param array\n/// @param callback pattern\n/// @returns index of element\nvar findIndex = function (array, callback) {\n var end = false;\n var i = 0;\n for (; i < array.length && !end; i++) {\n end = callback(array[i]);\n }\n return end ? i - 1 : -1;\n};\n\n/// @returns a function that is used as a pattern for 'findIndex'\nvar findMethodIndex = function (json, methodName) {\n return findIndex(json, function (method) {\n return method.name === methodName;\n });\n};\n\n/// @param string string to be padded\n/// @param number of characters that result string should have\n/// @param sign, by default 0\n/// @returns right aligned string\nvar padLeft = function (string, chars, sign) {\n return new Array(chars - string.length + 1).join(sign ? sign : \"0\") + string;\n};\n\n/// @param expected type prefix (string)\n/// @returns function which checks if type has matching prefix. if yes, returns true, otherwise false\nvar prefixedType = function (prefix) {\n return function (type) {\n return type.indexOf(prefix) === 0;\n };\n};\n\n/// @param expected type name (string)\n/// @returns function which checks if type is matching expected one. if yes, returns true, otherwise false\nvar namedType = function (name) {\n return function (type) {\n return name === type;\n };\n};\n\nvar arrayType = function (type) {\n return type.slice(-2) === '[]';\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/// @returns right-aligned byte representation of int\nvar formatInputInt = function (value) {\n var padding = ETH_PADDING * 2;\n if (value instanceof BigNumber || typeof value === 'number') {\n if (typeof value === 'number')\n value = new BigNumber(value);\n value = value.round();\n\n if (value.lessThan(0)) \n value = new BigNumber(\"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff\", 16).plus(value).plus(1);\n value = value.toString(16);\n }\n else if (value.indexOf('0x') === 0)\n value = value.substr(2);\n else if (typeof value === 'string')\n value = formatInputInt(new BigNumber(value));\n else\n value = (+value).toString(16);\n return padLeft(value, padding);\n};\n\n/// Formats input value to byte representation of string\n/// @returns left-algined byte representation of string\nvar formatInputString = function (value) {\n return web3.fromAscii(value, ETH_PADDING).substr(2);\n};\n\n/// Formats input value to byte representation of bool\n/// @returns right-aligned byte representation bool\nvar formatInputBool = function (value) {\n return '000000000000000000000000000000000000000000000000000000000000000' + (value ? '1' : '0');\n};\n\n/// Formats input value to byte representation of real\n/// Values are multiplied by 2^m and encoded as integers\n/// @returns byte representation of real\nvar formatInputReal = function (value) {\n return formatInputInt(new BigNumber(value).times(new BigNumber(2).pow(128))); \n};\n\nvar dynamicTypeBytes = function (type, value) {\n // TODO: decide what to do with array of strings\n if (arrayType(type) || prefixedType('string')(type))\n return formatInputInt(value.length); \n return \"\";\n};\n\n/// Setups input formatters for solidity types\n/// @returns an array of input formatters \nvar setupInputTypes = function () {\n \n return [\n { type: prefixedType('uint'), format: formatInputInt },\n { type: prefixedType('int'), format: formatInputInt },\n { type: prefixedType('hash'), format: formatInputInt },\n { type: prefixedType('string'), format: formatInputString }, \n { type: prefixedType('real'), format: formatInputReal },\n { type: prefixedType('ureal'), format: formatInputReal },\n { type: namedType('address'), format: formatInputInt },\n { type: namedType('bool'), format: formatInputBool }\n ];\n};\n\nvar inputTypes = setupInputTypes();\n\n/// Formats input params to bytes\n/// @param contract json abi\n/// @param name of the method that we want to use\n/// @param array of params that will be formatted to bytes\n/// @returns bytes representation of input params\nvar toAbiInput = function (json, methodName, params) {\n var bytes = \"\";\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n var method = json[index];\n var padding = ETH_PADDING * 2;\n\n /// first we iterate in search for dynamic \n method.inputs.forEach(function (input, index) {\n bytes += dynamicTypeBytes(input.type, params[index]);\n });\n\n method.inputs.forEach(function (input, i) {\n var typeMatch = false;\n for (var j = 0; j < inputTypes.length && !typeMatch; j++) {\n typeMatch = inputTypes[j].type(method.inputs[i].type, params[i]);\n }\n if (!typeMatch) {\n console.error('input parser does not support type: ' + method.inputs[i].type);\n }\n\n var formatter = inputTypes[j - 1].format;\n var toAppend = \"\";\n\n if (arrayType(method.inputs[i].type))\n toAppend = params[i].reduce(function (acc, curr) {\n return acc + formatter(curr);\n }, \"\");\n else\n toAppend = formatter(params[i]);\n\n bytes += toAppend; \n });\n return bytes;\n};\n\n/// Check if input value is negative\n/// @param value is hex format\n/// @returns true if it is negative, otherwise false\nvar signedIsNegative = function (value) {\n return (new BigNumber(value.substr(0, 1), 16).toString(2).substr(0, 1)) === '1';\n};\n\n/// Formats input right-aligned input bytes to int\n/// @returns right-aligned input bytes formatted to int\nvar formatOutputInt = function (value) {\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/// Formats big right-aligned input bytes to uint\n/// @returns right-aligned input bytes formatted to uint\nvar formatOutputUInt = function (value) {\n return new BigNumber(value, 16);\n};\n\n/// @returns input bytes formatted to real\nvar formatOutputReal = function (value) {\n return formatOutputInt(value).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/// @returns input bytes formatted to ureal\nvar formatOutputUReal = function (value) {\n return formatOutputUInt(value).dividedBy(new BigNumber(2).pow(128)); \n};\n\n/// @returns right-aligned input bytes formatted to hex\nvar formatOutputHash = function (value) {\n return \"0x\" + value;\n};\n\n/// @returns right-aligned input bytes formatted to bool\nvar formatOutputBool = function (value) {\n return value === '0000000000000000000000000000000000000000000000000000000000000001' ? true : false;\n};\n\n/// @returns left-aligned input bytes formatted to ascii string\nvar formatOutputString = function (value) {\n return web3.toAscii(value);\n};\n\n/// @returns right-aligned input bytes formatted to address\nvar formatOutputAddress = function (value) {\n return \"0x\" + value.slice(value.length - 40, value.length);\n};\n\nvar dynamicBytesLength = function (type) {\n if (arrayType(type) || prefixedType('string')(type))\n return ETH_PADDING * 2;\n return 0;\n};\n\n/// Setups output formaters for solidity types\n/// @returns an array of output formatters\nvar setupOutputTypes = function () {\n\n return [\n { type: prefixedType('uint'), format: formatOutputUInt },\n { type: prefixedType('int'), format: formatOutputInt },\n { type: prefixedType('hash'), format: formatOutputHash },\n { type: prefixedType('string'), format: formatOutputString },\n { type: prefixedType('real'), format: formatOutputReal },\n { type: prefixedType('ureal'), format: formatOutputUReal },\n { type: namedType('address'), format: formatOutputAddress },\n { type: namedType('bool'), format: formatOutputBool }\n ];\n};\n\nvar outputTypes = setupOutputTypes();\n\n/// Formats output bytes back to param list\n/// @param contract json abi\n/// @param name of the method that we want to use\n/// @param bytes representtion of output \n/// @returns array of output params \nvar fromAbiOutput = function (json, methodName, output) {\n var index = findMethodIndex(json, methodName);\n\n if (index === -1) {\n return;\n }\n\n output = output.slice(2);\n\n var result = [];\n var method = json[index];\n var padding = ETH_PADDING * 2;\n\n var dynamicPartLength = method.outputs.reduce(function (acc, curr) {\n return acc + dynamicBytesLength(curr.type);\n }, 0);\n \n var dynamicPart = output.slice(0, dynamicPartLength);\n output = output.slice(dynamicPartLength);\n\n method.outputs.forEach(function (out, i) {\n var typeMatch = false;\n for (var j = 0; j < outputTypes.length && !typeMatch; j++) {\n typeMatch = outputTypes[j].type(method.outputs[i].type);\n }\n\n if (!typeMatch) {\n console.error('output parser does not support type: ' + method.outputs[i].type);\n }\n\n var formatter = outputTypes[j - 1].format;\n if (arrayType(method.outputs[i].type)) {\n var size = formatOutputUInt(dynamicPart.slice(0, padding));\n dynamicPart = dynamicPart.slice(padding);\n var array = [];\n for (var k = 0; k < size; k++) {\n array.push(formatter(output.slice(0, padding))); \n output = output.slice(padding);\n }\n result.push(array);\n }\n else if (prefixedType('string')(method.outputs[i].type)) {\n dynamicPart = dynamicPart.slice(padding); \n result.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n } else {\n result.push(formatter(output.slice(0, padding)));\n output = output.slice(padding);\n }\n });\n\n return result;\n};\n\n/// @param json abi for contract\n/// @returns input parser object for given json abi\nvar inputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function () {\n var params = Array.prototype.slice.call(arguments);\n return toAbiInput(json, method.name, params);\n };\n });\n\n return parser;\n};\n\n/// @param json abi for contract\n/// @returns output parser for given json abi\nvar outputParser = function (json) {\n var parser = {};\n json.forEach(function (method) {\n parser[method.name] = function (output) {\n return fromAbiOutput(json, method.name, output);\n };\n });\n\n return parser;\n};\n\n/// @param json abi for contract\n/// @param method name for which we want to get method signature\n/// @returns (promise) contract method signature for method with given name\nvar methodSignature = function (json, name) {\n var method = json[findMethodIndex(json, name)];\n var result = name + '(';\n var inputTypes = method.inputs.map(function (inp) {\n return inp.type;\n });\n result += inputTypes.join(',');\n result += ')';\n\n return web3.sha3(web3.fromAscii(result));\n};\n\nmodule.exports = {\n inputParser: inputParser,\n outputParser: outputParser,\n methodSignature: methodSignature\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 autoprovider.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n/*\n * @brief if qt object is available, uses QtProvider,\n * if not tries to connect over websockets\n * if it fails, it uses HttpRpcProvider\n */\n\nvar web3 = require('./web3'); // jshint ignore:line\nif (\"build\" !== 'build') {/*\n var WebSocket = require('ws'); // jshint ignore:line\n*/}\n\n/**\n * AutoProvider object prototype is implementing 'provider protocol'\n * Automatically tries to setup correct provider(Qt, WebSockets or HttpRpc)\n * First it checkes if we are ethereum browser (if navigator.qt object is available)\n * if yes, we are using QtProvider\n * if no, we check if it is possible to establish websockets connection with ethereum (ws://localhost:40404/eth is default)\n * if it's not possible, we are using httprpc provider (http://localhost:8080)\n * The constructor allows you to specify uris on which we are trying to connect over http or websockets\n * You can do that by passing objects with fields httrpc and websockets\n */\nvar AutoProvider = function (userOptions) {\n if (web3.haveProvider()) {\n return;\n }\n\n // before we determine what provider we are, we have to cache request\n this.sendQueue = [];\n this.onmessageQueue = [];\n\n if (navigator.qt) {\n this.provider = new web3.providers.QtProvider();\n return;\n }\n\n userOptions = userOptions || {};\n var options = {\n httprpc: userOptions.httprpc || 'http://localhost:8080',\n websockets: userOptions.websockets || 'ws://localhost:40404/eth'\n };\n\n var self = this;\n var closeWithSuccess = function (success) {\n ws.close();\n if (success) {\n self.provider = new web3.providers.WebSocketProvider(options.websockets);\n } else {\n self.provider = new web3.providers.HttpRpcProvider(options.httprpc);\n self.poll = self.provider.poll.bind(self.provider);\n }\n self.sendQueue.forEach(function (payload) {\n self.provider.send(payload);\n });\n self.onmessageQueue.forEach(function (handler) {\n self.provider.onmessage = handler;\n });\n };\n\n var ws = new WebSocket(options.websockets);\n\n ws.onopen = function() {\n closeWithSuccess(true);\n };\n\n ws.onerror = function() {\n closeWithSuccess(false);\n };\n};\n\n/// Sends message forward to the provider, that is being used\n/// if provider is not yet set, enqueues the message\nAutoProvider.prototype.send = function (payload) {\n if (this.provider) {\n this.provider.send(payload);\n return;\n }\n this.sendQueue.push(payload);\n};\n\n/// On incoming message sends the message to the provider that is currently being used\nObject.defineProperty(AutoProvider.prototype, 'onmessage', {\n set: function (handler) {\n if (this.provider) {\n this.provider.onmessage = handler;\n return;\n }\n this.onmessageQueue.push(handler);\n }\n});\n\nmodule.exports = AutoProvider;\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file contract.js\n * @authors:\n * Marek Kotewicz \n * @date 2014\n */\n\nvar web3 = require('./web3'); // jshint ignore:line\nvar abi = require('./abi');\n\n/// method signature length in bytes\nvar ETH_METHOD_SIGNATURE_LENGTH = 4;\n\n/**\n * This method should be called when we want to call / transact some solidity method from javascript\n * it returns an object which has same methods available as solidity contract description\n * usage example: \n *\n * var abi = [{\n * name: 'myMethod',\n * inputs: [{ name: 'a', type: 'string' }],\n * outputs: [{name: 'd', type: 'string' }]\n * }]; // contract abi\n *\n * var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object\n *\n * myContract.myMethod('this is test string param for call').call(); // myMethod call\n * myContract.myMethod('this is test string param for transact').transact() // myMethod transact\n *\n * @param address - address of the contract, which should be called\n * @param desc - abi json description of the contract, which is being created\n * @returns contract object\n */\nvar contract = function (address, desc) {\n var inputParser = abi.inputParser(desc);\n var outputParser = abi.outputParser(desc);\n\n var contract = {};\n\n desc.forEach(function (method) {\n contract[method.name] = function () {\n var params = Array.prototype.slice.call(arguments);\n var parsed = inputParser[method.name].apply(null, params);\n\n var onSuccess = function (result) {\n return outputParser[method.name](result);\n };\n\n return {\n call: function (extra) {\n extra = extra || {};\n extra.to = address;\n return abi.methodSignature(desc, method.name).then(function (signature) {\n extra.data = signature.slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2) + parsed;\n return web3.eth.call(extra).then(onSuccess);\n });\n },\n transact: function (extra) {\n extra = extra || {};\n extra.to = address;\n return abi.methodSignature(desc, method.name).then(function (signature) {\n extra.data = signature.slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2) + parsed;\n return web3.eth.transact(extra).then(onSuccess);\n });\n }\n };\n };\n });\n\n return contract;\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 filter.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Gav Wood \n * @date 2014\n */\n\nvar web3 = require('./web3'); // jshint ignore:line\n\n/// should be used when we want to watch something\n/// it's using inner polling mechanism and is notified about changes\nvar Filter = function(options, impl) {\n this.impl = impl;\n this.callbacks = [];\n\n var self = this;\n this.promise = impl.newFilter(options);\n this.promise.then(function (id) {\n self.id = id;\n web3.on(impl.changed, id, self.trigger.bind(self));\n web3.provider.startPolling({call: impl.changed, args: [id]}, id);\n });\n};\n\n/// alias for changed*\nFilter.prototype.arrived = function(callback) {\n this.changed(callback);\n};\n\n/// gets called when there is new eth/shh message\nFilter.prototype.changed = function(callback) {\n var self = this;\n this.promise.then(function(id) {\n self.callbacks.push(callback);\n });\n};\n\n/// trigger calling new message from people\nFilter.prototype.trigger = function(messages) {\n for(var i = 0; i < this.callbacks.length; i++) {\n this.callbacks[i].call(this, messages);\n }\n};\n\n/// should be called to uninstall current filter\nFilter.prototype.uninstall = function() {\n var self = this;\n this.promise.then(function (id) {\n self.impl.uninstallFilter(id);\n web3.provider.stopPolling(id);\n web3.off(impl.changed, id);\n });\n};\n\n/// should be called to manually trigger getting latest messages from the client\nFilter.prototype.messages = function() {\n var self = this;\n return this.promise.then(function (id) {\n return self.impl.getMessages(id);\n });\n};\n\n/// alias for messages\nFilter.prototype.logs = function () {\n return this.messages();\n};\n\nmodule.exports = Filter;\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 httprpc.js\n * @authors:\n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line\n*/}\n\n/**\n * HttpRpcProvider object prototype is implementing 'provider protocol'\n * Should be used when we want to connect to ethereum backend over http && jsonrpc\n * It's compatible with cpp client\n * The contructor allows to specify host uri\n * This provider is using in-browser polling mechanism\n */\nvar HttpRpcProvider = function (host) {\n this.handlers = [];\n this.host = host;\n};\n\n/// Transforms inner message to proper jsonrpc object\n/// @param inner message object\n/// @returns jsonrpc object\nfunction formatJsonRpcObject(object) {\n return {\n jsonrpc: '2.0',\n method: object.call,\n params: object.args,\n id: object._id\n };\n}\n\n/// Transforms jsonrpc object to inner message\n/// @param incoming jsonrpc message \n/// @returns inner message object\nfunction formatJsonRpcMessage(message) {\n var object = JSON.parse(message);\n\n return {\n _id: object.id,\n data: object.result,\n error: object.error\n };\n}\n\n/// Prototype object method \n/// Asynchronously sends request to server\n/// @param payload is inner message object\n/// @param cb is callback which is being called when response is comes back\nHttpRpcProvider.prototype.sendRequest = function (payload, cb) {\n var data = formatJsonRpcObject(payload);\n\n var request = new XMLHttpRequest();\n request.open(\"POST\", this.host, true);\n request.send(JSON.stringify(data));\n request.onreadystatechange = function () {\n if (request.readyState === 4 && cb) {\n cb(request);\n }\n };\n};\n\n/// Prototype object method\n/// Should be called when we want to send single api request to server\n/// Asynchronous\n/// On response it passes message to handlers\n/// @param payload is inner message object\nHttpRpcProvider.prototype.send = function (payload) {\n var self = this;\n this.sendRequest(payload, function (request) {\n self.handlers.forEach(function (handler) {\n handler.call(self, formatJsonRpcMessage(request.responseText));\n });\n });\n};\n\n/// Prototype object method\n/// Should be called only for polling requests\n/// Asynchronous\n/// On response it passege message to handlers, but only if message's result is true or not empty array\n/// Otherwise response is being silently ignored\n/// @param payload is inner message object\n/// @id is id of poll that we are calling\nHttpRpcProvider.prototype.poll = function (payload, id) {\n var self = this;\n this.sendRequest(payload, function (request) {\n var parsed = JSON.parse(request.responseText);\n if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {\n return;\n }\n self.handlers.forEach(function (handler) {\n handler.call(self, {_event: payload.call, _id: id, data: parsed.result});\n });\n });\n};\n\n/// Prototype object property\n/// Should be used to set message handlers for this provider\nObject.defineProperty(HttpRpcProvider.prototype, \"onmessage\", {\n set: function (handler) {\n this.handlers.push(handler);\n }\n});\n\nmodule.exports = HttpRpcProvider;\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 providermanager.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Gav Wood \n * @date 2014\n */\n\nvar web3 = require('./web3'); // jshint ignore:line\n\n/**\n * Provider manager object prototype\n * It's responsible for passing messages to providers\n * If no provider is set it's responsible for queuing requests\n * It's also responsible for polling the ethereum node for incoming messages\n * Default poll timeout is 12 seconds\n * If we are running ethereum.js inside ethereum browser, there are backend based tools responsible for polling,\n * and provider manager polling mechanism is not used\n */\nvar ProviderManager = function() {\n this.queued = [];\n this.polls = [];\n this.ready = false;\n this.provider = undefined;\n this.id = 1;\n\n var self = this;\n var poll = function () {\n if (self.provider && self.provider.poll) {\n self.polls.forEach(function (data) {\n data.data._id = self.id;\n self.id++;\n self.provider.poll(data.data, data.id);\n });\n }\n setTimeout(poll, 12000);\n };\n poll();\n};\n\n/// sends outgoing requests, if provider is not available, enqueue the request\nProviderManager.prototype.send = function(data, cb) {\n data._id = this.id;\n if (cb) {\n web3._callbacks[data._id] = cb;\n }\n\n data.args = data.args || [];\n this.id++;\n\n if(this.provider !== undefined) {\n this.provider.send(data);\n } else {\n console.warn(\"provider is not set\");\n this.queued.push(data);\n }\n};\n\n/// setups provider, which will be used for sending messages\nProviderManager.prototype.set = function(provider) {\n if(this.provider !== undefined && this.provider.unload !== undefined) {\n this.provider.unload();\n }\n\n this.provider = provider;\n this.ready = true;\n};\n\n/// resends queued messages\nProviderManager.prototype.sendQueued = function() {\n for(var i = 0; this.queued.length; i++) {\n // Resend\n this.send(this.queued[i]);\n }\n};\n\n/// @returns true if the provider i properly set\nProviderManager.prototype.installed = function() {\n return this.provider !== undefined;\n};\n\n/// this method is only used, when we do not have native qt bindings and have to do polling on our own\n/// should be callled, on start watching for eth/shh changes\nProviderManager.prototype.startPolling = function (data, pollId) {\n if (!this.provider || !this.provider.poll) {\n return;\n }\n this.polls.push({data: data, id: pollId});\n};\n\n/// should be called to stop polling for certain watch changes\nProviderManager.prototype.stopPolling = function (pollId) {\n for (var i = this.polls.length; i--;) {\n var poll = this.polls[i];\n if (poll.id === pollId) {\n this.polls.splice(i, 1);\n }\n }\n};\n\nmodule.exports = ProviderManager;\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 qt.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * @date 2014\n */\n\n/**\n * QtProvider object prototype is implementing 'provider protocol'\n * Should be used inside ethereum browser. It's compatible with cpp and go clients.\n * It uses navigator.qt object to pass the messages to native bindings\n */\nvar QtProvider = function() {\n this.handlers = [];\n\n var self = this;\n navigator.qt.onmessage = function (message) {\n self.handlers.forEach(function (handler) {\n handler.call(self, JSON.parse(message.data));\n });\n };\n};\n\n/// Prototype object method\n/// Should be called when we want to send single api request to native bindings\n/// Asynchronous\n/// Response will be received by navigator.qt.onmessage method and passed to handlers\n/// @param payload is inner message object\nQtProvider.prototype.send = function(payload) {\n navigator.qt.postMessage(JSON.stringify(payload));\n};\n\n/// Prototype object property\n/// Should be used to set message handlers for this provider\nObject.defineProperty(QtProvider.prototype, \"onmessage\", {\n set: function(handler) {\n this.handlers.push(handler);\n }\n});\n\nmodule.exports = QtProvider;\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file web3.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * Gav Wood \n * @date 2014\n */\n\n/// Recursively resolves all promises in given object and replaces the resolved values with promises\n/// @param any object/array/promise/anything else..\n/// @returns (resolves) object with replaced promises with their result \nfunction flattenPromise (obj) {\n if (obj instanceof Promise) {\n return Promise.resolve(obj);\n }\n\n if (obj instanceof Array) {\n return new Promise(function (resolve) {\n var promises = obj.map(function (o) {\n return flattenPromise(o);\n });\n\n return Promise.all(promises).then(function (res) {\n for (var i = 0; i < obj.length; i++) {\n obj[i] = res[i];\n }\n resolve(obj);\n });\n });\n }\n\n if (obj instanceof Object) {\n return new Promise(function (resolve) {\n var keys = Object.keys(obj);\n var promises = keys.map(function (key) {\n return flattenPromise(obj[key]);\n });\n\n return Promise.all(promises).then(function (res) {\n for (var i = 0; i < keys.length; i++) {\n obj[keys[i]] = res[i];\n }\n resolve(obj);\n });\n });\n }\n\n return Promise.resolve(obj);\n}\n\n/// @returns an array of objects describing web3 api methods\nvar web3Methods = function () {\n return [\n { name: 'sha3', call: 'web3_sha3' }\n ];\n};\n\n/// @returns an array of objects describing web3.eth api methods\nvar ethMethods = function () {\n var blockCall = function (args) {\n return typeof args[0] === \"string\" ? \"eth_blockByHash\" : \"eth_blockByNumber\";\n };\n\n var transactionCall = function (args) {\n return typeof args[0] === \"string\" ? 'eth_transactionByHash' : 'eth_transactionByNumber';\n };\n\n var uncleCall = function (args) {\n return typeof args[0] === \"string\" ? 'eth_uncleByHash' : 'eth_uncleByNumber';\n };\n\n var methods = [\n { name: 'balanceAt', call: 'eth_balanceAt' },\n { name: 'stateAt', call: 'eth_stateAt' },\n { name: 'storageAt', call: 'eth_storageAt' },\n { name: 'countAt', call: 'eth_countAt'},\n { name: 'codeAt', call: 'eth_codeAt' },\n { name: 'transact', call: 'eth_transact' },\n { name: 'call', call: 'eth_call' },\n { name: 'block', call: blockCall },\n { name: 'transaction', call: transactionCall },\n { name: 'uncle', call: uncleCall },\n { name: 'compilers', call: 'eth_compilers' },\n { name: 'lll', call: 'eth_lll' },\n { name: 'solidity', call: 'eth_solidity' },\n { name: 'serpent', call: 'eth_serpent' },\n { name: 'logs', call: 'eth_logs' }\n ];\n return methods;\n};\n\n/// @returns an array of objects describing web3.eth api properties\nvar ethProperties = function () {\n return [\n { name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },\n { name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },\n { name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },\n { name: 'gasPrice', getter: 'eth_gasPrice' },\n { name: 'account', getter: 'eth_account' },\n { name: 'accounts', getter: 'eth_accounts' },\n { name: 'peerCount', getter: 'eth_peerCount' },\n { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },\n { name: 'number', getter: 'eth_number'}\n ];\n};\n\n/// @returns an array of objects describing web3.db api methods\nvar dbMethods = function () {\n return [\n { name: 'put', call: 'db_put' },\n { name: 'get', call: 'db_get' },\n { name: 'putString', call: 'db_putString' },\n { name: 'getString', call: 'db_getString' }\n ];\n};\n\n/// @returns an array of objects describing web3.shh api methods\nvar shhMethods = function () {\n return [\n { name: 'post', call: 'shh_post' },\n { name: 'newIdentity', call: 'shh_newIdentity' },\n { name: 'haveIdentity', call: 'shh_haveIdentity' },\n { name: 'newGroup', call: 'shh_newGroup' },\n { name: 'addToGroup', call: 'shh_addToGroup' }\n ];\n};\n\n/// @returns an array of objects describing web3.eth.watch api methods\nvar ethWatchMethods = function () {\n var newFilter = function (args) {\n return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';\n };\n\n return [\n { name: 'newFilter', call: newFilter },\n { name: 'uninstallFilter', call: 'eth_uninstallFilter' },\n { name: 'getMessages', call: 'eth_filterLogs' }\n ];\n};\n\n/// @returns an array of objects describing web3.shh.watch api methods\nvar shhWatchMethods = function () {\n return [\n { name: 'newFilter', call: 'shh_newFilter' },\n { name: 'uninstallFilter', call: 'shh_uninstallFilter' },\n { name: 'getMessage', call: 'shh_getMessages' }\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 obj[method.name] = function () {\n return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) {\n var call = typeof method.call === \"function\" ? method.call(args) : method.call;\n return {call: call, args: args};\n }).then(function (request) {\n return new Promise(function (resolve, reject) {\n web3.provider.send(request, function (err, result) {\n if (!err) {\n resolve(result);\n return;\n }\n reject(err);\n });\n });\n }).catch(function(err) {\n console.error(err);\n });\n };\n });\n};\n\n/// creates properties in a given object based on properties description on input\n/// setups api calls for these properties\nvar setupProperties = function (obj, properties) {\n properties.forEach(function (property) {\n var proto = {};\n proto.get = function () {\n return new Promise(function(resolve, reject) {\n web3.provider.send({call: property.getter}, function(err, result) {\n if (!err) {\n resolve(result);\n return;\n }\n reject(err);\n });\n });\n };\n if (property.setter) {\n proto.set = function (val) {\n return flattenPromise([val]).then(function (args) {\n return new Promise(function (resolve) {\n web3.provider.send({call: property.setter, args: args}, function (err, result) {\n if (!err) {\n resolve(result);\n return;\n }\n reject(err);\n });\n });\n }).catch(function (err) {\n console.error(err);\n });\n };\n }\n Object.defineProperty(obj, property.name, proto);\n });\n};\n\n// TODO: import from a dependency, don't duplicate.\nvar hexToDec = function (hex) {\n return parseInt(hex, 16).toString();\n};\n\nvar decToHex = function (dec) {\n return parseInt(dec).toString(16);\n};\n\n/// setups web3 object, and it's in-browser executed methods\nvar web3 = {\n _callbacks: {},\n _events: {},\n providers: {},\n\n toHex: 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 /// @returns ascii string representation of hex value prefixed with 0x\n 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 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 /// @returns hex representation (prefixed by 0x) of ascii string\n fromAscii: function(str, pad) {\n pad = pad === undefined ? 0 : pad;\n var hex = this.toHex(str);\n while(hex.length < pad*2)\n hex += \"00\";\n return \"0x\" + hex;\n },\n\n /// @returns decimal representaton of hex value prefixed by 0x\n toDecimal: function (val) {\n return hexToDec(val.substring(2));\n },\n\n /// @returns hex representation (prefixed by 0x) of decimal value\n fromDecimal: function (val) {\n return \"0x\" + decToHex(val);\n },\n\n /// used to transform value/string to eth string\n toEth: function(str) {\n var val = typeof str === \"string\" ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;\n var unit = 0;\n var units = [ 'wei', 'Kwei', 'Mwei', 'Gwei', 'szabo', 'finney', 'ether', 'grand', 'Mether', 'Gether', 'Tether', 'Pether', 'Eether', 'Zether', 'Yether', 'Nether', 'Dether', 'Vether', 'Uether' ];\n while (val > 3000 && unit < units.length - 1)\n {\n val /= 1000;\n unit++;\n }\n var s = val.toString().length < val.toFixed(2).length ? val.toString() : val.toFixed(2);\n var replaceFunction = function($0, $1, $2) {\n return $1 + ',' + $2;\n };\n\n while (true) {\n var o = s;\n s = s.replace(/(\\d)(\\d\\d\\d[\\.\\,])/, replaceFunction);\n if (o === s)\n break;\n }\n return s + ' ' + units[unit];\n },\n\n /// eth object prototype\n eth: {\n watch: function (params) {\n return new web3.filter(params, ethWatch);\n }\n },\n\n /// db object prototype\n db: {},\n\n /// shh object prototype\n shh: {\n watch: function (params) {\n return new web3.filter(params, shhWatch);\n }\n },\n\n /// used by filter to register callback with given id\n on: function(event, id, cb) {\n if(web3._events[event] === undefined) {\n web3._events[event] = {};\n }\n\n web3._events[event][id] = cb;\n return this;\n },\n\n /// used by filter to unregister callback with given id\n off: function(event, id) {\n if(web3._events[event] !== undefined) {\n delete web3._events[event][id];\n }\n\n return this;\n },\n\n /// used to trigger callback registered by filter\n trigger: function(event, id, data) {\n var callbacks = web3._events[event];\n if (!callbacks || !callbacks[id]) {\n return;\n }\n var cb = callbacks[id];\n cb(data);\n },\n\n /// @returns true if provider is installed\n haveProvider: function() {\n return !!web3.provider.provider;\n }\n};\n\n/// setups all api methods\nsetupMethods(web3, web3Methods());\nsetupMethods(web3.eth, ethMethods());\nsetupProperties(web3.eth, ethProperties());\nsetupMethods(web3.db, dbMethods());\nsetupMethods(web3.shh, shhMethods());\n\nvar ethWatch = {\n changed: 'eth_changed'\n};\n\nsetupMethods(ethWatch, ethWatchMethods());\n\nvar shhWatch = {\n changed: 'shh_changed'\n};\n\nsetupMethods(shhWatch, shhWatchMethods());\n\nweb3.setProvider = function(provider) {\n provider.onmessage = messageHandler;\n web3.provider.set(provider);\n web3.provider.sendQueued();\n};\n\n/// callled when there is new incoming message\nfunction messageHandler(data) {\n if(data._event !== undefined) {\n web3.trigger(data._event, data._id, data.data);\n return;\n }\n\n if(data._id) {\n var cb = web3._callbacks[data._id];\n if (cb) {\n cb.call(this, data.error, data.data);\n delete web3._callbacks[data._id];\n }\n }\n}\n\nmodule.exports = web3;\n\n", + "/*\n This file is part of ethereum.js.\n\n ethereum.js is free software: you can redistribute it and/or modify\n it under the terms of the GNU Lesser General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n\n ethereum.js is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU Lesser General Public License for more details.\n\n You should have received a copy of the GNU Lesser General Public License\n along with ethereum.js. If not, see .\n*/\n/** @file websocket.js\n * @authors:\n * Jeffrey Wilcke \n * Marek Kotewicz \n * Marian Oancea \n * @date 2014\n */\n\n// TODO: is these line is supposed to be here? \nif (\"build\" !== 'build') {/*\n var WebSocket = require('ws'); // jshint ignore:line\n*/}\n\n/**\n * WebSocketProvider object prototype is implementing 'provider protocol'\n * Should be used when we want to connect to ethereum backend over websockets\n * It's compatible with go client\n * The constructor allows to specify host uri\n */\nvar WebSocketProvider = function(host) {\n\n // onmessage handlers\n this.handlers = [];\n\n // queue will be filled with messages if send is invoked before the ws is ready\n this.queued = [];\n this.ready = false;\n\n this.ws = new WebSocket(host);\n\n var self = this;\n this.ws.onmessage = function(event) {\n for(var i = 0; i < self.handlers.length; i++) {\n self.handlers[i].call(self, JSON.parse(event.data), event);\n }\n };\n\n this.ws.onopen = function() {\n self.ready = true;\n\n for (var i = 0; i < self.queued.length; i++) {\n // Resend\n self.send(self.queued[i]);\n }\n };\n};\n\n/// Prototype object method\n/// Should be called when we want to send single api request to server\n/// Asynchronous, it's using websockets\n/// Response for the call will be received by ws.onmessage\n/// @param payload is inner message object\nWebSocketProvider.prototype.send = function(payload) {\n if (this.ready) {\n var data = JSON.stringify(payload);\n\n this.ws.send(data);\n } else {\n this.queued.push(payload);\n }\n};\n\n/// Prototype object method\n/// Should be called to add handlers\nWebSocketProvider.prototype.onMessage = function(handler) {\n this.handlers.push(handler);\n};\n\n/// Prototype object method\n/// Should be called to close websockets connection\nWebSocketProvider.prototype.unload = function() {\n this.ws.close();\n};\n\n/// Prototype object property\n/// Should be used to set message handlers for this provider\nObject.defineProperty(WebSocketProvider.prototype, \"onmessage\", {\n set: function(provider) { this.onMessage(provider); }\n});\n\nif (typeof(module) !== \"undefined\")\n module.exports = WebSocketProvider;\n", + "var web3 = require('./lib/web3');\nvar ProviderManager = require('./lib/providermanager');\nweb3.provider = new ProviderManager();\nweb3.filter = require('./lib/filter');\nweb3.providers.WebSocketProvider = require('./lib/websocket');\nweb3.providers.HttpRpcProvider = require('./lib/httprpc');\nweb3.providers.QtProvider = require('./lib/qt');\nweb3.providers.AutoProvider = require('./lib/autoprovider');\nweb3.eth.contract = require('./lib/contract');\n\nmodule.exports = web3;\n" ] } \ No newline at end of file diff --git a/libjsqrc/ethereumjs/dist/ethereum.min.js b/libjsqrc/ethereumjs/dist/ethereum.min.js index 58ef8847e..fba5e4db5 100644 --- a/libjsqrc/ethereumjs/dist/ethereum.min.js +++ b/libjsqrc/ethereumjs/dist/ethereum.min.js @@ -1 +1 @@ -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++)o+=r[i]/8;return o},c=function(){var t=function(t){return"number"==typeof t?t.toString(16):"string"==typeof t&&0===t.indexOf("0x")?t.substr(2):(+t).toString(16)},e=function(e,n){return function(r,o){var a=e;if(0!==r.indexOf(a))return!1;var s=n(r,a);return s>32?!1:(s=32,"string"===e?web3.fromAscii(o,s).substr(2):i(t(o),2*s))}},n=function(t,e,n){return function(r,o){return r!==t?!1:(e=32,i(n?n(o):o,2*e))}},r=function(t){return t?"01":"00"};return[e("uint",a),e("int",a),e("hash",a),e("string",s),e("real",u),e("ureal",u),n("address",20,t),n("bool",1,r)]},l=c(),h=function(t,e,n){var r="",i=o(t,e);if(-1!==i){for(var a=t[i],s=0;s32?-1:(o=32,2*o)}},e=function(t,e){return function(n){return e=32,t===n?2*e:-1}},r=function(t){return t.length<=8?+parseInt(t,16):n(t)},o=function(t){return"0x"+t},i=function(t){return"1"===t?!0:!1},c=function(t){return web3.toAscii(t)};return[{padding:t("uint",a),format:r},{padding:t("int",a),format:r},{padding:t("hash",a),format:o},{padding:t("string",s),format:c},{padding:t("real",u),format:r},{padding:t("ureal",u),format:r},{padding:e("address",20)},{padding:e("bool",1),format:i}]},p=f(),d=function(t,e,n){var r=o(t,e);if(-1!==r){n=n.slice(2);for(var i=[],a=t[r],s=0;sn;n+=2){var o=t.charCodeAt(n);if(0===o)break;e+=String.fromCharCode(parseInt(t.substr(n,2),16))}return e},fromAscii:function(t,e){e=void 0===e?0:e;for(var n=this.toHex(t);n.length<2*e;)n+="00";return"0x"+n},toDecimal:function(t){return p(t.substring(2))},fromDecimal:function(t){return"0x"+d(t)},toEth:function(t){for(var e="string"==typeof t?0===t.indexOf("0x")?parseInt(t.substr(2),16):parseInt(t):t,n=0,r=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];e>3e3&&nd;d++)h.push(o(n.slice(0,c))),n=n.slice(c);s.push(h)}else a("string")(u.outputs[t].type)?(p=p.slice(c),s.push(o(n.slice(0,c))),n=n.slice(c)):(s.push(o(n.slice(0,c))),n=n.slice(c))}),s}},E=function(e){var t={};return e.forEach(function(n){t[n.name]=function(){var t=Array.prototype.slice.call(arguments);return m(e,n.name,t)}}),t},F=function(e){var t={};return e.forEach(function(n){t[n.name]=function(t){return q(e,n.name,t)}}),t},M=function(e,t){var r=e[o(e,t)],i=t+"(",s=r.inputs.map(function(e){return e.type});return i+=s.join(","),i+=")",n.sha3(n.fromAscii(i))};t.exports={inputParser:E,outputParser:F,methodSignature:M}},{"./web3":8}],2:[function(e,t){var n=e("./web3"),r=function(e){if(!n.haveProvider()){if(this.sendQueue=[],this.onmessageQueue=[],navigator.qt)return void(this.provider=new n.providers.QtProvider);e=e||{};var t={httprpc:e.httprpc||"http://localhost:8080",websockets:e.websockets||"ws://localhost:40404/eth"},r=this,i=function(e){o.close(),e?r.provider=new n.providers.WebSocketProvider(t.websockets):(r.provider=new n.providers.HttpRpcProvider(t.httprpc),r.poll=r.provider.poll.bind(r.provider)),r.sendQueue.forEach(function(e){r.provider.send(e)}),r.onmessageQueue.forEach(function(e){r.provider.onmessage=e})},o=new WebSocket(t.websockets);o.onopen=function(){i(!0)},o.onerror=function(){i(!1)}}};r.prototype.send=function(e){return this.provider?void this.provider.send(e):void this.sendQueue.push(e)},Object.defineProperty(r.prototype,"onmessage",{set:function(e){return this.provider?void(this.provider.onmessage=e):void this.onmessageQueue.push(e)}}),t.exports=r},{"./web3":8}],3:[function(e,t){var n=e("./web3"),r=e("./abi"),i=4,o=function(e,t){var o=r.inputParser(t),s=r.outputParser(t),a={};return t.forEach(function(u){a[u.name]=function(){var a=Array.prototype.slice.call(arguments),f=o[u.name].apply(null,a),c=function(e){return s[u.name](e)};return{call:function(o){return o=o||{},o.to=e,r.methodSignature(t,u.name).then(function(e){return o.data=e.slice(0,2+2*i)+f,n.eth.call(o).then(c)})},transact:function(o){return o=o||{},o.to=e,r.methodSignature(t,u.name).then(function(e){return o.data=e.slice(0,2+2*i)+f,n.eth.transact(o).then(c)})}}}}),a};t.exports=o},{"./abi":1,"./web3":8}],4:[function(e,t){var n=e("./web3"),r=function(e,t){this.impl=t,this.callbacks=[];var r=this;this.promise=t.newFilter(e),this.promise.then(function(e){r.id=e,n.on(t.changed,e,r.trigger.bind(r)),n.provider.startPolling({call:t.changed,args:[e]},e)})};r.prototype.arrived=function(e){this.changed(e)},r.prototype.changed=function(e){var t=this;this.promise.then(function(){t.callbacks.push(e)})},r.prototype.trigger=function(e){for(var t=0;tn;n+=2){var i=parseInt(e.substr(n,2),16);if(0===i)break;t+=String.fromCharCode(i)}return t},fromAscii:function(e,t){t=void 0===t?0:t;for(var n=this.toHex(e);n.length<2*t;)n+="00";return"0x"+n},toDecimal:function(e){return h(e.substring(2))},fromDecimal:function(e){return"0x"+d(e)},toEth:function(e){for(var t="string"==typeof e?0===e.indexOf("0x")?parseInt(e.substr(2),16):parseInt(e):e,n=0,r=["wei","Kwei","Mwei","Gwei","szabo","finney","ether","grand","Mether","Gether","Tether","Pether","Eether","Zether","Yether","Nether","Dether","Vether","Uether"];t>3e3&&n + + + + + + + + + + + diff --git a/mix/qml/js/Debugger.js b/mix/qml/js/Debugger.js index 43b15f27e..9078befdb 100644 --- a/mix/qml/js/Debugger.js +++ b/mix/qml/js/Debugger.js @@ -7,7 +7,7 @@ var currentSelectedState = null; var jumpStartingPoint = null; function init() { - if (debugStates === undefined) + if (typeof(debugStates) === "undefined") return; statesSlider.maximumValue = debugStates.length - 1; @@ -24,6 +24,9 @@ function init() function moveSelection(incr) { + if (typeof(debugStates) === "undefined") + return; + if (currentSelectedState + incr >= 0) { if (currentSelectedState + incr < debugStates.length) @@ -34,6 +37,9 @@ function moveSelection(incr) function select(stateIndex) { + if (typeof(debugStates) === "undefined") + return; + var codeLine = codeStr(stateIndex); var state = debugStates[stateIndex]; highlightSelection(codeLine); @@ -53,6 +59,9 @@ function select(stateIndex) function codeStr(stateIndex) { + if (typeof(debugStates) === "undefined") + return; + var state = debugStates[stateIndex]; return bytesCodeMapping.getValue(state.curPC); } @@ -64,10 +73,13 @@ function highlightSelection(index) function completeCtxInformation(state) { + if (typeof(debugStates) === "undefined") + return; + currentStep.update(state.step); - mem.update(state.newMemSize + " " + qsTr("words")); - stepCost.update(state.gasCost); - gasSpent.update(debugStates[0].gas - state.gas); + mem.update(state.newMemSize.value() + " " + qsTr("words")); + stepCost.update(state.gasCost.value()); + gasSpent.update(debugStates[0].gas.subtract(state.gas).value()); stack.listModel = state.debugStack; storage.listModel = state.debugStorage; @@ -83,6 +95,9 @@ function displayReturnValue() function stepOutBack() { + if (typeof(debugStates) === "undefined") + return; + if (jumpStartingPoint != null) { select(jumpStartingPoint); @@ -99,6 +114,9 @@ function stepIntoBack() function stepOverBack() { + if (typeof(debugStates) === "undefined") + return; + var state = debugStates[currentSelectedState]; if (state.instruction === "JUMPDEST") { @@ -118,6 +136,9 @@ function stepOverBack() function stepOverForward() { + if (typeof(debugStates) === "undefined") + return; + var state = debugStates[currentSelectedState]; if (state.instruction === "JUMP") { @@ -137,6 +158,9 @@ function stepOverForward() function stepIntoForward() { + if (typeof(debugStates) === "undefined") + return; + var state = debugStates[currentSelectedState]; if (state.instruction === "JUMP") { diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index 836b75e13..0e889ae03 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -43,10 +43,14 @@ function closeProject() { function saveProject() { if (!isEmpty) { + var projectData = { files: [] }; + for (var i = 0; i < projectListModel.count; i++) + projectData.files.push(projectListModel.get(i).fileName) projectSaving(projectData); var json = JSON.stringify(projectData); var projectFile = projectPath + projectFileName; fileIo.writeFile(projectFile, json); + projectSaved(); } } @@ -55,11 +59,12 @@ function loadProject(path) { console.log("loading project at " + path); var projectFile = path + projectFileName; var json = fileIo.readFile(projectFile); - projectData = JSON.parse(json); + var projectData = JSON.parse(json); if (!projectData.title) { var parts = path.split("/"); projectData.title = parts[parts.length - 2]; } + projectTitle = projectData.title; projectPath = path; if (!projectData.files) projectData.files = []; @@ -68,32 +73,31 @@ function loadProject(path) { addFile(projectData.files[i]); } projectSettings.lastProjectPath = path; - projectLoaded(); + projectLoaded(projectData); } function addExistingFile() { addExistingFileDialog.open(); } -function addProjectFiles(files) { - for(var i = 0; i < files.length; i++) - addFile(files[i]); -} - function addFile(fileName) { var p = projectPath + fileName; - var extension = fileName.substring(fileName.length - 4, fileName.length); + var extension = fileName.substring(fileName.lastIndexOf("."), fileName.length); var isContract = extension === ".sol"; - var fileData = { + var isHtml = extension === ".html"; + var docData = { contract: false, path: p, + fileName: fileName, name: isContract ? "Contract" : fileName, documentId: fileName, - isText: isContract || extension === ".html" || extension === ".js", + isText: isContract || isHtml || extension === ".js", isContract: isContract, + isHtml: isHtml, }; - projectListModel.append(fileData); + projectListModel.append(docData); + return docData.documentId; } function findDocument(documentId) @@ -113,7 +117,6 @@ function doCloseProject() { console.log("closing project"); projectListModel.clear(); projectPath = ""; - projectData = null; projectClosed(); } @@ -143,14 +146,12 @@ function doCreateProject(title, path) { function doAddExistingFiles(files) { for(var i = 0; i < files.length; i++) { var sourcePath = files[i]; - console.log(sourcePath); var sourceFileName = sourcePath.substring(sourcePath.lastIndexOf("/") + 1, sourcePath.length); - console.log(sourceFileName); var destPath = projectPath + sourceFileName; - console.log(destPath); if (sourcePath !== destPath) fileIo.copyFile(sourcePath, destPath); - addFile(sourceFileName); + var id = addFile(sourceFileName); + documentAdded(id) } } @@ -168,12 +169,17 @@ function renameDocument(documentId, newName) { } } +function getDocument(documentId) { + var i = findDocument(documentId); + return projectListModel.get(i); +} + function removeDocument(documentId) { var i = findDocument(documentId); var document = projectListModel.get(i); if (!document.isContract) { projectListModel.remove(i); - documentUpdated(documentId); + documentRemoved(documentId); } } @@ -189,7 +195,8 @@ function createAndAddFile(name, extension, content) { var fileName = generateFileName(name, extension); var filePath = projectPath + fileName; fileIo.writeFile(filePath, content); - addFile(fileName); + var id = addFile(fileName); + documentAdded(id); } function generateFileName(name, extension) { diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 469a6d1f4..7970c4027 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -5,7 +5,6 @@ import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 import CodeEditorExtensionManager 1.0 -import org.ethereum.qml.ProjectModel 1.0 ApplicationWindow { id: mainApplication @@ -41,6 +40,7 @@ ApplicationWindow { Menu { title: qsTr("Windows") MenuItem { action: showHideRightPanel } + MenuItem { action: toggleWebPreview } } } @@ -89,74 +89,85 @@ ApplicationWindow { onTriggered: clientModel.resetState(); } + Action { + id: toggleWebPreview + text: "Show Web View" + shortcut: "F2" + checkable: true + checked: mainContent.webViewVisible + onTriggered: mainContent.toggleWebPreview(); + } + Action { id: showHideRightPanel - text: "Show/Hide right view" + text: "Show Right View" shortcut: "F7" + checkable: true + checked: mainContent.rightViewVisible onTriggered: mainContent.toggleRightView(); } Action { id: createProjectAction - text: qsTr("&New project") + text: qsTr("&New Project") shortcut: "Ctrl+N" enabled: true; - onTriggered: ProjectModel.createProject(); + onTriggered: projectModel.createProject(); } Action { id: openProjectAction - text: qsTr("&Open project") + text: qsTr("&Open Project") shortcut: "Ctrl+O" enabled: true; - onTriggered: ProjectModel.browseProject(); + onTriggered: projectModel.browseProject(); } Action { id: addNewJsFileAction - text: qsTr("New JavaScript file") + text: qsTr("New JavaScript File") shortcut: "Ctrl+Alt+J" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.newJsFile(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.newJsFile(); } Action { id: addNewHtmlFileAction - text: qsTr("New HTML file") + text: qsTr("New HTML File") shortcut: "Ctrl+Alt+H" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.newHtmlFile(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.newHtmlFile(); } Action { id: addNewContractAction - text: qsTr("New contract") + text: qsTr("New Contract") shortcut: "Ctrl+Alt+C" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.newContract(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.newContract(); } Action { id: addExistingFileAction - text: qsTr("Add existing file") + text: qsTr("Add Existing File") shortcut: "Ctrl+Alt+A" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.addExistingFile(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.addExistingFile(); } Action { id: saveAllFilesAction - text: qsTr("Save all") + text: qsTr("Save All") shortcut: "Ctrl+S" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.saveAll(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.saveAll(); } Action { id: closeProjectAction - text: qsTr("Close project") + text: qsTr("Close Project") shortcut: "Ctrl+W" - enabled: !ProjectModel.isEmpty - onTriggered: ProjectModel.closeProject(); + enabled: !projectModel.isEmpty + onTriggered: projectModel.closeProject(); } } diff --git a/mix/web.qrc b/mix/web.qrc new file mode 100644 index 000000000..a50863a2c --- /dev/null +++ b/mix/web.qrc @@ -0,0 +1,6 @@ + + + qml/WebPreview.qml + qml/html/WebContainer.html + + diff --git a/neth/main.cpp b/neth/main.cpp index 144ac1701..e49e47c16 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -305,7 +305,6 @@ int main(int argc, char** argv) unsigned short remotePort = 30303; string dbPath; unsigned mining = ~(unsigned)0; - (void)mining; NodeMode mode = NodeMode::Full; unsigned peers = 5; #if ETH_JSONRPC @@ -379,13 +378,14 @@ int main(int argc, char** argv) mining = ~(unsigned)0; else if (isFalse(m)) mining = 0; - else if (int i = stoi(m)) - mining = i; else - { - cerr << "Unknown -m/--mining option: " << m << endl; - return -1; - } + try { + mining = stoi(m); + } + catch (...) { + cerr << "Unknown -m/--mining option: " << m << endl; + return -1; + } } else if (arg == "-b" || arg == "--bootstrap") bootstrap = true; @@ -440,6 +440,8 @@ int main(int argc, char** argv) web3.connect(Host::pocHost()); if (remoteHost.size()) web3.connect(remoteHost, remotePort); + if (mining) + c->startMining(); #if ETH_JSONRPC shared_ptr jsonrpcServer; @@ -884,7 +886,7 @@ int main(int argc, char** argv) auto b = bc.block(h); for (auto const& i: RLP(b)[1]) { - Transaction t(i.data()); + Transaction t(i.data(), CheckSignature::Sender); auto s = t.receiveAddress() ? boost::format(" %1% %2%> %3%: %4% [%5%]") % toString(t.safeSender()) % diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 8c5192abe..3888f2314 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ static string const g_argAbiStr = "json-abi"; static string const g_argSolAbiStr = "sol-abi"; static string const g_argAsmStr = "asm"; static string const g_argAstStr = "ast"; +static string const g_argAstJson = "ast-json"; static string const g_argBinaryStr = "binary"; static string const g_argOpcodesStr = "opcodes"; static string const g_argNatspecDevStr = "natspec-dev"; @@ -75,9 +77,10 @@ static inline bool argToStdout(po::variables_map const& _args, string const& _na static bool needStdout(po::variables_map const& _args) { + return argToStdout(_args, g_argAbiStr) || argToStdout(_args, g_argSolAbiStr) || - argToStdout(_args, g_argNatspecUserStr) || + argToStdout(_args, g_argNatspecUserStr) || argToStdout(_args, g_argAstJson) || argToStdout(_args, g_argNatspecDevStr) || argToStdout(_args, g_argAsmStr) || argToStdout(_args, g_argOpcodesStr) || argToStdout(_args, g_argBinaryStr); } @@ -215,6 +218,8 @@ bool CommandLineInterface::parseArguments(int argc, char** argv) ("input-file", po::value>(), "input file") (g_argAstStr.c_str(), po::value(), "Request to output the AST of the contract. " OUTPUT_TYPE_STR) + (g_argAstJson.c_str(), po::value(), + "Request to output the AST of the contract in JSON format. " OUTPUT_TYPE_STR) (g_argAsmStr.c_str(), po::value(), "Request to output the EVM assembly of the contract. " OUTPUT_TYPE_STR) (g_argOpcodesStr.c_str(), po::value(), @@ -339,20 +344,44 @@ bool CommandLineInterface::processInput() return true; } -void CommandLineInterface::actOnInput() +void CommandLineInterface::handleAst(string const& _argStr) { + string title; + string suffix; + + if (_argStr == g_argAstStr) + { + title = "Syntax trees:"; + suffix = ".ast"; + } + else if (_argStr == g_argAstJson) + { + title = "JSON AST:"; + suffix = ".json"; + } + else + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal argStr for AST")); + // do we need AST output? - if (m_args.count(g_argAstStr)) + if (m_args.count(_argStr)) { - auto choice = m_args[g_argAstStr].as(); + auto choice = m_args[_argStr].as(); if (outputToStdout(choice)) { - cout << "Syntax trees:" << endl << endl; + cout << title << endl << endl; for (auto const& sourceCode: m_sourceCodes) { cout << endl << "======= " << sourceCode.first << " =======" << endl; - ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); - printer.print(cout); + if (_argStr == g_argAstStr) + { + ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); + printer.print(cout); + } + else + { + ASTJsonConverter converter(m_compiler.getAST(sourceCode.first)); + converter.print(cout); + } } } @@ -362,12 +391,27 @@ void CommandLineInterface::actOnInput() { boost::filesystem::path p(sourceCode.first); ofstream outFile(p.stem().string() + ".ast"); - ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); - printer.print(outFile); + if (_argStr == g_argAstStr) + { + ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); + printer.print(outFile); + } + else + { + ASTJsonConverter converter(m_compiler.getAST(sourceCode.first)); + converter.print(outFile); + } outFile.close(); } } } +} + +void CommandLineInterface::actOnInput() +{ + // do we need AST output? + handleAst(g_argAstStr); + handleAst(g_argAstJson); vector contracts = m_compiler.getContractNames(); for (string const& contract: contracts) diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 9dfee7199..2862773ba 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -53,6 +53,7 @@ public: void actOnInput(); private: + void handleAst(std::string const& _argStr); void handleBinary(std::string const& _contract); void handleOpcode(std::string const& _contract); void handleBytecode(std::string const& _contract); diff --git a/test/SolidityABIJSON.cpp b/test/SolidityABIJSON.cpp index d553f576a..892b71f15 100644 --- a/test/SolidityABIJSON.cpp +++ b/test/SolidityABIJSON.cpp @@ -41,13 +41,9 @@ public: { m_compilerStack.parse(_code); } - catch (const std::exception& e) + catch(boost::exception const& _e) { - std::string const* extra = boost::get_error_info(e); - std::string msg = std::string("Parsing contract failed with: ") + - e.what() + std::string("\n"); - if (extra) - msg += *extra; + auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e); BOOST_FAIL(msg); } std::string generatedInterfaceString = m_compilerStack.getMetadata("", DocumentationType::ABI_INTERFACE); diff --git a/test/SolidityCompiler.cpp b/test/SolidityCompiler.cpp index b4874e195..53daa9dfe 100644 --- a/test/SolidityCompiler.cpp +++ b/test/SolidityCompiler.cpp @@ -64,7 +64,7 @@ bytes compileContract(const string& _sourceCode) if (ContractDefinition* contract = dynamic_cast(node.get())) { Compiler compiler; - compiler.compileContract(*contract, {}, map{}); + compiler.compileContract(*contract, map{}); // debug //compiler.streamAssembly(cout); diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index b79e9c4b7..cf04edaad 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -772,6 +772,94 @@ BOOST_AUTO_TEST_CASE(struct_reference) BOOST_CHECK(callContractFunction("check()") == encodeArgs(true)); } +BOOST_AUTO_TEST_CASE(deleteStruct) +{ + char const* sourceCode = R"( + contract test { + struct topStruct { + nestedStruct nstr; + emptyStruct empty; + uint topValue; + mapping (uint => uint) topMapping; + } + uint toDelete; + topStruct str; + struct nestedStruct { + uint nestedValue; + mapping (uint => bool) nestedMapping; + } + struct emptyStruct{ + } + function test(){ + toDelete = 5; + str.topValue = 1; + str.topMapping[0] = 1; + str.topMapping[1] = 2; + + str.nstr.nestedValue = 2; + str.nstr.nestedMapping[0] = true; + str.nstr.nestedMapping[1] = false; + delete str; + delete toDelete; + } + function getToDelete() returns (uint res){ + res = toDelete; + } + function getTopValue() returns(uint topValue){ + topValue = str.topValue; + } + function getNestedValue() returns(uint nestedValue){ + nestedValue = str.nstr.nestedValue; + } + function getTopMapping(uint index) returns(uint ret) { + ret = str.topMapping[index]; + } + function getNestedMapping(uint index) returns(bool ret) { + return str.nstr.nestedMapping[index]; + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("getToDelete()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("getTopValue()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("getNestedValue()") == encodeArgs(0)); + // mapping values should be the same + BOOST_CHECK(callContractFunction("getTopMapping(uint256)", 0) == encodeArgs(1)); + BOOST_CHECK(callContractFunction("getTopMapping(uint256)", 1) == encodeArgs(2)); + BOOST_CHECK(callContractFunction("getNestedMapping(uint256)", 0) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("getNestedMapping(uint256)", 1) == encodeArgs(false)); +} + +BOOST_AUTO_TEST_CASE(deleteLocal) +{ + char const* sourceCode = R"( + contract test { + function delLocal() returns (uint res){ + uint v = 5; + delete v; + res = v; + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(0)); +} + +BOOST_AUTO_TEST_CASE(deleteLocals) +{ + char const* sourceCode = R"( + contract test { + function delLocal() returns (uint res1, uint res2){ + uint v = 5; + uint w = 6; + uint x = 7; + delete v; + res1 = w; + res2 = x; + } + })"; + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("delLocal()") == encodeArgs(6, 7)); +} + BOOST_AUTO_TEST_CASE(constructor) { char const* sourceCode = "contract test {\n" @@ -1243,6 +1331,7 @@ BOOST_AUTO_TEST_CASE(constructor_arguments) contract Helper { string3 name; bool flag; + function Helper(string3 x, bool f) { name = x; flag = f; @@ -1404,6 +1493,163 @@ BOOST_AUTO_TEST_CASE(value_for_constructor) BOOST_REQUIRE(callContractFunction("getBalances()") == encodeArgs(12, 10)); } +BOOST_AUTO_TEST_CASE(virtual_function_calls) +{ + char const* sourceCode = R"( + contract Base { + function f() returns (uint i) { return g(); } + function g() returns (uint i) { return 1; } + } + contract Derived is Base { + function g() returns (uint i) { return 2; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(2)); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(access_base_storage) +{ + char const* sourceCode = R"( + contract Base { + uint dataBase; + function getViaBase() returns (uint i) { return dataBase; } + } + contract Derived is Base { + uint dataDerived; + function setData(uint base, uint derived) returns (bool r) { + dataBase = base; + dataDerived = derived; + return true; + } + function getViaDerived() returns (uint base, uint derived) { + base = dataBase; + derived = dataDerived; + } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("setData(uint256,uint256)", 1, 2) == encodeArgs(true)); + BOOST_CHECK(callContractFunction("getViaBase()") == encodeArgs(1)); + BOOST_CHECK(callContractFunction("getViaDerived()") == encodeArgs(1, 2)); +} + +BOOST_AUTO_TEST_CASE(single_copy_with_multiple_inheritance) +{ + char const* sourceCode = R"( + contract Base { + uint data; + function setData(uint i) { data = i; } + function getViaBase() returns (uint i) { return data; } + } + contract A is Base { function setViaA(uint i) { setData(i); } } + contract B is Base { function getViaB() returns (uint i) { return getViaBase(); } } + contract Derived is A, B, Base { } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getViaB()") == encodeArgs(0)); + BOOST_CHECK(callContractFunction("setViaA(uint256)", 23) == encodeArgs()); + BOOST_CHECK(callContractFunction("getViaB()") == encodeArgs(23)); +} + +BOOST_AUTO_TEST_CASE(explicit_base_cass) +{ + char const* sourceCode = R"( + contract BaseBase { function g() returns (uint r) { return 1; } } + contract Base is BaseBase { function g() returns (uint r) { return 2; } } + contract Derived is Base { + function f() returns (uint r) { return BaseBase.g(); } + function g() returns (uint r) { return 3; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("g()") == encodeArgs(3)); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1)); +} + +BOOST_AUTO_TEST_CASE(base_constructor_arguments) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + } + contract Base is BaseBase(7) { + function Base() { + m_a *= m_a; + } + } + contract Derived is Base() { + function getA() returns (uint r) { return m_a; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(7 * 7)); +} + +BOOST_AUTO_TEST_CASE(function_usage_in_constructor_arguments) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + function g() returns (uint r) { return 2; } + } + contract Base is BaseBase(BaseBase.g()) { + } + contract Derived is Base() { + function getA() returns (uint r) { return m_a; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(virtual_function_usage_in_constructor_arguments) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + function overridden() returns (uint r) { return 1; } + function g() returns (uint r) { return overridden(); } + } + contract Base is BaseBase(BaseBase.g()) { + } + contract Derived is Base() { + function getA() returns (uint r) { return m_a; } + function overridden() returns (uint r) { return 2; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(2)); +} + +BOOST_AUTO_TEST_CASE(constructor_argument_overriding) +{ + char const* sourceCode = R"( + contract BaseBase { + uint m_a; + function BaseBase(uint a) { + m_a = a; + } + } + contract Base is BaseBase(2) { } + contract Derived is Base, BaseBase(3) { + function getA() returns (uint r) { return m_a; } + } + )"; + compileAndRun(sourceCode, 0, "Derived"); + BOOST_CHECK(callContractFunction("getA()") == encodeArgs(3)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityExpressionCompiler.cpp b/test/SolidityExpressionCompiler.cpp index 579af5bb9..d50dc253e 100644 --- a/test/SolidityExpressionCompiler.cpp +++ b/test/SolidityExpressionCompiler.cpp @@ -86,13 +86,19 @@ Declaration const& resolveDeclaration(vector const& _namespacedName, } bytes compileFirstExpression(const string& _sourceCode, vector> _functions = {}, - vector> _localVariables = {}) + vector> _localVariables = {}, vector> _globalDeclarations = {}) { Parser parser; ASTPointer sourceUnit; BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared(CharStream(_sourceCode)))); - NameAndTypeResolver resolver({}); + + vector declarations; + declarations.reserve(_globalDeclarations.size() + 1); + for (ASTPointer const& variable: _globalDeclarations) + declarations.push_back(variable.get()); + NameAndTypeResolver resolver(declarations); resolver.registerDeclarations(*sourceUnit); + for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { @@ -390,6 +396,21 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals) BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); } +BOOST_AUTO_TEST_CASE(blockhash) +{ + char const* sourceCode = "contract test {\n" + " function f() {\n" + " block.blockhash(3);\n" + " }\n" + "}\n"; + bytes code = compileFirstExpression(sourceCode, {}, {}, + {make_shared("block", make_shared(MagicType::Kind::BLOCK))}); + + bytes expectation({byte(eth::Instruction::PUSH1), 0x03, + byte(eth::Instruction::BLOCKHASH)}); + BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index e2b4f160d..6c8fd1b1c 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -357,7 +357,6 @@ BOOST_AUTO_TEST_CASE(function_canonical_signature_type_aliases) } } - BOOST_AUTO_TEST_CASE(hash_collision_in_interface) { char const* text = "contract test {\n" @@ -369,6 +368,128 @@ BOOST_AUTO_TEST_CASE(hash_collision_in_interface) BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); } +BOOST_AUTO_TEST_CASE(inheritance_basic) +{ + char const* text = R"( + contract base { uint baseMember; struct BaseType { uint element; } } + contract derived is base { + BaseType data; + function f() { baseMember = 7; } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(inheritance_diamond_basic) +{ + char const* text = R"( + contract root { function rootFunction() {} } + contract inter1 is root { function f() {} } + contract inter2 is root { function f() {} } + contract derived is inter1, inter2, root { + function g() { f(); rootFunction(); } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(cyclic_inheritance) +{ + char const* text = R"( + contract A is B { } + contract B is A { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(illegal_override_direct) +{ + char const* text = R"( + contract B { function f() {} } + contract C is B { function f(uint i) {} } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(illegal_override_indirect) +{ + char const* text = R"( + contract A { function f(uint a) {} } + contract B { function f() {} } + contract C is A, B { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(complex_inheritance) +{ + char const* text = R"( + contract A { function f() { uint8 x = C(0).g(); } } + contract B { function f() {} function g() returns (uint8 r) {} } + contract C is A, B { } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(constructor_visibility) +{ + // The constructor of a base class should not be visible in the derived class + char const* text = R"( + contract A { function A() { } } + contract B is A { function f() { A x = A(0); } } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(overriding_constructor) +{ + // It is fine to "override" constructor of a base class since it is invisible + char const* text = R"( + contract A { function A() { } } + contract B is A { function A() returns (uint8 r) {} } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} + +BOOST_AUTO_TEST_CASE(missing_base_constructor_arguments) +{ + char const* text = R"( + contract A { function A(uint a) { } } + contract B is A { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(base_constructor_arguments_override) +{ + char const* text = R"( + contract A { function A(uint a) { } } + contract B is A { } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + +BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion) +{ + char const* text = R"( + contract A { } + contract B is A { + function f() { A a = B(1); } + } + )"; + BOOST_CHECK_NO_THROW(parseTextAndResolveNames(text)); +} +BOOST_AUTO_TEST_CASE(implicit_base_to_derived_conversion) +{ + char const* text = R"( + contract A { } + contract B is A { + function f() { B b = A(1); } + } + )"; + BOOST_CHECK_THROW(parseTextAndResolveNames(text), TypeError); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/SolidityNatspecJSON.cpp b/test/SolidityNatspecJSON.cpp index d43aebc2b..743651d54 100644 --- a/test/SolidityNatspecJSON.cpp +++ b/test/SolidityNatspecJSON.cpp @@ -45,13 +45,9 @@ public: { m_compilerStack.parse(_code); } - catch (const std::exception& e) + catch(boost::exception const& _e) { - std::string const* extra = boost::get_error_info(e); - std::string msg = std::string("Parsing contract failed with: ") + - e.what() + std::string("\n"); - if (extra) - msg += *extra; + auto msg = std::string("Parsing contract failed with: ") + boost::diagnostic_information(_e); BOOST_FAIL(msg); } @@ -510,17 +506,35 @@ BOOST_AUTO_TEST_CASE(dev_title_at_function_error) BOOST_CHECK_THROW(checkNatspec(sourceCode, natspec, false), DocstringParsingError); } -// test for bug where having no tags in docstring would cause infinite loop -BOOST_AUTO_TEST_CASE(natspec_no_tags) +BOOST_AUTO_TEST_CASE(natspec_notice_without_tag) { char const* sourceCode = "contract test {\n" " /// I do something awesome\n" - " function mul(uint a, uint second) returns(uint d) { return a * 7 + second; }\n" + " function mul(uint a) returns(uint d) { return a * 7; }\n" "}\n"; - char const* natspec = "{\"methods\": {}}"; + char const* natspec = "{" + "\"methods\":{" + " \"mul(uint256)\":{ \"notice\": \"I do something awesome\"}" + "}}"; + + checkNatspec(sourceCode, natspec, true); +} - checkNatspec(sourceCode, natspec, false); +BOOST_AUTO_TEST_CASE(natspec_multiline_notice_without_tag) +{ + char const* sourceCode = "contract test {\n" + " /// I do something awesome\n" + " /// which requires two lines to explain\n" + " function mul(uint a) returns(uint d) { return a * 7; }\n" + "}\n"; + + char const* natspec = "{" + "\"methods\":{" + " \"mul(uint256)\":{ \"notice\": \"I do something awesome which requires two lines to explain\"}" + "}}"; + + checkNatspec(sourceCode, natspec, true); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/SolidityParser.cpp b/test/SolidityParser.cpp index 86f935c39..91e571306 100644 --- a/test/SolidityParser.cpp +++ b/test/SolidityParser.cpp @@ -495,6 +495,51 @@ BOOST_AUTO_TEST_CASE(multiple_contracts_and_imports) BOOST_CHECK_NO_THROW(parseText(text)); } +BOOST_AUTO_TEST_CASE(contract_inheritance) +{ + char const* text = "contract base {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n" + "contract derived is base {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + +BOOST_AUTO_TEST_CASE(contract_multiple_inheritance) +{ + char const* text = "contract base {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n" + "contract derived is base, nonExisting {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + +BOOST_AUTO_TEST_CASE(contract_multiple_inheritance_with_arguments) +{ + char const* text = "contract base {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n" + "contract derived is base(2), nonExisting(\"abc\", \"def\", base.fun()) {\n" + " function fun() {\n" + " uint64(2);\n" + " }\n" + "}\n"; + BOOST_CHECK_NO_THROW(parseText(text)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp index 355a5080d..45c56f6ae 100644 --- a/test/TestHelper.cpp +++ b/test/TestHelper.cpp @@ -115,7 +115,7 @@ void ImportTest::importState(json_spirit::mObject& _o, State& _state) if (code.size()) { _state.m_cache[address] = Account(toInt(o["balance"]), Account::ContractConception); - _state.m_cache[address].setCode(bytesConstRef(&code)); + _state.m_cache[address].setCode(code); } else _state.m_cache[address] = Account(toInt(o["balance"]), Account::NormalCreation); diff --git a/test/solidityExecutionFramework.h b/test/solidityExecutionFramework.h index 8d3c7e77c..271a594c4 100644 --- a/test/solidityExecutionFramework.h +++ b/test/solidityExecutionFramework.h @@ -46,7 +46,16 @@ public: bytes const& compileAndRun(std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "") { dev::solidity::CompilerStack compiler; - compiler.compile(_sourceCode, m_optimize); + try + { + compiler.compile(_sourceCode, m_optimize); + } + catch(boost::exception const& _e) + { + auto msg = std::string("Compiling contract failed with: ") + boost::diagnostic_information(_e); + BOOST_FAIL(msg); + } + bytes code = compiler.getBytecode(_contractName); sendMessage(code, true, _value); BOOST_REQUIRE(!m_output.empty()); @@ -97,6 +106,7 @@ public: static bytes encode(char const* _value) { return encode(std::string(_value)); } static bytes encode(byte _value) { return bytes(31, 0) + bytes{_value}; } static bytes encode(u256 const& _value) { return toBigEndian(_value); } + static bytes encode(h256 const& _value) { return _value.asBytes(); } static bytes encode(bytes const& _value, bool _padLeft = true) { bytes padding = bytes((32 - _value.size() % 32) % 32, 0);