diff --git a/.gitignore b/.gitignore index c60cf19e1..c18d5a01d 100644 --- a/.gitignore +++ b/.gitignore @@ -18,15 +18,23 @@ ipch *.sdf *.opensdf *.suo +*.vcxproj +*.vcxproj.filters +*.sln -#Xcode stuff +# VIM stuff +*.swp + +# Xcode stuff build_xc *.user *.user.* *~ +# build system build.*/ +extdep/install *.pyc diff --git a/CMakeLists.txt b/CMakeLists.txt index e623c7319..5763c9b85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,384 +1,187 @@ # cmake global +cmake_minimum_required(VERSION 2.8.12) +# let cmake autolink dependencies on windows +# it's specified globally, cause qt libraries requires that on windows and they are also found globally +cmake_policy(SET CMP0020 NEW) + project(ethereum) -cmake_minimum_required(VERSION 2.8.9) -set(CMAKE_AUTOMOC ON) -cmake_policy(SET CMP0015 NEW) -# user defined, defaults -# Normally, set(...CACHE...) creates cache variables, but does not modify them. +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -set(HEADLESS OFF CACHE BOOL "Do not compile GUI (AlethZero)") -set(LANGUAGES OFF CACHE BOOL "Limit build to Serpent/LLL tools") -set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)") -set(PARANOIA OFF CACHE BOOL "Additional run-time checks") -if (LANGUAGES) - add_definitions(-DETH_LANGUAGES) -endif () +###################################################################################################### -if (PARANOIA) - if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - add_definitions(-DETH_PARANOIA) - else () - message(FATAL_ERROR "Paranoia requires debug.") +# user defined, defaults +# Normally, set(...CACHE...) creates cache variables, but does not modify them. +function(createDefaultCacheConfig) + set(HEADLESS OFF CACHE BOOL "Do not compile GUI (AlethZero)") + set(VMTRACE OFF CACHE BOOL "VM tracing and run-time checks (useful for cross-implementation VM debugging)") + set(PARANOIA OFF CACHE BOOL "Additional run-time checks") + set(JSONRPC ON CACHE BOOL "Build with jsonprc. default on") +endfunction() + + +# propagates CMake configuration options to the compiler +function(configureProject) + if (PARANOIA) + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + add_definitions(-DETH_PARANOIA) + else () + message(FATAL_ERROR "Paranoia requires debug.") + endif () endif () -endif () -if (VMTRACE) - if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") - add_definitions(-DETH_VMTRACE) + if (VMTRACE) + if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + add_definitions(-DETH_VMTRACE) + else () + message(FATAL_ERROR "VM tracing requires debug.") + endif () + endif () +endfunction() + + + +function(createBuildInfo) + # Set build platform; to be written to BuildInfo.h + if (CMAKE_COMPILER_IS_MINGW) + set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/mingw") + elseif (CMAKE_COMPILER_IS_MSYS) + set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msys") + elseif (CMAKE_COMPILER_IS_GNUCXX) + set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/g++") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msvc") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/clang") else () - message(FATAL_ERROR "VM tracing requires debug.") + set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/unknown") endif () -endif () - -message("LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}") -# Default TARGET_PLATFORM to "linux". -set(TARGET_PLATFORM CACHE STRING "linux") -if ("x${TARGET_PLATFORM}" STREQUAL "x") - set(TARGET_PLATFORM "linux") -endif () + #cmake build type may be not specified when using msvc + if (${CMAKE_BUILD_TYPE}) + set(_cmake_build_type ${CMAKE_BUILD_TYPE}) + else() + set(_cmake_build_type "undefined") + endif() -if ("${TARGET_PLATFORM}" STREQUAL "linux") - set(CMAKE_THREAD_LIBS_INIT pthread) -endif () + # Generate header file containing useful build information + add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${_cmake_build_type} ${ETH_BUILD_PLATFORM}) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) -# Set default build type to Release w/debug info -# if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) -# set(CMAKE_BUILD_TYPE RelWithDebInfo) -# endif() - -# Initialize CXXFLAGS -set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB") -set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") -set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") -set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG -DETH_RELEASE") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") - -# Windows -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_SYSTEM_NAME Windows) - - set(CMAKE_CXX_LIBRARY_ARCHITECTURE x86_64-w64-mingw32) - set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc) - set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++) - set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) - set(CMAKE_AR x86_64-w64-mingw32-ar) - set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib) - - set(CMAKE_EXECUTABLE_SUFFIX .exe) - - set(CMAKE_FIND_ROOT_PATH - /usr/x86_64-w64-mingw32 - ) - - include_directories(/usr/x86_64-w64-mingw32/include/cryptopp) - - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) - - set(CMAKE_INSTALL_PREFIX /usr/x86_64-w64-mingw32) - set(ETH_BUILD_PLATFORM "windows") - set(ETH_STATIC 1) -else () - set(ETH_BUILD_PLATFORM ${CMAKE_SYSTEM_NAME}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - set(ETH_SHARED 1) -endif() + set(CMAKE_INCLUDE_CURRENT_DIR ON) + set(SRC_LIST BuildInfo.h) +endfunction() -# Set build platform; to be written to BuildInfo.h -if (CMAKE_COMPILER_IS_MINGW) - set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/mingw") -elseif (CMAKE_COMPILER_IS_MSYS) - set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msys") -elseif (CMAKE_COMPILER_IS_GNUCXX) - set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/g++") -elseif (CMAKE_COMPILER_IS_MSVC) - set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/msvc") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/clang") -else () - set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/unknown") -endif () -message("CXXFLAGS: ${CMAKE_CXX_FLAGS}") -#add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}") -#add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}") -# C++11 check and activation -if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - execute_process( - COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) - if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) - message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") - endif () -elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") -else () - message(FATAL_ERROR "Your C++ compiler does not support C++11.") -endif () +###################################################################################################### -if("${TARGET_PLATFORM}" STREQUAL "w64") -# set(MINIUPNPC_LS /usr/x86_64-w64-mingw32/lib/libminiupnpc.a) - set(LEVELDB_LS leveldb) - set(CRYPTOPP_LS cryptopp) - set(CRYPTOPP_ID /usr/x86_64-w64-mingw32/include/cryptopp) -else() - # Look for available Crypto++ version and if it is >= 5.6.2 - find_path(ID cryptlib.h - ../cryptopp/src - ../../cryptopp/src - /usr/include/cryptopp - /usr/include/crypto++ - /usr/local/include/cryptopp - /usr/local/include/crypto++ - /opt/local/include/cryptopp - /opt/local/include/crypto++ - ) - find_library(LS NAMES cryptoppeth cryptopp - ../cryptopp/src/../target/build/release - ../../cryptopp/src/../target/build/release - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - ) - - if (ID AND LS) - message(STATUS "Found Crypto++: ${ID}, ${LS}") - set(_CRYPTOPP_VERSION_HEADER ${ID}/config.h) - if(EXISTS ${_CRYPTOPP_VERSION_HEADER}) - file(STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION REGEX "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") - string(REGEX REPLACE "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION ${_CRYPTOPP_VERSION}) - if(${_CRYPTOPP_VERSION} LESS 562) - message(FATAL_ERROR "Crypto++ version found is smaller than 5.6.2.") - else() - set(CRYPTOPP_ID ${ID} CACHE FILEPATH "") - set(CRYPTOPP_LS ${LS} CACHE FILEPATH "") - message(STATUS "Crypto++ found and version greater or equal to 5.6.2") - endif() - endif() - else() - message(STATUS "Crypto++ Not Found: ${CRYPTOPP_ID}, ${CRYPTOPP_LS}") - endif() - find_path( LEVELDB_ID leveldb/db.h - /usr/include - /usr/local/include - ) - if ( LEVELDB_ID STREQUAL "LEVELDB_ID-NOTFOUND" ) - message(FATAL_ERROR "Failed to find the LevelDB headers") - else () - message(STATUS "Found LevelDB Headers") - - # Check for accessory dev libraries leveldb and miniupnpc - find_library( LEVELDB_LS NAMES leveldb - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( LEVELDB_LS STREQUAL "LEVELDB_LS-NOTFOUND" ) - message(FATAL_ERROR "Failed to find the LevelDB Library!") - else () - message(STATUS "Found LevelDB Library: ${LEVELDB_LS}") - add_definitions(-DETH_LEVELDB) - endif () - endif () +set(CMAKE_AUTOMOC ON) +cmake_policy(SET CMP0015 NEW) - find_path( PYTHON_ID pyconfig.h - ${PYTHON_INCLUDE_DIR} - /usr/include/python2.7 - /usr/local/include/python2.7 - ) - if ( PYTHON_ID STREQUAL "PYTHON_ID-NOTFOUND" ) - message(STATUS "Failed to find the Python-2.7 headers") - else () - message(STATUS "Found Python-2.7 Headers: ${PYTHON_ID}") - - # Check for accessory dev libraries leveldb and miniupnpc - find_library( PYTHON_LS NAMES python2.7 - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( PYTHON_LS STREQUAL "PYTHON_LS-NOTFOUND" ) - message(STATUS "Failed to find the Python-2.7 Library!") - set(PYTHON_ID) - set(PYTHON_LS) - else () - message(STATUS "Found Python-2.7 Library: ${PYTHON_LS}") - add_definitions(-DETH_PYTHON) - endif () - endif () - find_path( MINIUPNPC_ID miniupnpc/miniwget.h - /usr/include - /usr/local/include - ) - if ( MINIUPNPC_ID ) - message(STATUS "Found miniupnpc headers") - - find_library( MINIUPNPC_LS NAMES miniupnpc - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( MINIUPNPC_LS ) - message(STATUS "Found miniupnpc library: ${MINIUPNPC_LS}") - add_definitions(-DETH_MINIUPNPC) - else () - message(STATUS "Failed to find the miniupnpc library!") - endif () - else () - message(STATUS "Failed to find the miniupnpc headers!") - endif () +createDefaultCacheConfig() +configureProject() +message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}") - find_path( JSONRPC_ID jsonrpc/rpc.h - /usr/include - /usr/local/include - ) - if ( JSONRPC_ID ) - message(STATUS "Found jsonrpc headers") - find_library( JSONRPC_LS NAMES jsonrpc - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( JSONRPC_LS ) - message(STATUS "Found jsonrpc library: ${JSONRPC_LS}") - add_definitions(-DETH_JSONRPC) - else () - message(STATUS "Failed to find the jsonrpc library!") - endif () - else () - message(STATUS "Failed to find the jsonrpc headers!") - endif () - find_path( READLINE_ID readline/readline.h - /usr/include - /usr/local/include - ) - if ( READLINE_ID ) - message(STATUS "Found readline headers") - find_library( READLINE_LS NAMES readline - PATHS - /usr/lib - /usr/local/lib - /opt/local/lib - /usr/lib/*/ - ) - if ( READLINE_LS ) - message(STATUS "Found readline library: ${READLINE_LS}") - add_definitions(-DETH_READLINE) - else () - message(STATUS "Failed to find the readline library!") - endif () - else () - message(STATUS "Failed to find the readline headers!") - endif () +# Default TARGET_PLATFORM to "linux". +set(TARGET_PLATFORM CACHE STRING "linux") +if ("x${TARGET_PLATFORM}" STREQUAL "x") + set(TARGET_PLATFORM "linux") +endif () - if (LANGUAGES) - find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time) - else() - find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system regex) - endif() +if ("${TARGET_PLATFORM}" STREQUAL "linux") + set(CMAKE_THREAD_LIBS_INIT pthread) +endif () - set(QTQML 1) -endif() +include(EthCompilerSettings) +message("-- CXXFLAGS: ${CMAKE_CXX_FLAGS}") -if(CRYPTOPP_ID) - include_directories(${CRYPTOPP_ID}) -endif() -if(PYTHON_ID) - include_directories(${PYTHON_ID}) -endif() -if(MINIUPNPC_ID) - include_directories(${MINIUPNPC_ID}) -endif() -if(LEVELDB_ID) - include_directories(${LEVELDB_ID}) -endif() -if(READLINE_ID) - include_directories(${READLINE_ID}) -endif() -if(JSONRPC_ID) - include_directories(${JSONRPC_ID}) -endif() -# Generate header file containing useful build information -add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BUILD_TYPE} ${ETH_BUILD_PLATFORM}) -include_directories(${CMAKE_CURRENT_BINARY_DIR}) +# this must be an include, as a function it would messs up with variable scope! +include(EthDependencies) +include(EthExecutableHelper) -if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - link_directories(/usr/local/lib) - include_directories(/usr/local/include) -endif() +createBuildInfo() add_subdirectory(libdevcore) -add_subdirectory(libevmface) +add_subdirectory(libevmcore) add_subdirectory(liblll) add_subdirectory(libserpent) -if(NOT APPLE) -if(PYTHON_LS) -add_subdirectory(libpyserpent) -endif() -endif() +add_subdirectory(libsolidity) add_subdirectory(lllc) +add_subdirectory(solc) add_subdirectory(sc) -if (NOT LANGUAGES) - add_subdirectory(secp256k1) - add_subdirectory(libp2p) - add_subdirectory(libdevcrypto) - add_subdirectory(libwhisper) - - add_subdirectory(libethcore) - add_subdirectory(libevm) - add_subdirectory(libethereum) -# add_subdirectory(libethereumx) # TODO remove - - add_subdirectory(libwebthree) - add_subdirectory(test) - add_subdirectory(eth) - if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") - add_subdirectory(exp) - endif () - if(NOT ("${TARGET_PLATFORM}" STREQUAL "w64")) - add_subdirectory(neth) - endif () - if(QTQML) - add_definitions(-DETH_QTQML) - endif() - if(NOT HEADLESS) - if ("${TARGET_PLATFORM}" STREQUAL "w64") - cmake_policy(SET CMP0020 NEW) - endif () - - add_subdirectory(libqethereum) - add_subdirectory(alethzero) - add_subdirectory(third) - if(QTQML) - #add_subdirectory(iethxi) - #add_subdirectory(walleth) // resurect once we want to submit ourselves to QML. - endif() - endif() +if (JSONRPC) + add_subdirectory(libweb3jsonrpc) endif() -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(SRC_LIST BuildInfo.h) +add_subdirectory(secp256k1) +add_subdirectory(libp2p) +add_subdirectory(libdevcrypto) +add_subdirectory(libwhisper) + +add_subdirectory(libethcore) +add_subdirectory(libevm) +add_subdirectory(libethereum) + +add_subdirectory(libwebthree) +add_subdirectory(test) +add_subdirectory(eth) +if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") + add_subdirectory(exp) +endif () + +# TODO check msvc +if(NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")) + add_subdirectory(neth) +endif () + +if (NOT HEADLESS) + + add_subdirectory(libjsqrc) + add_subdirectory(libqethereum) + add_subdirectory(alethzero) + add_subdirectory(third) + add_subdirectory(mix) + +endif() enable_testing() add_test(NAME alltests WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth) #unset(TARGET_PLATFORM CACHE) +if (WIN32) + # packaging stuff + include(InstallRequiredSystemLibraries) + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ethereum") + set(CPACK_PACKAGE_VENDOR "ethereum.org") + set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") + set(CPACK_PACKAGE_VERSION "0.7") + set(CPACK_GENERATOR "NSIS") + # seems to be not working + # set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.bmp") + + # our stuff + set(CPACK_COMPONENT_ALETHZERO_GROUP "Applications") + set(CPACK_COMPONENT_THIRD_GROUP "Applications") + set(CPACK_COMPONENT_MIX_GROUP "Applications") + set(CPACK_COMPONENTS_ALL alethzero third mix) + + # nsis specific stuff + set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ethereum") + set(CPACK_NSIS_HELP_LINK "https://github.com/ethereum/cpp-ethereum") + set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/ethereum/cpp-ethereum") + set(CPACK_NSIS_CONTACT "ethereum.org") + set(CPACK_NSIS_MODIFY_PATH ON) + set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.ico") + set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.ico") + + include(CPack) +endif (WIN32) diff --git a/CodingStandards.txt b/CodingStandards.txt index 79403af2f..672a20958 100644 --- a/CodingStandards.txt +++ b/CodingStandards.txt @@ -1,7 +1,7 @@ 0. Formatting a. Use tabs for indentation! -- 1 tab is 4 spaces wide. +- tab stops are every 4 characters. - One indentation level -> exactly one byte (i.e. a tab character) in the source file. b. Line widths: - Don't worry about having lines of code > 80-char wide. @@ -11,8 +11,9 @@ d. Never place condition bodies on same line as condition. e. Space between first paren and keyword, but *not* following first paren or preceeding final paren. f. No spaces when fewer than intra-expression three parens together; when three or more, space according to clarity. g. No spaces for subscripting. -h. Space all other operators. -i. Braces, when used, always have their own lines and are at same indentation level as "parent" scope. +h. No space before ':' but one after it, except in the ternary operator: one on both sides. +i. Space all other operators. +j. Braces, when used, always have their own lines and are at same indentation level as "parent" scope. (WRONG) if( a==b[ i ] ) { printf ("Hello\n"); } @@ -71,8 +72,8 @@ All other entities' first alpha is lower case. 4. Variable prefixes: a. Leading underscore "_" to parameter names (both normal and template). -- Exception: "o_parameterName" when it is used exclusively for output. See 7(f). -- Exception: "io_parameterName" when it is used for both input and output. See 7(f). +- Exception: "o_parameterName" when it is used exclusively for output. See 6(f). +- Exception: "io_parameterName" when it is used for both input and output. See 6(f). b. Leading "c_" to const variables (unless part of an external API). c. Leading "g_" to global (non-const) variables. d. Leading "s_" to static (non-const, non-global) variables. @@ -147,8 +148,17 @@ e. A dictionary and thesaurus are your friends. - Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments. +10. Type-definitions -10. Commenting +a. Prefer using to typedef. e.g. using ints = std::vector; rather than typedef std::vector ints; +b. Generally avoid shortening a standard form that already includes all important information: +- e.g. stick to shared_ptr rather than shortening to ptr. +c. Where there are exceptions to this (due to excessive use and clear meaning), note the change prominently and use it consistently. +- e.g. using Guard = boost::lock_guard; ///< Guard is used throughout the codebase since it's clear in meaning and used commonly. +d. In general expressions should be roughly as important/semantically meaningful as the space they occupy. + + +11. Commenting a. Comments should be doxygen-compilable, using @notation rather than \notation. diff --git a/alethzero/EthereumMacOSXBundleInfo.plist.in b/EthereumMacOSXBundleInfo.plist.in similarity index 100% rename from alethzero/EthereumMacOSXBundleInfo.plist.in rename to EthereumMacOSXBundleInfo.plist.in diff --git a/README.md b/README.md index 7529fed50..8b5ff903d 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,13 @@ By Gav Wood, 2014. -Based on a design by Vitalik Buterin. +[![Build ++Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20master%20branch/builds/-1) master [![Build ++Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20branch/builds/-1) develop -Contributors, builders and testers include Eric Lombrozo (cross-compilation), Tim Hughes (MSVC compilation & Dagger testing), Alex Leverington (Clang & Mac building), Marko Simovic (CI) and several others. +[![Stories in Ready](https://badge.waffle.io/ethereum/cpp-ethereum.png?label=ready&title=Ready)](http://waffle.io/ethereum/cpp-ethereum) + +Ethereum is based on a design in an original whitepaper by Vitalik Buterin. This implementation is based on the formal specification of a refinement of that idea detailed in the 'yellow paper' by Gavin Wood. Contributors, builders and testers include Alex Leverington (Clang & Mac building, client multiplexing), Tim Hughes (MSVC compilation & Dagger testing), Caktux (ongoing CI), Christoph Jentzsch (tests), Christian Reissweiner (Solidity), Marek Kotewicz (external JS & JSON-RPC), Eric Lombrozo (MinGW32 cross-compilation), Marko Simovic (original CI), and several others. ### Building @@ -29,6 +33,8 @@ All development goes in develop branch - please don't submit pull requests to ma Please read [CodingStandards.txt](CodingStandards.txt) thoroughly before making alterations to the code base. Please do *NOT* use an editor that automatically reformats whitespace away from astylerc or the formatting guidelines as described in [CodingStandards.txt](CodingStandards.txt). -When altering eth/spec.json, mirror the changes to eth/eth.js. This should simply be cutting and pasting the relevant part from spec.json into eth.js. Don't alter the spec part from eth.js independently. +libweb3jsonrpc/abstractwebthreestubserver.h is autogenerated from the jsonrpcstub executable that comes with the libjsonrpc library (json-rpc-cpp project). It shouldn't be maually altered. -eth/abstractethstubserver.h is autogenerated from the jsonrpcstub executable that comes with the libjsonrpc library (json-rpc-cpp project). It shouldn't be maually altered. +```bash +jsonrpcstub spec.json --cpp-server=AbstractWebThreeStubServer +``` diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index c5d1aa0be..8c8a37a42 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -1,100 +1,53 @@ +cmake_policy(SET CMP0015 NEW) +# let cmake autolink dependencies on windows +cmake_policy(SET CMP0020 NEW) +# this policy was introduced in cmake 3.0 +# remove if, once 3.0 will be used on unix +if (${CMAKE_MAJOR_VERSION} GREATER 2) + cmake_policy(SET CMP0043 OLD) +endif() + set(CMAKE_INCLUDE_CURRENT_DIR ON) aux_source_directory(. SRC_LIST) -include_directories(..) -if (APPLE) - # Add homebrew path for qt5 - set(CMAKE_PREFIX_PATH /usr/local/opt/qt5) - include_directories(/usr/local/opt/qt5/include /usr/local/include) -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(SRC_LIST ${SRC_LIST} ../windows/qt_plugin_import.cpp) - include_directories(/usr/x86_64-w64-mingw32/include /usr/x86_64-w64-mingw32/include/QtCore /usr/x86_64-w64-mingw32/include/QtGui /usr/x86_64-w64-mingw32/include/QtQuick /usr/x86_64-w64-mingw32/include/QtQml /usr/x86_64-w64-mingw32/include/QtNetwork /usr/x86_64-w64-mingw32/include/QtWidgets /usr/x86_64-w64-mingw32/include/QtWebKit /usr/x86_64-w64-mingw32/include/QtWebKitWidgets) -elseif (UNIX) - set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake") -endif () - -find_package(Qt5Core REQUIRED) -find_package(Qt5Gui REQUIRED) -find_package(Qt5Quick REQUIRED) -find_package(Qt5Qml REQUIRED) -find_package(Qt5Network REQUIRED) -find_package(Qt5Widgets REQUIRED) -find_package(Qt5WebKit REQUIRED) -find_package(Qt5WebKitWidgets REQUIRED) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) +include_directories(..) qt5_wrap_ui(ui_Main.h Main.ui) -# Set name of binary and add_executable() -if (APPLE) - set(EXECUTEABLE AlethZero) - set(BIN_INSTALL_DIR ".") - set(DOC_INSTALL_DIR ".") - - set(PROJECT_VERSION "${ETH_VERSION}") - set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") - set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") - set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") - set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") - set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTEABLE}) - set(MACOSX_BUNDLE_ICON_FILE alethzero) - include(BundleUtilities) - - add_executable(${EXECUTEABLE} MACOSX_BUNDLE alethzero.icns Main.ui ${SRC_LIST}) - set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") - SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) - SET_SOURCE_FILES_PROPERTIES(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources") - -else () - set(EXECUTEABLE alethzero) - add_executable(${EXECUTEABLE} Main.ui ${SRC_LIST}) -endif () - -qt5_use_modules(${EXECUTEABLE} Core)# Gui Widgets Network WebKit WebKitWidgets) -target_link_libraries(${EXECUTEABLE} webthree qethereum ethereum evm ethcore devcrypto secp256k1 gmp ${CRYPTOPP_LS} serpent lll evmface devcore) +file(GLOB HEADERS "*.h") if (APPLE) - # First have qt5 install plugins and frameworks - add_custom_command(TARGET ${EXECUTEABLE} POST_BUILD - COMMAND /usr/local/opt/qt5/bin/macdeployqt ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTEABLE}.app - WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - - # This tool and next will inspect linked libraries in order to determine which dependencies are required - if (${CMAKE_CFG_INTDIR} STREQUAL ".") - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTEABLE}.app") - else () - set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTEABLE}.app") - endif () - install(CODE " - include(BundleUtilities) - set(BU_CHMOD_BUNDLE_ITEMS 1) - fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") - " COMPONENT RUNTIME ) - # Cleanup duplicate libs from macdeployqt - install(CODE " - file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") - if (LINGER_RM) - file(REMOVE \${LINGER_RM}) - endif () - ") -elseif ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") - target_link_libraries(${EXECUTEABLE} gcc) - target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) - target_link_libraries(${EXECUTEABLE} boost_system-mt-s) - target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTEABLE} crypt32) - target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) + set(EXECUTABLE AlethZero) else () - target_link_libraries(${EXECUTEABLE} boost_system) - target_link_libraries(${EXECUTEABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT}) - install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin ) + set(EXECUTABLE alethzero) endif () + +# eth_add_executable is defined in cmake/EthExecutableHelper.cmake +eth_add_executable(${EXECUTABLE} + ICON alethzero + UI_RESOURCES alethzero.icns Main.ui + WIN_RESOURCES alethzero.rc +) + +add_dependencies(${EXECUTABLE} BuildInfo.h) + +target_link_libraries(${EXECUTABLE} Qt5::Core) +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} qethereum) +target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} evm) +target_link_libraries(${EXECUTABLE} ethcore) +target_link_libraries(${EXECUTABLE} devcrypto) +target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} serpent) +target_link_libraries(${EXECUTABLE} lll) +target_link_libraries(${EXECUTABLE} solidity) +target_link_libraries(${EXECUTABLE} evmcore) +target_link_libraries(${EXECUTABLE} devcore) +target_link_libraries(${EXECUTABLE} web3jsonrpc) +target_link_libraries(${EXECUTABLE} jsqrc) + +# eth_install_executable is defined in cmake/EthExecutableHelper.cmake +eth_install_executable(${EXECUTABLE}) diff --git a/alethzero/DownloadView.cpp b/alethzero/DownloadView.cpp index 657727a6a..88a595566 100644 --- a/alethzero/DownloadView.cpp +++ b/alethzero/DownloadView.cpp @@ -45,13 +45,13 @@ void DownloadView::paintEvent(QPaintEvent*) double ratio = (double)rect().width() / rect().height(); if (ratio < 1) ratio = 1 / ratio; - double n = min(rect().width(), rect().height()) / ceil(sqrt(m_man->chain().size() / ratio)); + double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chain().size() / ratio))); // QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n)); QSizeF area(n, n); QPointF pos(0, 0); - auto const& bg = m_man->blocksGot(); + auto bg = m_man->blocksGot(); for (unsigned i = bg.all().first, ei = bg.all().second; i < ei; ++i) { @@ -63,7 +63,7 @@ void DownloadView::paintEvent(QPaintEvent*) unsigned h = 0; m_man->foreachSub([&](DownloadSub const& sub) { - if (sub.asked().contains(i)) + if (sub.askedContains(i)) s = h; h++; }); diff --git a/alethzero/Main.ui b/alethzero/Main.ui index dbc4bb144..1fdf7de19 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -6,8 +6,8 @@ 0 0 - 1711 - 1138 + 1617 + 1371 @@ -116,7 +116,7 @@ 0 0 - 1711 + 1617 25 @@ -130,6 +130,8 @@ &Network + + @@ -141,15 +143,12 @@ T&ools - + - - - @@ -162,7 +161,32 @@ Deb&ug - + + + + + + + + + + + + + + + &View + + + + + + + + + D&ebugger + + &Dump Trace @@ -171,8 +195,7 @@ - - + @@ -180,20 +203,19 @@ - - - - - - - - - - + + + + &Whisper + + + + + @@ -507,8 +529,7 @@ false - - + @@ -1466,6 +1487,276 @@ font-size: 14pt + + + QDockWidget::DockWidgetFeatureMask + + + Nodes + + + 2 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + + + + + + + QDockWidget::DockWidgetFeatureMask + + + Whisper + + + 1 + + + + + + + ms + + + 1 + + + 1000 + + + 50 + + + + + + + + 0 + 0 + + + + Topic + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + data + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + 0 + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + 0 + + + + + + + Post + + + + + + + + 0 + 0 + + + + TTL + + + destination + + + + + + + + 0 + 0 + + + + From + + + destination + + + + + + + + 0 + 0 + + + + To + + + destination + + + + + + + false + + + + + + + true + + + + + + + + 0 + 0 + + + + Data + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + data + + + + + + + seconds + + + 5 + + + 259200 + + + + + + + + 0 + 0 + + + + Work to Prove + + + destination + + + + + + + + + QDockWidget::DockWidgetFeatureMask + + + Active Whispers + + + 2 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QFrame::NoFrame + + + + + + &Quit @@ -1521,7 +1812,7 @@ font-size: 14pt true - &Preview + &Preview Pending Transactions @@ -1740,6 +2031,24 @@ font-size: 14pt Enable Local Addresses + + + false + + + Claim Ether Presale &Wallet... + + + + + Go! + + + + + New Identity + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index b4bbb8ca7..671322332 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -25,30 +25,39 @@ #include #include #include +#include #include #include #include +#include #include #include #include -#include +#include #include #include +#include +#include +#include #include #include #include #include +#include #include #include +#include #include "DownloadView.h" #include "MiningView.h" #include "BuildInfo.h" #include "MainWin.h" +#include "OurWebThreeStubServer.h" #include "ui_Main.h" using namespace std; using namespace dev; using namespace dev::p2p; using namespace dev::eth; +namespace js = json_spirit; static void initUnits(QComboBox* _b) { @@ -56,7 +65,7 @@ static void initUnits(QComboBox* _b) _b->addItem(QString::fromStdString(units()[n].second), n); } -static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr) +QString Main::fromRaw(dev::h256 _n, unsigned* _inc) { if (_n) { @@ -81,6 +90,21 @@ static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr) return QString(); } +static std::vector keysAsVector(QList const& keys) +{ + auto list = keys.toStdList(); + return {begin(list), end(list)}; +} + +static QString contentsOfQResource(std::string const& res) +{ + QFile file(QString::fromStdString(res)); + if (!file.open(QFile::ReadOnly)) + BOOST_THROW_EXCEPTION(FileError()); + QTextStream in(&file); + return in.readAll(); +} + Address c_config = Address("661005d2720d855f1d9976f88bb10c1a3398c77f"); Main::Main(QWidget *parent) : @@ -104,10 +128,11 @@ Main::Main(QWidget *parent) : #endif m_servers.append(QString::fromStdString(Host::pocHost() + ":30303")); - cerr << "State root: " << BlockChain::genesis().stateRoot << endl; - cerr << "Block Hash: " << sha3(BlockChain::createGenesisBlock()) << endl; - cerr << "Block RLP: " << RLP(BlockChain::createGenesisBlock()) << endl; - cerr << "Block Hex: " << toHex(BlockChain::createGenesisBlock()) << endl; + cerr << "State root: " << BlockChain::genesis().stateRoot << endl; + auto block = BlockChain::createGenesisBlock(); + cerr << "Block Hash: " << BlockChain::genesis().hash << endl; + cerr << "Block RLP: " << RLP(block) << endl; + cerr << "Block Hex: " << toHex(block) << endl; cerr << "Network protocol version: " << dev::eth::c_protocolVersion << endl; cerr << "Client database version: " << dev::eth::c_databaseVersion << endl; @@ -124,36 +149,43 @@ Main::Main(QWidget *parent) : statusBar()->addPermanentWidget(ui->peerCount); statusBar()->addPermanentWidget(ui->mineStatus); statusBar()->addPermanentWidget(ui->blockCount); - + connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"})); + m_qwebConnector.reset(new QWebThreeConnector()); + m_server.reset(new OurWebThreeStubServer(*m_qwebConnector, *web3(), keysAsVector(m_myKeys))); + connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); + m_server->setIdentities(keysAsVector(owned())); + m_server->StartListening(); + connect(ui->webView, &QWebView::loadStarted, [this]() { // NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it. - m_ethereum = new QEthereum(this, ethereum(), owned()); + m_qweb = new QWebThree(this); + auto qweb = m_qweb; + m_qwebConnector->setQWeb(qweb); + QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); QWebFrame* f = ui->webView->page()->mainFrame(); f->disconnect(SIGNAL(javaScriptWindowObjectCleared())); - auto qeth = m_ethereum; - connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, this)); + connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qweb)); + connect(m_qweb, SIGNAL(onNewId(QString)), this, SLOT(addNewId(QString))); }); - + connect(ui->webView, &QWebView::loadFinished, [=]() { - m_ethereum->poll(); + m_qweb->poll(); }); - + connect(ui->webView, &QWebView::titleChanged, [=]() { ui->tabWidget->setTabText(0, ui->webView->title()); }); - - readSettings(); + readSettings(); installWatches(); - startTimer(100); { @@ -170,12 +202,35 @@ Main::~Main() { // Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor) // *after* the client is dead. - m_ethereum->clientDieing(); - + m_qweb->clientDieing(); g_logPost = simpleDebugOut; writeSettings(); } +void Main::on_newIdentity_triggered() +{ + KeyPair kp = KeyPair::create(); + m_myIdentities.append(kp); + m_server->setIdentities(keysAsVector(owned())); + refreshWhisper(); +} + +void Main::refreshWhisper() +{ + ui->shhFrom->clear(); + for (auto i: m_server->ids()) + ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref()))); +} + +void Main::addNewId(QString _ids) +{ + Secret _id = jsToSecret(_ids.toStdString()); + KeyPair kp(_id); + m_myIdentities.push_back(kp); + m_server->setIdentities(keysAsVector(owned())); + refreshWhisper(); +} + dev::p2p::NetworkPreferences Main::netPrefs() const { return NetworkPreferences(ui->port->value(), ui->forceAddress->text().toStdString(), ui->upnp->isChecked(), ui->localNetworking->isChecked()); @@ -186,7 +241,7 @@ void Main::onKeysChanged() installBalancesWatch(); } -unsigned Main::installWatch(dev::eth::MessageFilter const& _tf, std::function const& _f) +unsigned Main::installWatch(dev::eth::LogFilter const& _tf, std::function const& _f) { auto ret = ethereum()->installWatch(_tf); m_handlers[ret] = _f; @@ -200,42 +255,45 @@ unsigned Main::installWatch(dev::h256 _tf, std::function const& _f) return ret; } +void Main::uninstallWatch(unsigned _w) +{ + ethereum()->uninstallWatch(_w); + m_handlers.erase(_w); +} + void Main::installWatches() { - installWatch(dev::eth::MessageFilter().altered(c_config, 0), [=](){ installNameRegWatch(); }); - installWatch(dev::eth::MessageFilter().altered(c_config, 1), [=](){ installCurrenciesWatch(); }); + installWatch(dev::eth::LogFilter().address(c_config), [=]() { installNameRegWatch(); }); + installWatch(dev::eth::LogFilter().address(c_config), [=]() { installCurrenciesWatch(); }); installWatch(dev::eth::PendingChangedFilter, [=](){ onNewPending(); }); installWatch(dev::eth::ChainChangedFilter, [=](){ onNewBlock(); }); } void Main::installNameRegWatch() { - ethereum()->uninstallWatch(m_nameRegFilter); - m_nameRegFilter = installWatch(dev::eth::MessageFilter().altered((u160)ethereum()->stateAt(c_config, 0)), [=](){ onNameRegChange(); }); + uninstallWatch(m_nameRegFilter); + m_nameRegFilter = installWatch(dev::eth::LogFilter().address((u160)ethereum()->stateAt(c_config, 0)), [=](){ onNameRegChange(); }); } void Main::installCurrenciesWatch() { - ethereum()->uninstallWatch(m_currenciesFilter); - m_currenciesFilter = installWatch(dev::eth::MessageFilter().altered((u160)ethereum()->stateAt(c_config, 1)), [=](){ onCurrenciesChange(); }); + uninstallWatch(m_currenciesFilter); + m_currenciesFilter = installWatch(dev::eth::LogFilter().address((u160)ethereum()->stateAt(c_config, 1)), [=](){ onCurrenciesChange(); }); } void Main::installBalancesWatch() { - dev::eth::MessageFilter tf; + dev::eth::LogFilter tf; vector
altCoins; Address coinsAddr = right160(ethereum()->stateAt(c_config, 1)); for (unsigned i = 0; i < ethereum()->stateAt(coinsAddr, 0); ++i) altCoins.push_back(right160(ethereum()->stateAt(coinsAddr, i + 1))); for (auto i: m_myKeys) - { - tf.altered(i.address()); for (auto c: altCoins) - tf.altered(c, (u160)i.address()); - } + tf.address(c).topic(h256(i.address(), h256::AlignRight)); - ethereum()->uninstallWatch(m_balancesFilter); + uninstallWatch(m_balancesFilter); m_balancesFilter = installWatch(tf, [=](){ onBalancesChange(); }); } @@ -292,8 +350,16 @@ void Main::on_enableOptimizer_triggered() on_data_textChanged(); } +QString Main::contents(QString _s) +{ + return QString::fromStdString(dev::asString(dev::contents(_s.toStdString()))); +} + void Main::load(QString _s) { + QString contents = QString::fromStdString(dev::asString(dev::contents(_s.toStdString()))); + ui->webView->page()->currentFrame()->evaluateJavaScript(contents); + /* QFile fin(_s); if (!fin.open(QFile::ReadOnly)) return; @@ -314,11 +380,9 @@ void Main::load(QString _s) //eval(line); line.clear(); } - } + }*/ } -// env.load("/home/gav/eth/init.eth") - void Main::on_loadJS_triggered() { QString f = QFileDialog::getOpenFileName(this, "Load Javascript", QString(), "Javascript (*.js);;All files (*)"); @@ -373,6 +437,17 @@ void Main::eval(QString const& _js) ui->jsConsole->setHtml(s); } +static Public stringToPublic(QString const& _a) +{ + string sn = _a.toStdString(); + if (_a.size() == sizeof(Public) * 2) + return Public(fromHex(_a.toStdString())); + else if (_a.size() == sizeof(Public) * 2 + 2 && _a.startsWith("0x")) + return Public(fromHex(_a.mid(2).toStdString())); + else + return Public(); +} + QString Main::pretty(dev::Address _a) const { h256 n; @@ -456,7 +531,7 @@ QString Main::lookup(QString const& _a) const void Main::on_about_triggered() { - QMessageBox::about(this, "About AlethZero PoC-" + QString(dev::Version).section('.', 1, 1), QString("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) "\n" DEV_QUOTED(ETH_COMMIT_HASH) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nThanks to the various contributors including: Alex Leverington, Tim Hughes, caktux, Eric Lombrozo, Marko Simovic."); + QMessageBox::about(this, "About AlethZero PoC-" + QString(dev::Version).section('.', 1, 1), QString("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) "\n" DEV_QUOTED(ETH_COMMIT_HASH) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBerlin ÐΞV team, 2014.\nOriginally by Gav Wood. Based on a design by Vitalik Buterin.\n\nThanks to the various contributors including: Tim Hughes, caktux, Eric Lombrozo, Marko Simovic."); } void Main::on_paranoia_triggered() @@ -467,15 +542,28 @@ void Main::on_paranoia_triggered() void Main::writeSettings() { QSettings s("ethereum", "alethzero"); - QByteArray b; - b.resize(sizeof(Secret) * m_myKeys.size()); - auto p = b.data(); - for (auto i: m_myKeys) { - memcpy(p, &(i.secret()), sizeof(Secret)); - p += sizeof(Secret); + QByteArray b; + b.resize(sizeof(Secret) * m_myKeys.size()); + auto p = b.data(); + for (auto i: m_myKeys) + { + memcpy(p, &(i.secret()), sizeof(Secret)); + p += sizeof(Secret); + } + s.setValue("address", b); + } + { + QByteArray b; + b.resize(sizeof(Secret) * m_myIdentities.size()); + auto p = b.data(); + for (auto i: m_myIdentities) + { + memcpy(p, &(i.secret()), sizeof(Secret)); + p += sizeof(Secret); + } + s.setValue("identities", b); } - s.setValue("address", b); s.setValue("upnp", ui->upnp->isChecked()); s.setValue("forceAddress", ui->forceAddress->text()); @@ -493,7 +581,7 @@ void Main::writeSettings() s.setValue("privateChain", m_privateChain); s.setValue("verbosity", ui->verbosity->value()); - bytes d = m_webThree->savePeers(); + bytes d = m_webThree->saveNodes(); if (d.size()) m_peers = QByteArray((char*)d.data(), (int)d.size()); s.setValue("peers", m_peers); @@ -511,21 +599,40 @@ void Main::readSettings(bool _skipGeometry) restoreGeometry(s.value("geometry").toByteArray()); restoreState(s.value("windowState").toByteArray()); - m_myKeys.clear(); - QByteArray b = s.value("address").toByteArray(); - if (b.isEmpty()) - m_myKeys.append(KeyPair::create()); - else { - h256 k; - for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) + m_myKeys.clear(); + QByteArray b = s.value("address").toByteArray(); + if (b.isEmpty()) + m_myKeys.append(KeyPair::create()); + else + { + h256 k; + for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) + { + memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret)); + if (!count(m_myKeys.begin(), m_myKeys.end(), KeyPair(k))) + m_myKeys.append(KeyPair(k)); + } + } + ethereum()->setAddress(m_myKeys.back().address()); + m_server->setAccounts(keysAsVector(m_myKeys)); + } + + { + m_myIdentities.clear(); + QByteArray b = s.value("identities").toByteArray(); + if (!b.isEmpty()) { - memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret)); - if (!count(m_myKeys.begin(), m_myKeys.end(), KeyPair(k))) - m_myKeys.append(KeyPair(k)); + h256 k; + for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i) + { + memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret)); + if (!count(m_myIdentities.begin(), m_myIdentities.end(), KeyPair(k))) + m_myIdentities.append(KeyPair(k)); + } } } - ethereum()->setAddress(m_myKeys.back().address()); + m_peers = s.value("peers").toByteArray(); ui->upnp->setChecked(s.value("upnp", true).toBool()); ui->forceAddress->setText(s.value("forceAddress", "").toString()); @@ -539,6 +646,8 @@ void Main::readSettings(bool _skipGeometry) m_enableOptimizer = s.value("enableOptimizer", true).toBool(); ui->enableOptimizer->setChecked(m_enableOptimizer); ui->clientName->setText(s.value("clientName", "").toString()); + if (ui->clientName->text().isEmpty()) + ui->clientName->setText(QInputDialog::getText(this, "Enter identity", "Enter a name that will identify you on the peer network")); ui->idealPeers->setValue(s.value("idealPeers", ui->idealPeers->value()).toInt()); ui->port->setValue(s.value("port", ui->port->value()).toInt()); ui->nameReg->setText(s.value("nameReg", "").toString()); @@ -560,8 +669,7 @@ void Main::on_importKey_triggered() if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) { m_myKeys.append(k); - m_keysChanged = true; - update(); + keysChanged(); } else QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account."); @@ -570,6 +678,57 @@ void Main::on_importKey_triggered() QMessageBox::warning(this, "Invalid Entry", "Could not import the secret key; invalid key entered. Make sure it is 64 hex characters (0-9 or A-F)."); } +void Main::on_importKeyFile_triggered() +{ + QString s = QFileDialog::getOpenFileName(this, "Import Account", QDir::homePath(), "JSON Files (*.json);;All Files (*)"); + try + { + js::mValue val; + json_spirit::read_string(asString(dev::contents(s.toStdString())), val); + auto obj = val.get_obj(); + if (obj["encseed"].type() == js::str_type) + { + auto encseed = fromHex(obj["encseed"].get_str()); + KeyPair k; + for (bool gotit = false; !gotit;) + { + gotit = true; + k = KeyPair::fromEncryptedSeed(&encseed, QInputDialog::getText(this, "Enter Password", "Enter the wallet's passphrase", QLineEdit::Password).toStdString()); + if (obj["ethaddr"].type() == js::str_type) + { + Address a(obj["ethaddr"].get_str()); + Address b = k.address(); + if (a != b) + { + if (QMessageBox::warning(this, "Password Wrong", "Could not import the secret key: the password you gave appears to be wrong.", QMessageBox::Retry, QMessageBox::Cancel) == QMessageBox::Cancel) + return; + else + gotit = false; + } + } + } + + if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end()) + { + m_myKeys.append(k); + keysChanged(); + } + else + QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account."); + } + else + BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("encseed type is not js::str_type") ); + + } + catch (...) + { + cerr << "Unhandled exception!" << endl << + boost::current_exception_diagnostic_information(); + + QMessageBox::warning(this, "Key File Invalid", "Could not find secret key definition. This is probably not an Ethereum key file."); + } +} + void Main::on_exportKey_triggered() { if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) @@ -690,8 +849,36 @@ void Main::refreshNetwork() ui->peerCount->setText(QString::fromStdString(toString(ps.size())) + " peer(s)"); ui->peers->clear(); - for (PeerInfo const& i: ps) - ui->peers->addItem(QString("%3 ms - %1:%2 - %4 %5").arg(i.host.c_str()).arg(i.port).arg(chrono::duration_cast(i.lastPing).count()).arg(i.clientVersion.c_str()).arg(QString::fromStdString(toString(i.caps)))); + ui->nodes->clear(); + + if (web3()->haveNetwork()) + { + map clients; + for (PeerInfo const& i: ps) + ui->peers->addItem(QString("[%8 %7] %3 ms - %1:%2 - %4 %5 %6") + .arg(QString::fromStdString(i.host)) + .arg(i.port) + .arg(chrono::duration_cast(i.lastPing).count()) + .arg(clients[i.id] = QString::fromStdString(i.clientVersion)) + .arg(QString::fromStdString(toString(i.caps))) + .arg(QString::fromStdString(toString(i.notes))) + .arg(i.socket) + .arg(QString::fromStdString(i.id.abridged()))); + + auto ns = web3()->nodes(); + for (p2p::Node const& i: ns) + if (!i.dead) + ui->nodes->insertItem(clients.count(i.id) ? 0 : ui->nodes->count(), QString("[%1 %3] %2 - ( =%5s | /%4s%6 ) - *%7 $%8") + .arg(QString::fromStdString(i.id.abridged())) + .arg(QString::fromStdString(toString(i.address))) + .arg(i.id == web3()->id() ? "self" : clients.count(i.id) ? clients[i.id] : i.secondsSinceLastAttempted() == -1 ? "session-fail" : i.secondsSinceLastAttempted() >= (int)i.fallbackSeconds() ? "retrying..." : "retry-" + QString::number(i.fallbackSeconds() - i.secondsSinceLastAttempted()) + "s") + .arg(i.secondsSinceLastAttempted()) + .arg(i.secondsSinceLastConnected()) + .arg(i.isOffline() ? " | " + QString::fromStdString(reasonOf(i.lastDisconnect)) + " | " + QString::number(i.failedAttempts) + "x" : "") + .arg(i.rating) + .arg((int)i.idOrigin) + ); + } } void Main::refreshAll() @@ -710,18 +897,18 @@ void Main::refreshPending() ui->transactionQueue->clear(); for (Transaction const& t: ethereum()->pending()) { - QString s = t.receiveAddress ? + QString s = t.receiveAddress() ? QString("%2 %5> %3: %1 [%4]") - .arg(formatBalance(t.value).c_str()) + .arg(formatBalance(t.value()).c_str()) .arg(render(t.safeSender())) - .arg(render(t.receiveAddress)) - .arg((unsigned)t.nonce) - .arg(ethereum()->codeAt(t.receiveAddress).size() ? '*' : '-') : + .arg(render(t.receiveAddress())) + .arg((unsigned)t.nonce()) + .arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') : QString("%2 +> %3: %1 [%4]") - .arg(formatBalance(t.value).c_str()) + .arg(formatBalance(t.value()).c_str()) .arg(render(t.safeSender())) - .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce))))) - .arg((unsigned)t.nonce); + .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))) + .arg((unsigned)t.nonce()); ui->transactionQueue->addItem(s); } } @@ -766,7 +953,7 @@ void Main::refreshBlockCount() cwatch << "refreshBlockCount()"; auto d = ethereum()->blockChain().details(); auto diff = BlockInfo(ethereum()->blockChain().block()).difficulty; - ui->blockCount->setText(QString("%6 #%1 @%3 T%2 N%4 D%5").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)).arg(dev::eth::c_protocolVersion).arg(dev::eth::c_databaseVersion).arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet")); + ui->blockCount->setText(QString("%6 #%1 @%3 T%2 PV%4 D%5").arg(d.number).arg(toLog2(d.totalDifficulty)).arg(toLog2(diff)).arg(dev::eth::c_protocolVersion).arg(dev::eth::c_databaseVersion).arg(m_privateChain.size() ? "[" + m_privateChain + "] " : "testnet")); } static bool blockMatch(string const& _f, dev::eth::BlockDetails const& _b, h256 _h, BlockChain const& _bc) @@ -788,7 +975,7 @@ static bool blockMatch(string const& _f, dev::eth::BlockDetails const& _b, h256 static bool transactionMatch(string const& _f, Transaction const& _t) { - string info = toHex(_t.receiveAddress.ref()) + " " + toHex(_t.sha3(true).ref()) + " " + toHex(_t.sha3(false).ref()) + " " + toHex(_t.sender().ref()); + string info = toHex(_t.receiveAddress().ref()) + " " + toHex(_t.sha3().ref()) + " " + toHex(_t.sha3(eth::WithoutSignature).ref()) + " " + toHex(_t.sender().ref()); if (info.find(_f) != string::npos) return true; return false; @@ -809,7 +996,7 @@ void Main::refreshBlockChain() string filter = ui->blockChainFilter->text().toLower().toStdString(); auto const& bc = ethereum()->blockChain(); unsigned i = (ui->showAll->isChecked() || !filter.empty()) ? (unsigned)-1 : 10; - for (auto h = bc.currentHash(); h != bc.genesisHash() && bc.details(h) && i; h = bc.details(h).parent, --i) + for (auto h = bc.currentHash(); bc.details(h) && i; h = bc.details(h).parent, --i) { auto d = bc.details(h); auto bm = blockMatch(filter, d, h, bc); @@ -825,21 +1012,21 @@ void Main::refreshBlockChain() auto b = bc.block(h); for (auto const& i: RLP(b)[1]) { - Transaction t(i[0].data()); + Transaction t(i.data()); if (bm || transactionMatch(filter, t)) { - QString s = t.receiveAddress ? + QString s = t.receiveAddress() ? QString(" %2 %5> %3: %1 [%4]") - .arg(formatBalance(t.value).c_str()) + .arg(formatBalance(t.value()).c_str()) .arg(render(t.safeSender())) - .arg(render(t.receiveAddress)) - .arg((unsigned)t.nonce) - .arg(ethereum()->codeAt(t.receiveAddress).size() ? '*' : '-') : + .arg(render(t.receiveAddress())) + .arg((unsigned)t.nonce()) + .arg(ethereum()->codeAt(t.receiveAddress()).size() ? '*' : '-') : QString(" %2 +> %3: %1 [%4]") - .arg(formatBalance(t.value).c_str()) + .arg(formatBalance(t.value()).c_str()) .arg(render(t.safeSender())) - .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce))))) - .arg((unsigned)t.nonce); + .arg(render(right160(sha3(rlpList(t.safeSender(), t.nonce()))))) + .arg((unsigned)t.nonce()); QListWidgetItem* txItem = new QListWidgetItem(s, ui->blocks); auto hba = QByteArray((char const*)h.data(), h.size); txItem->setData(Qt::UserRole, hba); @@ -849,6 +1036,8 @@ void Main::refreshBlockChain() } n++; } + if (h == bc.genesisHash()) + break; } if (!ui->blocks->currentItem()) @@ -878,12 +1067,12 @@ void Main::timerEvent(QTimerEvent*) // 7/18, Alex: aggregating timers, prelude to better threading? // Runs much faster on slower dual-core processors static int interval = 100; - + // refresh mining every 200ms if (interval / 100 % 2 == 0) refreshMining(); - if (interval / 100 % 2 == 0 && m_webThree->ethereum()->isSyncing()) + if ((interval / 100 % 2 == 0 && m_webThree->ethereum()->isSyncing()) || interval == 1000) ui->downloadView->update(); if (m_logChanged) @@ -900,12 +1089,13 @@ void Main::timerEvent(QTimerEvent*) { interval = 0; refreshNetwork(); + refreshWhispers(); } else interval += 100; - - if (m_ethereum) - m_ethereum->poll(); + + if (m_qweb) + m_qweb->poll(); for (auto const& i: m_handlers) if (ethereum()->checkWatch(i.first)) @@ -983,26 +1173,26 @@ void Main::on_transactionQueue_currentItemChanged() { Transaction tx(ethereum()->pending()[i]); auto ss = tx.safeSender(); - h256 th = sha3(rlpList(ss, tx.nonce)); + h256 th = sha3(rlpList(ss, tx.nonce())); s << "

" << th << "

"; s << "From: " << pretty(ss).toStdString() << " " << ss; if (tx.isCreation()) s << "
Creates: " << pretty(right160(th)).toStdString() << " " << right160(th); else - s << "
To: " << pretty(tx.receiveAddress).toStdString() << " " << tx.receiveAddress; - s << "
Value: " << formatBalance(tx.value) << ""; - s << "   #" << tx.nonce << ""; - s << "
Gas price: " << formatBalance(tx.gasPrice) << ""; - s << "
Gas: " << tx.gas << ""; + s << "
To: " << pretty(tx.receiveAddress()).toStdString() << " " << tx.receiveAddress(); + s << "
Value: " << formatBalance(tx.value()) << ""; + s << "   #" << tx.nonce() << ""; + s << "
Gas price: " << formatBalance(tx.gasPrice()) << ""; + s << "
Gas: " << tx.gas() << ""; if (tx.isCreation()) { - if (tx.data.size()) - s << "

Code

" << disassemble(tx.data); + if (tx.data().size()) + s << "

Code

" << disassemble(tx.data()); } else { - if (tx.data.size()) - s << dev::memDump(tx.data, 16, true); + if (tx.data().size()) + s << dev::memDump(tx.data(), 16, true); } s << "
"; @@ -1028,8 +1218,9 @@ void Main::ourAccountsRowsMoved() myKeys.push_back(i); } m_myKeys = myKeys; - if (m_ethereum) - m_ethereum->setAccounts(myKeys); + + if (m_server.get()) + m_server->setAccounts(keysAsVector(m_myKeys)); } void Main::on_inject_triggered() @@ -1068,48 +1259,73 @@ void Main::on_blocks_currentItemChanged() s << "
D/TD: 2^" << log2((double)info.difficulty) << "/2^" << log2((double)details.totalDifficulty) << ""; s << "   Children: " << details.children.size() << ""; s << "
Gas used/limit: " << info.gasUsed << "/" << info.gasLimit << ""; - s << "   Minimum gas price: " << formatBalance(info.minGasPrice) << ""; s << "
Coinbase: " << pretty(info.coinbaseAddress).toHtmlEscaped().toStdString() << " " << info.coinbaseAddress; s << "
Nonce: " << info.nonce << ""; + s << "
Hash w/o nonce: " << info.headerHash(WithoutNonce) << ""; + s << "
Difficulty: " << info.difficulty << ""; + if (info.number) + s << "
Proof-of-Work: " << ProofOfWork::eval(info.headerHash(WithoutNonce), info.nonce) << " <= " << (h256)u256((bigint(1) << 256) / info.difficulty) << ""; + else + s << "
Proof-of-Work: Phil has nothing to prove"; s << "
Parent: " << info.parentHash << ""; - s << "
Bloom: " << details.bloom << ""; +// s << "
Bloom: " << details.bloom << ""; + s << "
Log Bloom: " << info.logBloom << ""; s << "
Transactions: " << block[1].itemCount() << " @" << info.transactionsRoot << ""; + s << "
Receipts: @" << info.receiptsRoot << ":"; s << "
Uncles: " << block[2].itemCount() << " @" << info.sha3Uncles << ""; - s << "
Pre: " << BlockInfo(ethereum()->blockChain().block(info.parentHash)).stateRoot << ""; + for (auto u: block[2]) + { + BlockInfo uncle = BlockInfo::fromHeader(u.data()); + s << "
 Hash: " << uncle.hash << ""; + s << "
 Parent: " << uncle.parentHash << ""; + s << "
 Number: " << uncle.number << ""; + } + if (info.parentHash) + s << "
Pre: " << BlockInfo(ethereum()->blockChain().block(info.parentHash)).stateRoot << ""; + else + s << "
Pre: Nothing is before Phil"; for (auto const& i: block[1]) - s << "
" << sha3(i[0].data()).abridged() << ": " << i[1].toHash() << " [" << i[2].toInt() << " used]"; + 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()) << "
"; } else { unsigned txi = item->data(Qt::UserRole + 1).toInt(); - Transaction tx(block[1][txi][0].data()); + Transaction tx(block[1][txi].data()); auto ss = tx.safeSender(); - h256 th = sha3(rlpList(ss, tx.nonce)); + h256 th = sha3(rlpList(ss, tx.nonce())); + TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi]; s << "

" << th << "

"; s << "

" << h << "[" << txi << "]

"; s << "
From: " << pretty(ss).toHtmlEscaped().toStdString() << " " << ss; if (tx.isCreation()) s << "
Creates: " << pretty(right160(th)).toHtmlEscaped().toStdString() << " " << right160(th); else - s << "
To: " << pretty(tx.receiveAddress).toHtmlEscaped().toStdString() << " " << tx.receiveAddress; - s << "
Value: " << formatBalance(tx.value) << ""; - s << "   #" << tx.nonce << ""; - s << "
Gas price: " << formatBalance(tx.gasPrice) << ""; - s << "
Gas: " << tx.gas << ""; - s << "
V: " << hex << nouppercase << (int)tx.vrs.v << ""; - s << "
R: " << hex << nouppercase << tx.vrs.r << ""; - s << "
S: " << hex << nouppercase << tx.vrs.s << ""; - s << "
Msg: " << tx.sha3(false) << ""; + s << "
To: " << pretty(tx.receiveAddress()).toHtmlEscaped().toStdString() << " " << tx.receiveAddress(); + s << "
Value: " << formatBalance(tx.value()) << ""; + s << "   #" << tx.nonce() << ""; + s << "
Gas price: " << formatBalance(tx.gasPrice()) << ""; + s << "
Gas: " << tx.gas() << ""; + s << "
V: " << hex << nouppercase << (int)tx.signature().v << " + 27"; + s << "
R: " << hex << nouppercase << tx.signature().r << ""; + s << "
S: " << hex << nouppercase << tx.signature().s << ""; + s << "
Msg: " << tx.sha3(eth::WithoutSignature) << ""; + s << "
Log Bloom: " << receipt.bloom() << "
"; + s << "
Hex: " << toHex(block[1][txi].data()) << "
"; + auto r = receipt.rlp(); + s << "
Receipt: " << toString(RLP(r)) << "
"; + s << "
Receipt-Hex: " << toHex(receipt.rlp()) << "
"; if (tx.isCreation()) { - if (tx.data.size()) - s << "

Code

" << disassemble(tx.data); + if (tx.data().size()) + s << "

Code

" << disassemble(tx.data()); } else { - if (tx.data.size()) - s << dev::memDump(tx.data, 16, true); + if (tx.data().size()) + s << dev::memDump(tx.data(), 16, true); } s << renderDiff(ethereum()->diff(txi, h)); ui->debugCurrent->setEnabled(true); @@ -1134,7 +1350,7 @@ void Main::on_debugCurrent_triggered() { unsigned txi = item->data(Qt::UserRole + 1).toInt(); m_executiveState = ethereum()->state(txi + 1, h); - m_currentExecution = unique_ptr(new Executive(m_executiveState)); + m_currentExecution = unique_ptr(new Executive(m_executiveState, 0)); Transaction t = m_executiveState.pending()[txi]; m_executiveState = m_executiveState.fromPending(txi); auto r = t.rlp(); @@ -1178,20 +1394,20 @@ void Main::populateDebugger(dev::bytesConstRef _r) debugFinished(); vector levels; m_codes.clear(); - bytesConstRef lastExtCode; + bytes lastExtCode; bytesConstRef lastData; h256 lastHash; h256 lastDataHash; - auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, void* voidVM, void const* voidExt) + auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, dev::eth::VM* voidVM, dev::eth::ExtVMFace const* voidExt) { - dev::eth::VM& vm = *(dev::eth::VM*)voidVM; - dev::eth::ExtVM const& ext = *(dev::eth::ExtVM const*)voidExt; + dev::eth::VM& vm = *voidVM; + dev::eth::ExtVM const& ext = *static_cast(voidExt); if (ext.code != lastExtCode) { lastExtCode = ext.code; lastHash = sha3(lastExtCode); if (!m_codes.count(lastHash)) - m_codes[lastHash] = ext.code.toBytes(); + m_codes[lastHash] = ext.code; } if (ext.data != lastData) { @@ -1200,10 +1416,10 @@ void Main::populateDebugger(dev::bytesConstRef _r) if (!m_codes.count(lastDataHash)) m_codes[lastDataHash] = ext.data.toBytes(); } - if (levels.size() < ext.level) + if (levels.size() < ext.depth) levels.push_back(&m_history.back()); else - levels.resize(ext.level); + levels.resize(ext.depth); m_history.append(WorldState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, vm.gas(), lastHash, lastDataHash, vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels})); }; m_currentExecution->go(onOp); @@ -1231,7 +1447,7 @@ void Main::on_contracts_currentItemChanged() s << "

Body Code

" << disassemble(ethereum()->codeAt(address)); ui->contractInfo->appendHtml(QString::fromStdString(s.str())); } - catch (dev::eth::InvalidTrie) + catch (dev::InvalidTrie) { ui->contractInfo->appendHtml("Corrupted trie."); } @@ -1284,6 +1500,60 @@ void Main::on_destination_currentTextChanged() // updateFee(); } +static shh::Topic topicFromText(QString _s) +{ + shh::BuildTopic ret; + while (_s.size()) + { + QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?"); + QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); + QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); + bytes part; + if (r.exactMatch(_s)) + { + for (auto i: r.cap(2)) + part.push_back((byte)i.toLatin1()); + if (r.cap(1) != "$") + for (int i = r.cap(2).size(); i < 32; ++i) + part.push_back(0); + else + part.push_back(0); + _s = r.cap(3); + } + else if (d.exactMatch(_s)) + { + u256 v(d.cap(2).toStdString()); + if (d.cap(6) == "szabo") + v *= dev::eth::szabo; + else if (d.cap(5) == "finney") + v *= dev::eth::finney; + else if (d.cap(4) == "ether") + v *= dev::eth::ether; + bytes bs = dev::toCompactBigEndian(v); + if (d.cap(1) != "$") + for (auto i = bs.size(); i < 32; ++i) + part.push_back(0); + for (auto b: bs) + part.push_back(b); + _s = d.cap(7); + } + else if (h.exactMatch(_s)) + { + bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString()); + if (h.cap(1) != "$") + for (auto i = bs.size(); i < 32; ++i) + part.push_back(0); + for (auto b: bs) + part.push_back(b); + _s = h.cap(5); + } + else + _s = _s.mid(1); + ret.shift(part); + } + return ret; +} + void Main::on_data_textChanged() { m_pcWarp.clear(); @@ -1292,10 +1562,29 @@ void Main::on_data_textChanged() string src = ui->data->toPlainText().toStdString(); vector errors; QString lll; + QString solidity; if (src.find_first_not_of("1234567890abcdefABCDEF") == string::npos && src.size() % 2 == 0) { m_data = fromHex(src); } + else if (src.substr(0, 8) == "contract") // improve this heuristic + { + dev::solidity::CompilerStack compiler; + try + { + m_data = compiler.compile(src, m_enableOptimizer); + } + catch (dev::Exception const& exception) + { + ostringstream error; + solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler); + solidity = "

Solidity

" + QString::fromStdString(error.str()).toHtmlEscaped() + "
"; + } + catch (...) + { + solidity = "

Solidity

Uncaught exception.
"; + } + } else { m_data = dev::eth::compileLLL(src, m_enableOptimizer, &errors); @@ -1330,66 +1619,19 @@ void Main::on_data_textChanged() for (auto const& i: errors) errs.append("
" + QString::fromStdString(i).toHtmlEscaped() + "
"); } - ui->code->setHtml(errs + lll + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped()); - ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 0)); + ui->code->setHtml(errs + lll + solidity + "

Code

" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped()); + ui->gas->setMinimum((qint64)Client::txGas(m_data, 0)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); } else { - m_data.clear(); - QString s = ui->data->toPlainText(); - while (s.size()) - { - QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?"); - QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); - QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); - if (r.exactMatch(s)) - { - for (auto i: r.cap(2)) - m_data.push_back((byte)i.toLatin1()); - if (r.cap(1) != "$") - for (int i = r.cap(2).size(); i < 32; ++i) - m_data.push_back(0); - else - m_data.push_back(0); - s = r.cap(3); - } - else if (d.exactMatch(s)) - { - u256 v(d.cap(2).toStdString()); - if (d.cap(6) == "szabo") - v *= dev::eth::szabo; - else if (d.cap(5) == "finney") - v *= dev::eth::finney; - else if (d.cap(4) == "ether") - v *= dev::eth::ether; - bytes bs = dev::toCompactBigEndian(v); - if (d.cap(1) != "$") - for (auto i = bs.size(); i < 32; ++i) - m_data.push_back(0); - for (auto b: bs) - m_data.push_back(b); - s = d.cap(7); - } - else if (h.exactMatch(s)) - { - bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString()); - if (h.cap(1) != "$") - for (auto i = bs.size(); i < 32; ++i) - m_data.push_back(0); - for (auto b: bs) - m_data.push_back(b); - s = h.cap(5); - } - else - s = s.mid(1); - } + m_data = parseData(ui->data->toPlainText().toStdString()); ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size()) { - ui->gas->setMinimum((qint64)Client::txGas(m_data.size(), 1)); + ui->gas->setMinimum((qint64)Client::txGas(m_data, 1)); if (!ui->gas->isEnabled()) ui->gas->setValue(m_backupGas); ui->gas->setEnabled(true); @@ -1398,7 +1640,7 @@ void Main::on_data_textChanged() { if (ui->gas->isEnabled()) m_backupGas = ui->gas->value(); - ui->gas->setValue((qint64)Client::txGas(m_data.size())); + ui->gas->setValue((qint64)Client::txGas(m_data)); ui->gas->setEnabled(false); } } @@ -1412,7 +1654,6 @@ void Main::on_killBlockchain_triggered() ui->net->setChecked(false); web3()->stopNetwork(); ethereum()->killChain(); - m_ethereum->setClient(ethereum()); readSettings(true); installWatches(); refreshAll(); @@ -1470,7 +1711,7 @@ void Main::on_net_triggered() { ui->port->setEnabled(!ui->net->isChecked()); ui->clientName->setEnabled(!ui->net->isChecked()); - string n = string("AlethZero/v") + dev::Version; + string n = string("AlethZero/v") + dev::Version; if (ui->clientName->text().size()) n += "/" + ui->clientName->text().toStdString(); n += "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM); @@ -1482,10 +1723,10 @@ void Main::on_net_triggered() web3()->setIdealPeerCount(ui->idealPeers->value()); web3()->setNetworkPreferences(netPrefs()); ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : 0); + if (m_peers.size()/* && ui->usePast->isChecked()*/) + web3()->restoreNodes(bytesConstRef((byte*)m_peers.data(), m_peers.size())); web3()->startNetwork(); ui->downloadView->setDownloadMan(ethereum()->downloadMan()); - if (m_peers.size() && ui->usePast->isChecked()) - web3()->restorePeers(bytesConstRef((byte*)m_peers.data(), m_peers.size())); } else { @@ -1545,6 +1786,12 @@ void Main::on_send_clicked() statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount."); } +void Main::keysChanged() +{ + onBalancesChange(); + m_server->setAccounts(keysAsVector(m_myKeys)); +} + void Main::on_debug_clicked() { debugFinished(); @@ -1556,15 +1803,10 @@ void Main::on_debug_clicked() { Secret s = i.secret(); m_executiveState = ethereum()->postState(); - m_currentExecution = unique_ptr(new Executive(m_executiveState)); - Transaction t; - t.nonce = m_executiveState.transactionsFrom(dev::toAddress(s)); - t.value = value(); - t.gasPrice = gasPrice(); - t.gas = ui->gas->value(); - t.data = m_data; - t.receiveAddress = isCreation() ? Address() : fromString(ui->destination->currentText()); - t.sign(s); + m_currentExecution = unique_ptr(new Executive(m_executiveState, 0)); + Transaction t = isCreation() ? + Transaction(value(), gasPrice(), ui->gas->value(), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s) : + Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, m_executiveState.transactionsFrom(dev::toAddress(s)), s); auto r = t.rlp(); populateDebugger(&r); m_currentExecution.reset(); @@ -1574,14 +1816,15 @@ void Main::on_debug_clicked() } catch (dev::Exception const& _e) { - statusBar()->showMessage("Error running transaction: " + QString::fromStdString(_e.description())); + statusBar()->showMessage("Error running transaction: " + QString::fromStdString(diagnostic_information(_e))); + // this output is aimed at developers, reconsider using _e.what for more user friendly output. } } void Main::on_create_triggered() { m_myKeys.append(KeyPair::create()); - m_keysChanged = true; + keysChanged(); } void Main::on_debugStep_triggered() @@ -1638,9 +1881,9 @@ void Main::on_debugStepBack_triggered() void Main::on_debugStepBackOut_triggered() { - if (ui->debugTimeline->value() > 0) + if (ui->debugTimeline->value() > 0 && m_history.size() > 0) { - auto ls = m_history[ui->debugTimeline->value()].levels.size(); + auto ls = m_history[min(ui->debugTimeline->value(), m_history.size() - 1)].levels.size(); int l = ui->debugTimeline->value(); for (; l > 0 && m_history[l].levels.size() >= ls; --l) {} ui->debugTimeline->setValue(l); @@ -1689,6 +1932,16 @@ void Main::on_dumpTraceStorage_triggered() } } +void Main::on_go_triggered() +{ + if (!ui->net->isChecked()) + { + ui->net->setChecked(true); + on_net_triggered(); + } + web3()->connect(Host::pocHost()); +} + void Main::on_callStack_currentItemChanged() { updateDebugger(); @@ -1752,7 +2005,7 @@ QString Main::prettyU256(dev::u256 _n) const s << "" << (uint64_t)_n << " (0x" << hex << (uint64_t)_n << ")"; else if (!~(_n >> 64)) s << "" << (int64_t)_n << " (0x" << hex << (int64_t)_n << ")"; - else if ((_n >> 200) == 0) + else if ((_n >> 160) == 0) { Address a = right160(_n); QString n = pretty(a); @@ -1850,6 +2103,8 @@ void Main::updateDebugger() } catch (...) { + cerr << "Unhandled exception!" << endl << + boost::current_exception_diagnostic_information(); break; // probably hit data segment } } @@ -1896,17 +2151,43 @@ void Main::updateDebugger() } } -// extra bits needed to link on VS -#ifdef _MSC_VER - -// include moc file, ofuscated to hide from automoc -#include\ -"moc_MainWin.cpp" - -#include\ -"moc_MiningView.cpp" - -#include\ -"moc_DownloadView.cpp" +void Main::on_post_clicked() +{ + shh::Message m; + m.setTo(stringToPublic(ui->shhTo->currentText())); + m.setPayload(parseData(ui->shhData->toPlainText().toStdString())); + Public f = stringToPublic(ui->shhFrom->currentText()); + Secret from; + if (m_server->ids().count(f)) + from = m_server->ids().at(f); + whisper()->inject(m.seal(from, topicFromText(ui->shhTopic->toPlainText()), ui->shhTtl->value(), ui->shhWork->value())); +} -#endif +void Main::refreshWhispers() +{ + ui->whispers->clear(); + for (auto const& w: whisper()->all()) + { + shh::Envelope const& e = w.second; + shh::Message m; + for (pair const& i: m_server->ids()) + if (!!(m = e.open(i.second))) + break; + if (!m) + m = e.open(); + + QString msg; + if (m.from()) + // Good message. + msg = QString("{%1 -> %2} %3").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str()); + else if (m) + // Maybe message. + msg = QString("{%1 -> %2} %3 (?)").arg(m.from() ? m.from().abridged().c_str() : "???").arg(m.to() ? m.to().abridged().c_str() : "*").arg(toHex(m.payload()).c_str()); + + time_t ex = e.expiry(); + QString t(ctime(&ex)); + t.chop(1); + QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topics()).c_str()).arg(msg); + ui->whispers->addItem(item); + } +} diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index ce1a9b670..5c196792d 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -21,6 +21,9 @@ #pragma once +#ifdef Q_MOC_RUN +#define BOOST_MPL_IF_HPP_INCLUDED +#endif #include #include @@ -30,6 +33,7 @@ #include #include #include +#include #include #include @@ -40,10 +44,10 @@ class Main; namespace dev { namespace eth { class Client; class State; -class MessageFilter; }} class QQuickView; +class OurWebThreeStubServer; struct WorldState { @@ -65,22 +69,23 @@ struct WorldState class Main : public QMainWindow { Q_OBJECT - + public: explicit Main(QWidget *parent = 0); ~Main(); dev::WebThreeDirect* web3() const { return m_webThree.get(); } dev::eth::Client* ethereum() const { return m_webThree->ethereum(); } - dev::shh::WhisperHost* whisper() const { return m_webThree->whisper(); } + std::shared_ptr whisper() const { return m_webThree->whisper(); } + + QList owned() const { return m_myIdentities + m_myKeys; } - QList const& owned() const { return m_myKeys; } - public slots: void load(QString _file); void note(QString _entry); void debug(QString _entry); void warn(QString _entry); + QString contents(QString _file); void onKeysChanged(); @@ -141,9 +146,17 @@ private slots: void on_debugDumpState_triggered(int _add = 1); void on_debugDumpStatePre_triggered(); void on_refresh_triggered(); - void on_usePrivate_triggered(); + void on_usePrivate_triggered(); void on_enableOptimizer_triggered(); void on_turboMining_triggered(); + void on_go_triggered(); + void on_importKeyFile_triggered(); + void on_post_clicked(); + void on_newIdentity_triggered(); + + void refreshWhisper(); + void refreshBlockChain(); + void addNewId(QString _ids); signals: void poll(); @@ -176,8 +189,11 @@ private: dev::u256 value() const; dev::u256 gasPrice() const; - unsigned installWatch(dev::eth::MessageFilter const& _tf, std::function const& _f); + unsigned installWatch(dev::eth::LogFilter const& _tf, std::function const& _f); unsigned installWatch(dev::h256 _tf, std::function const& _f); + void uninstallWatch(unsigned _w); + + void keysChanged(); void onNewPending(); void onNewBlock(); @@ -194,12 +210,12 @@ private: void refreshNetwork(); void refreshMining(); + void refreshWhispers(); void refreshAll(); void refreshPending(); void refreshAccounts(); void refreshDestination(); - void refreshBlockChain(); void refreshBlockCount(); void refreshBalances(); @@ -215,8 +231,8 @@ private: QByteArray m_peers; QStringList m_servers; QList m_myKeys; + QList m_myIdentities; QString m_privateChain; - bool m_keysChanged = false; dev::bytes m_data; dev::Address m_nameReg; @@ -240,5 +256,9 @@ private: QString m_logHistory; bool m_logChanged = true; - QEthereum* m_ethereum = nullptr; + std::unique_ptr m_qwebConnector; + std::unique_ptr m_server; + QWebThree* m_qweb = nullptr; + + static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr); }; diff --git a/libethereum/Manifest.cpp b/alethzero/OurWebThreeStubServer.cpp similarity index 59% rename from libethereum/Manifest.cpp rename to alethzero/OurWebThreeStubServer.cpp index 2d1e4aa6e..0c6f42b5a 100644 --- a/libethereum/Manifest.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -14,33 +14,23 @@ You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ -/** @file Manifest.cpp +/** @file OurWebThreeStubServer.cpp * @author Gav Wood * @date 2014 */ -#include "Manifest.h" +#include "OurWebThreeStubServer.h" using namespace std; using namespace dev; using namespace dev::eth; -Manifest::Manifest(bytesConstRef _r) -{ - RLP r(_r); - from = r[0].toHash
(); - to = r[1].toHash
(); - value = r[2].toInt(); - altered = r[3].toVector(); - input = r[4].toBytes(); - output = r[5].toBytes(); - for (auto const& i: r[6]) - internal.emplace_back(i.data()); -} +OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts): + WebThreeStubServer(_conn, _web3, _accounts) +{} -void Manifest::streamOut(RLPStream& _s) const +std::string OurWebThreeStubServer::shh_newIdentity() { - _s.appendList(7) << from << to << value << altered << input << output; - _s.appendList(internal.size()); - for (auto const& i: internal) - i.streamOut(_s); + dev::KeyPair kp = dev::KeyPair::create(); + emit onNewId(QString::fromStdString(toJS(kp.sec()))); + return toJS(kp.pub()); } diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h new file mode 100644 index 000000000..fb026d07e --- /dev/null +++ b/alethzero/OurWebThreeStubServer.h @@ -0,0 +1,38 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . +*/ +/** @file OurWebThreeStubServer.h + * @author Gav Wood + * @date 2014 + */ + +#include +#include +#include +#include + +class OurWebThreeStubServer: public QObject, public WebThreeStubServer +{ + Q_OBJECT + +public: + OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector const& _accounts); + + virtual std::string shh_newIdentity() override; + +signals: + void onNewId(QString _s); +}; diff --git a/alethzero/alethzero.ico b/alethzero/alethzero.ico new file mode 100644 index 000000000..acee27751 Binary files /dev/null and b/alethzero/alethzero.ico differ diff --git a/alethzero/alethzero.rc b/alethzero/alethzero.rc new file mode 100644 index 000000000..29c778bd4 --- /dev/null +++ b/alethzero/alethzero.rc @@ -0,0 +1 @@ +APP_ICON ICON DISCARDABLE "alethzero.ico" \ No newline at end of file diff --git a/alethzero/main.cpp b/alethzero/main.cpp index 42afd5e66..8a430b0e9 100644 --- a/alethzero/main.cpp +++ b/alethzero/main.cpp @@ -4,6 +4,7 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); + Q_INIT_RESOURCE(js); Main w; w.show(); diff --git a/astylerc b/astylerc index 0b407b9fe..d4e1188eb 100644 --- a/astylerc +++ b/astylerc @@ -6,6 +6,6 @@ min-conditional-indent=1 pad-oper pad-header unpad-paren -delete-empty-lines align-pointer=type - +keep-one-line-blocks +close-templates diff --git a/build.py b/build.py new file mode 100755 index 000000000..099a8721d --- /dev/null +++ b/build.py @@ -0,0 +1,27 @@ +#!/usr/bin/python +# cpp-ethereum build script +# to be used from CI server, or to build locally +# uses python instead of bash script for better cross-platform support + +# TODO Initial version. Needs much more improvements + +import argparse +import os +import subprocess + +def build_dependencies(): + if os.path.exists("extdep"): + os.chdir("extdep") + if not os.path.exists("build"): + os.makedirs("build") + os.chdir("build") + subprocess.check_call(["cmake", ".."]) + subprocess.check_call("make") + +parser = argparse.ArgumentParser() +parser.add_argument("cmd", help="what to build") + +args = parser.parse_args() +if args.cmd == "dep": + build_dependencies() + diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake new file mode 100644 index 000000000..24252cc0b --- /dev/null +++ b/cmake/EthCompilerSettings.cmake @@ -0,0 +1,39 @@ +# Set necessary compile and link flags + +# C++11 check and activation +if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") + set(ETH_SHARED 1) + + execute_process( + COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) + if (NOT (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)) + message(FATAL_ERROR "${PROJECT_NAME} requires g++ 4.7 or greater.") + endif () + +elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + + set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wno-unknown-pragmas -Wextra -DSHAREDLIB -fPIC") + set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -DETH_DEBUG") + set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -DETH_RELEASE") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DETH_DEBUG") + set(ETH_SHARED 1) + +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + # specify Exception Handling Model in msvc + set(CMAKE_C_FLAGS "/EHsc") + set(CMAKE_CXX_FLAGS "/EHsc") + # windows likes static + set(ETH_STATIC 1) + +else () + message(WARNING "Your compiler is not tested, if you run into any issues, we'd welcome any patches.") +endif () + diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake new file mode 100644 index 000000000..136c86799 --- /dev/null +++ b/cmake/EthDependencies.cmake @@ -0,0 +1,148 @@ +# all dependencies that are not directly included in the cpp-ethereum distribution are defined here +# for this to work, download the dependency via the cmake script in extdep or install them manually! + +# by defining this variable, cmake will look for dependencies first in our own repository before looking in system paths like /usr/local/ ... +# this must be set to point to the same directory as $ETH_DEPENDENCY_INSTALL_DIR in /extdep directory +string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name) +set (ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/extdep/install/${_system_name}") +set (CMAKE_PREFIX_PATH ${ETH_DEPENDENCY_INSTALL_DIR}) + +# Qt5 requires opengl +# TODO use proper version of windows SDK (32 vs 64) +# TODO make it possible to use older versions of windows SDK (7.0+ should also work) +# TODO it windows SDK is NOT FOUND, throw ERROR +if (WIN32) + set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x86") + message(" - Found windows 8.1 SDK") + #set (CMAKE_PREFIX_PATH "C:/Program Files/Windows Kits/8.1/Lib/winv6.3/um/x64") +endif() + +# homebrew installs qts in opt +if (APPLE) + set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/qt5") +endif() + +# Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different. + +find_package (CryptoPP 5.6.2 EXACT REQUIRED) +message(" - CryptoPP header: ${CRYPTOPP_INCLUDE_DIRS}") +message(" - CryptoPP lib : ${CRYPTOPP_LIBRARIES}") + +find_package (LevelDB REQUIRED) +message(" - LevelDB header: ${LEVELDB_INCLUDE_DIRS}") +message(" - LevelDB lib: ${LEVELDB_LIBRARIES}") + +# TODO the Jsoncpp package does not yet check for correct version number +find_package (Jsoncpp 0.60 REQUIRED) +message(" - Jsoncpp header: ${JSONCPP_INCLUDE_DIRS}") +message(" - Jsoncpp lib : ${JSONCPP_LIBRARIES}") + +# TODO the JsonRpcCpp package does not yet check for correct version number +# json-rpc-cpp support is currently not mandatory +# TODO make headless client optional +# TODO get rid of -DETH_JSONRPC +if (JSONRPC) + + find_package (JsonRpcCpp 0.3.2) + if (NOT JSON_RPC_CPP_FOUND) + message (FATAL_ERROR "JSONRPC 0.3.2. not found") + endif() + message (" - json-rpc-cpp header: ${JSON_RPC_CPP_INCLUDE_DIRS}") + message (" - json-rpc-cpp lib : ${JSON_RPC_CPP_LIBRARIES}") + add_definitions(-DETH_JSONRPC) + +endif() #JSONRPC + +# TODO readline package does not yet check for correct version number +# TODO make readline package dependent on cmake options +# TODO get rid of -DETH_READLINE +find_package (Readline 6.3.8) +if (READLINE_FOUND) + message (" - readline header: ${READLINE_INCLUDE_DIRS}") + message (" - readline lib : ${READLINE_LIBRARIES}") + add_definitions(-DETH_READLINE) +endif () + +# TODO miniupnpc package does not yet check for correct version number +# TODO make miniupnpc package dependent on cmake options +# TODO get rid of -DMINIUPNPC +find_package (Miniupnpc 1.8.2013) +if (MINIUPNPC_FOUND) + message (" - miniupnpc header: ${MINIUPNPC_INCLUDE_DIRS}") + message (" - miniupnpc lib : ${MINIUPNPC_LIBRARIES}") + add_definitions(-DETH_MINIUPNPC) +endif() + +# TODO gmp package does not yet check for correct version number +# TODO it is also not required in msvc build +find_package (Gmp 6.0.0) +if (GMP_FOUND) + message(" - gmp Header: ${GMP_INCLUDE_DIRS}") + message(" - gmp lib : ${GMP_LIBRARIES}") +endif() + +# curl is only requried for tests +# TODO specify min curl version, on windows we are currently using 7.29 +find_package (CURL) +message(" - curl header: ${CURL_INCLUDE_DIRS}") +message(" - curl lib : ${CURL_LIBRARIES}") + +# do not compile GUI +if (NOT HEADLESS) + +# we need json rpc to build alethzero + if (NOT JSON_RPC_CPP_FOUND) + message (FATAL_ERROR "JSONRPC is required for GUI client") + endif() + +# find all of the Qt packages +# remember to use 'Qt' instead of 'QT', cause unix is case sensitive +# TODO make headless client optional + find_package (Qt5Core REQUIRED) + find_package (Qt5Gui REQUIRED) + find_package (Qt5Quick REQUIRED) + find_package (Qt5Qml REQUIRED) + find_package (Qt5Network REQUIRED) + find_package (Qt5Widgets REQUIRED) + find_package (Qt5WebKit REQUIRED) + find_package (Qt5WebKitWidgets REQUIRED) + + # we need to find path to macdeployqt on mac + if (APPLE) + set (MACDEPLOYQT_APP ${Qt5Core_DIR}/../../../bin/macdeployqt) + message(" - macdeployqt path: ${MACDEPLOYQT_APP}") + endif() + +endif() #HEADLESS + +# use multithreaded boost libraries, with -mt suffix +set(Boost_USE_MULTITHREADED ON) + +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + +# TODO hanlde other msvc versions or it will fail find them + set(Boost_COMPILER -vc120) +# use static boost libraries *.lib + set(Boost_USE_STATIC_LIBS ON) + +elseif (APPLE) + +# use static boost libraries *.a + set(Boost_USE_STATIC_LIBS ON) + +elseif (UNIX) +# use dynamic boost libraries .dll + set(Boost_USE_STATIC_LIBS OFF) + +endif() + +find_package(Boost 1.54.0 REQUIRED COMPONENTS thread date_time system regex chrono filesystem unit_test_framework program_options) + +message(" - boost header: ${Boost_INCLUDE_DIRS}") +message(" - boost lib : ${Boost_LIBRARIES}") + +if (APPLE) + link_directories(/usr/local/lib) + include_directories(/usr/local/include) +endif() + diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake new file mode 100644 index 000000000..88e2a3e16 --- /dev/null +++ b/cmake/EthExecutableHelper.cmake @@ -0,0 +1,152 @@ +# +# this function requires the following variables to be specified: +# ETH_VERSION +# PROJECT_NAME +# PROJECT_VERSION +# PROJECT_COPYRIGHT_YEAR +# PROJECT_VENDOR +# PROJECT_DOMAIN_SECOND +# PROJECT_DOMAIN_FIRST +# SRC_LIST +# HEADERS +# +# params: +# ICON +# + +macro(eth_add_executable EXECUTABLE) + set (extra_macro_args ${ARGN}) + set (options) + set (one_value_args ICON) + set (multi_value_args UI_RESOURCES WIN_RESOURCES) + cmake_parse_arguments (ETH_ADD_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (APPLE) + + add_executable(${EXECUTABLE} MACOSX_BUNDLE ${SRC_LIST} ${HEADERS} ${ETH_ADD_EXECUTABLE_UI_RESOURCES}) + set(PROJECT_VERSION "${ETH_VERSION}") + set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME} ${PROJECT_VERSION}") + set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}") + set(MACOSX_BUNDLE_COPYRIGHT "${PROJECT_COPYRIGHT_YEAR} ${PROJECT_VENDOR}") + set(MACOSX_BUNDLE_GUI_IDENTIFIER "${PROJECT_DOMAIN_SECOND}.${PROJECT_DOMAIN_FIRST}") + set(MACOSX_BUNDLE_BUNDLE_NAME ${EXECUTABLE}) + set(MACOSX_BUNDLE_ICON_FILE ${ETH_ADD_EXECUTABLE_ICON}) + set_target_properties(${EXECUTABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in") + set_source_files_properties(${EXECUTABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS) + set_source_files_properties(${MACOSX_BUNDLE_ICON_FILE}.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources) + + else () + add_executable(${EXECUTABLE} ${ETH_ADD_EXECUTABLE_UI_RESOURCES} ${ETH_ADD_EXECUTABLE_WIN_RESOURCES} ${SRC_LIST} ${HEADERS}) + endif() + +endmacro() + +# +# this function requires the following variables to be specified: +# ETH_DEPENDENCY_INSTALL_DIR +# +# params: +# QMLDIR +# + +macro(eth_install_executable EXECUTABLE) + + set (extra_macro_args ${ARGN}) + set (options) + set (one_value_args QMLDIR) + set (multi_value_args) + cmake_parse_arguments (ETH_INSTALL_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}") + + if (ETH_INSTALL_EXECUTABLE_QMLDIR) + if (APPLE) + set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}") + elseif (WIN32) + set(eth_qml_dir --qmldir ${ETH_INSTALL_EXECUTABLE_QMLDIR}) + endif() + message(STATUS "${EXECUTABLE} qmldir: ${eth_qml_dir}") + endif() + + if (APPLE) + # First have qt5 install plugins and frameworks + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND ${MACDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app ${eth_qml_dir} + WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + ) + + # This tool and next will inspect linked libraries in order to determine which dependencies are required + if (${CMAKE_CFG_INTDIR} STREQUAL ".") + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app") + else () + set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app") + endif () + + # TODO check, how fixup_bundle works and if it is required + install(CODE " + include(BundleUtilities) + set(BU_CHMOD_BUNDLE_ITEMS 1) + fixup_bundle(\"${APP_BUNDLE_PATH}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\") + " COMPONENT RUNTIME ) + # Cleanup duplicate libs from macdeployqt + install(CODE " + file(GLOB LINGER_RM \"${APP_BUNDLE_PATH}/Contents/Frameworks/*.dylib\") + if (LINGER_RM) + file(REMOVE \${LINGER_RM}) + endif () + ") + elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + + # copy all dlls to executable directory + # TODO improve that by copying only required dlls + file (GLOB DLLS ${ETH_DEPENDENCY_INSTALL_DIR}/bin/*.dll) + + foreach(DLL ${DLLS}) + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy "${DLL}" "$" + ) + endforeach() + + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy_directory + "${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms" + $/platforms + ) + + # ugly way, improve that + add_custom_command(TARGET ${EXECUTABLE} POST_BUILD + COMMAND cmake -E copy_directory + "${ETH_DEPENDENCY_INSTALL_DIR}/qml" + $ + ) + + install( FILES ${DLLS} + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) + + install( DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) + + file (GLOB QMLS ${ETH_DEPENDENCY_INSTALL_DIR}/qml/*) + foreach(QML ${QMLS}) + install( DIRECTORY ${QML} + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) + endforeach() + + install( TARGETS ${EXECUTABLE} RUNTIME + DESTINATION bin + COMPONENT ${EXECUTABLE} + ) + + else() + install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) + endif () + +endmacro() + + diff --git a/cmake/FindCURL.cmake b/cmake/FindCURL.cmake new file mode 100644 index 000000000..ba6603784 --- /dev/null +++ b/cmake/FindCURL.cmake @@ -0,0 +1,49 @@ +# Find CURL +# +# Find the curl includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# CURL_INCLUDE_DIRS, where to find header, etc. +# CURL_LIBRARIES, the libraries needed to use curl. +# CURL_FOUND, If false, do not try to use curl. + +# only look in default directories +find_path( + CURL_INCLUDE_DIR + NAMES curl/curl.h + DOC "curl include dir" +) + +find_library( + CURL_LIBRARY + # names from cmake's FindCURL + NAMES curl curllib libcurl_imp curllib_static libcurl + DOC "curl library" +) + +set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR}) +set(CURL_LIBRARIES ${CURL_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + CURL_LIBRARY_DEBUG + NAMES curld libcurld + DOC "curl debug library" + ) + + set(CURL_LIBRARIES optimized ${CURL_LIBRARIES} debug ${CURL_LIBRARY_DEBUG}) + +endif() + +# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CURL DEFAULT_MSG + CURL_INCLUDE_DIR CURL_LIBRARY) +mark_as_advanced (CURL_INCLUDE_DIR CURL_LIBRARY) + diff --git a/cmake/FindCryptoPP.cmake b/cmake/FindCryptoPP.cmake new file mode 100644 index 000000000..a9e7183c0 --- /dev/null +++ b/cmake/FindCryptoPP.cmake @@ -0,0 +1,108 @@ +# Module for locating the Crypto++ encryption library. +# +# Customizable variables: +# CRYPTOPP_ROOT_DIR +# This variable points to the CryptoPP root directory. On Windows the +# library location typically will have to be provided explicitly using the +# -D command-line option. The directory should include the include/cryptopp, +# lib and/or bin sub-directories. +# +# Read-only variables: +# CRYPTOPP_FOUND +# Indicates whether the library has been found. +# +# CRYPTOPP_INCLUDE_DIRS +# Points to the CryptoPP include directory. +# +# CRYPTOPP_LIBRARIES +# Points to the CryptoPP libraries that should be passed to +# target_link_libararies. +# +# +# Copyright (c) 2012 Sergiu Dotenco +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +INCLUDE (FindPackageHandleStandardArgs) + +FIND_PATH (CRYPTOPP_ROOT_DIR + NAMES cryptopp/cryptlib.h include/cryptopp/cryptlib.h + PATHS ENV CRYPTOPPROOT + DOC "CryptoPP root directory") + +# Re-use the previous path: +FIND_PATH (CRYPTOPP_INCLUDE_DIR + NAMES cryptopp/cryptlib.h + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES include + DOC "CryptoPP include directory") + +FIND_LIBRARY (CRYPTOPP_LIBRARY_DEBUG + NAMES cryptlibd cryptoppd + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES lib + DOC "CryptoPP debug library") + +FIND_LIBRARY (CRYPTOPP_LIBRARY_RELEASE + NAMES cryptlib cryptopp + HINTS ${CRYPTOPP_ROOT_DIR} + PATH_SUFFIXES lib + DOC "CryptoPP release library") + +IF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) + SET (CRYPTOPP_LIBRARY + optimized ${CRYPTOPP_LIBRARY_RELEASE} + debug ${CRYPTOPP_LIBRARY_DEBUG} CACHE DOC "CryptoPP library") +ELSEIF (CRYPTOPP_LIBRARY_RELEASE) + SET (CRYPTOPP_LIBRARY ${CRYPTOPP_LIBRARY_RELEASE} CACHE DOC + "CryptoPP library") +ENDIF (CRYPTOPP_LIBRARY_DEBUG AND CRYPTOPP_LIBRARY_RELEASE) + +IF (CRYPTOPP_INCLUDE_DIR) + SET (_CRYPTOPP_VERSION_HEADER ${CRYPTOPP_INCLUDE_DIR}/cryptopp/config.h) + + IF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) + FILE (STRINGS ${_CRYPTOPP_VERSION_HEADER} _CRYPTOPP_VERSION_TMP REGEX + "^#define CRYPTOPP_VERSION[ \t]+[0-9]+$") + + STRING (REGEX REPLACE + "^#define CRYPTOPP_VERSION[ \t]+([0-9]+)" "\\1" _CRYPTOPP_VERSION_TMP + ${_CRYPTOPP_VERSION_TMP}) + + STRING (REGEX REPLACE "([0-9]+)[0-9][0-9]" "\\1" CRYPTOPP_VERSION_MAJOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9]([0-9])[0-9]" "\\1" CRYPTOPP_VERSION_MINOR + ${_CRYPTOPP_VERSION_TMP}) + STRING (REGEX REPLACE "[0-9][0-9]([0-9])" "\\1" CRYPTOPP_VERSION_PATCH + ${_CRYPTOPP_VERSION_TMP}) + + SET (CRYPTOPP_VERSION_COUNT 3) + SET (CRYPTOPP_VERSION + ${CRYPTOPP_VERSION_MAJOR}.${CRYPTOPP_VERSION_MINOR}.${CRYPTOPP_VERSION_PATCH}) + ENDIF (EXISTS ${_CRYPTOPP_VERSION_HEADER}) +ENDIF (CRYPTOPP_INCLUDE_DIR) + +SET (CRYPTOPP_INCLUDE_DIRS ${CRYPTOPP_INCLUDE_DIR}) +SET (CRYPTOPP_LIBRARIES ${CRYPTOPP_LIBRARY}) + +MARK_AS_ADVANCED (CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY CRYPTOPP_LIBRARY_DEBUG + CRYPTOPP_LIBRARY_RELEASE) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS (CryptoPP REQUIRED_VARS + CRYPTOPP_INCLUDE_DIR CRYPTOPP_LIBRARY VERSION_VAR CRYPTOPP_VERSION) diff --git a/cmake/FindGmp.cmake b/cmake/FindGmp.cmake new file mode 100644 index 000000000..4570b35fa --- /dev/null +++ b/cmake/FindGmp.cmake @@ -0,0 +1,34 @@ +# Find gmp +# +# Find the gmp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# GMP_INCLUDE_DIRS, where to find header, etc. +# GMP_LIBRARIES, the libraries needed to use gmp. +# GMP_FOUND, If false, do not try to use gmp. + +# only look in default directories +find_path( + GMP_INCLUDE_DIR + NAMES gmp.h + DOC "gmp include dir" +) + +find_library( + GMP_LIBRARY + NAMES gmp + DOC "gmp library" +) + +set(GMP_INCLUDE_DIRS ${GMP_INCLUDE_DIR}) +set(GMP_LIBRARIES ${GMP_LIBRARY}) + +# handle the QUIETLY and REQUIRED arguments and set GMP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(gmp DEFAULT_MSG + GMP_INCLUDE_DIR GMP_LIBRARY) +mark_as_advanced (GMP_INCLUDE_DIR GMP_LIBRARY) + diff --git a/cmake/FindJsonRpcCpp.cmake b/cmake/FindJsonRpcCpp.cmake new file mode 100644 index 000000000..2ca176f68 --- /dev/null +++ b/cmake/FindJsonRpcCpp.cmake @@ -0,0 +1,99 @@ +# Find json-rcp-cpp +# +# Find the json-rpc-cpp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# JSON_RCP_CPP_INCLUDE_DIRS, where to find header, etc. +# JSON_RCP_CPP_LIBRARIES, the libraries needed to use json-rpc-cpp. +# JSON_RPC_CPP_SERVER_LIBRARIES, the libraries needed to use json-rpc-cpp-server +# JSON_RPC_CPP_CLIENT_LIBRARIES, the libraries needed to use json-rpc-cpp-client +# JSON_RCP_CPP_FOUND, If false, do not try to use json-rpc-cpp. + +# only look in default directories +find_path( + JSON_RPC_CPP_INCLUDE_DIR + NAMES jsonrpccpp/server.h + PATH_SUFFIXES jsonrpc + DOC "json-rpc-cpp include dir" +) + +find_library( + JSON_RPC_CPP_COMMON_LIBRARY + NAMES jsonrpccpp-common + DOC "json-rpc-cpp common library" +) + +find_library( + JSON_RPC_CPP_SERVER_LIBRARY + NAMES jsonrpccpp-server + DOC "json-rpc-cpp server library" +) + +find_library( + JSON_RPC_CPP_CLIENT_LIBRARY + NAMES jsonrpccpp-client + DOC "json-rpc-cpp client library" +) + +# these are the variables to be uses by the calling script +set (JSON_RPC_CPP_INCLUDE_DIRS ${JSON_RPC_CPP_INCLUDE_DIR}) +set (JSON_RPC_CPP_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) +set (JSON_RPC_CPP_SERVER_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_SERVER_LIBRARY}) +set (JSON_RPC_CPP_CLIENT_LIBRARIES ${JSON_RPC_CPP_COMMON_LIBRARY} ${JSON_RPC_CPP_CLIENT_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + JSON_RPC_CPP_COMMON_LIBRARY_DEBUG + NAMES jsonrpccpp-commond + DOC "json-rpc-cpp common debug library" + ) + + find_library( + JSON_RPC_CPP_SERVER_LIBRARY_DEBUG + NAMES jsonrpccpp-serverd + DOC "json-rpc-cpp server debug library" + ) + + find_library( + JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG + NAMES jsonrpccpp-clientd + DOC "json-rpc-cpp client debug library" + ) + + set (JSON_RPC_CPP_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_SERVER_LIBRARY} + optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} + ) + + set (JSON_RPC_CPP_SERVER_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_SERVER_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_SERVER_LIBRARY_DEBUG} + ) + + set (JSON_RPC_CPP_CLIENT_LIBRARIES + optimized ${JSON_RPC_CPP_COMMON_LIBRARY} + optimized ${JSON_RPC_CPP_CLIENT_LIBRARY} + debug ${JSON_RPC_CPP_COMMON_LIBRARY_DEBUG} + debug ${JSON_RPC_CPP_CLIENT_LIBRARY_DEBUG} + ) + +endif() + +# handle the QUIETLY and REQUIRED arguments and set JSON_RPC_CPP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(json_rpc_cpp DEFAULT_MSG + JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) +mark_as_advanced (JSON_RPC_CPP_COMMON_LIBRARY JSON_RPC_CPP_SERVER_LIBRARY JSON_RPC_CPP_CLIENT_LIBRARY JSON_RPC_CPP_INCLUDE_DIR) + diff --git a/cmake/FindJsoncpp.cmake b/cmake/FindJsoncpp.cmake new file mode 100644 index 000000000..36ba12a3e --- /dev/null +++ b/cmake/FindJsoncpp.cmake @@ -0,0 +1,48 @@ +# Find jsoncpp +# +# Find the jsoncpp includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# JSONCPP_INCLUDE_DIRS, where to find header, etc. +# JSONCPP_LIBRARIES, the libraries needed to use jsoncpp. +# JSONCPP_FOUND, If false, do not try to use jsoncpp. + +# only look in default directories +find_path( + JSONCPP_INCLUDE_DIR + NAMES jsoncpp/json/json.h + DOC "jsoncpp include dir" +) + +find_library( + JSONCPP_LIBRARY + NAMES jsoncpp + DOC "jsoncpp library" +) + +set(JSONCPP_INCLUDE_DIRS ${JSONCPP_INCLUDE_DIR}) +set(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + JSONCPP_LIBRARY_DEBUG + NAMES jsoncppd + DOC "jsoncpp debug library" + ) + + set(JSONCPP_LIBRARIES optimized ${JSONCPP_LIBRARIES} debug ${JSONCPP_LIBRARY_DEBUG}) + +endif() + +# handle the QUIETLY and REQUIRED arguments and set JSONCPP_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(jsoncpp DEFAULT_MSG + JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY) +mark_as_advanced (JSONCPP_INCLUDE_DIR JSONCPP_LIBRARY) + diff --git a/cmake/FindLevelDB.cmake b/cmake/FindLevelDB.cmake new file mode 100644 index 000000000..b1a9a5815 --- /dev/null +++ b/cmake/FindLevelDB.cmake @@ -0,0 +1,48 @@ +# Find leveldb +# +# Find the leveldb includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# LEVELDB_INCLUDE_DIRS, where to find header, etc. +# LEVELDB_LIBRARIES, the libraries needed to use leveldb. +# LEVELDB_FOUND, If false, do not try to use leveldb. + +# only look in default directories +find_path( + LEVELDB_INCLUDE_DIR + NAMES leveldb/db.h + DOC "leveldb include dir" +) + +find_library( + LEVELDB_LIBRARY + NAMES leveldb + DOC "leveldb library" +) + +set(LEVELDB_INCLUDE_DIRS ${LEVELDB_INCLUDE_DIR}) +set(LEVELDB_LIBRARIES ${LEVELDB_LIBRARY}) + +# debug library on windows +# same naming convention as in qt (appending debug library with d) +# boost is using the same "hack" as us with "optimized" and "debug" +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + find_library( + LEVELDB_LIBRARY_DEBUG + NAMES leveldbd + DOC "leveldb debug library" + ) + + set(LEVELDB_LIBRARIES optimized ${LEVELDB_LIBRARIES} debug ${LEVELDB_LIBRARY_DEBUG}) + +endif() + +# handle the QUIETLY and REQUIRED arguments and set LEVELDB_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(leveldb DEFAULT_MSG + LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) +mark_as_advanced (LEVELDB_INCLUDE_DIR LEVELDB_LIBRARY) + diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake new file mode 100644 index 000000000..1438a8526 --- /dev/null +++ b/cmake/FindMiniupnpc.cmake @@ -0,0 +1,34 @@ +# Find miniupnpc +# +# Find the miniupnpc includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# MINIUPNPC_INCLUDE_DIRS, where to find header, etc. +# MINIUPNPC_LIBRARIES, the libraries needed to use gmp. +# MINIUPNPC_FOUND, If false, do not try to use gmp. + +# only look in default directories +find_path( + MINIUPNPC_INCLUDE_DIR + NAMES miniupnpc/miniupnpc.h + DOC "miniupnpc include dir" + ) + +find_library( + MINIUPNPC_LIBRARY + NAMES miniupnpc + DOC "miniupnpc library" + ) + +set(MINIUPNPC_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR}) +set(MINIUPNPC_LIBRARIES ${MINIUPNPC_LIBRARY}) + +# handle the QUIETLY and REQUIRED arguments and set MINIUPNPC_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(miniupnpc DEFAULT_MSG + MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) +mark_as_advanced (MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) + diff --git a/cmake/FindReadline.cmake b/cmake/FindReadline.cmake new file mode 100644 index 000000000..c1cdfd33a --- /dev/null +++ b/cmake/FindReadline.cmake @@ -0,0 +1,34 @@ +# Find readline +# +# Find the readline includes and library +# +# if you nee to add a custom library search path, do it via via CMAKE_PREFIX_PATH +# +# This module defines +# READLINE_INCLUDE_DIRS, where to find header, etc. +# READLINE_LIBRARIES, the libraries needed to use readline. +# READLINE_FOUND, If false, do not try to use readline. + +# only look in default directories +find_path( + READLINE_INCLUDE_DIR + NAMES readline/readline.h + DOC "readling include dir" + ) + +find_library( + READLINE_LIBRARY + NAMES readline + DOC "readline library" + ) + +set(READLINE_INCLUDE_DIRS ${READLINE_INCLUDE_DIR}) +set(READLINE_LIBRARIES ${READLINE_LIBRARY}) + +# handle the QUIETLY and REQUIRED arguments and set READLINE_FOUND to TRUE +# if all listed variables are TRUE, hide their existence from configuration view +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(readline DEFAULT_MSG + READLINE_INCLUDE_DIR READLINE_LIBRARY) +mark_as_advanced (READLINE_INCLUDE_DIR READLINE_LIBRARY) + diff --git a/docker/Dockerfile b/docker/Dockerfile index 1bd690cbb..c183f03b9 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -4,17 +4,30 @@ ENV DEBIAN_FRONTEND noninteractive RUN apt-get update RUN apt-get upgrade -y -RUN apt-get install -qy wget -RUN apt-get install -qy build-essential g++-4.8 automake libtool unzip git cmake -RUN apt-get install -qy libncurses5-dev libgmp-dev libgmp3-dev libboost-all-dev libleveldb-dev yasm libminiupnpc-dev -RUN apt-get install -qy qtbase5-dev qt5-default qtdeclarative5-dev libqt5webkit5-dev +# Ethereum dependencies +RUN apt-get install -qy build-essential g++-4.8 git cmake libboost-all-dev libcurl4-openssl-dev wget +RUN apt-get install -qy automake unzip libgmp-dev libtool libleveldb-dev yasm libminiupnpc-dev libreadline-dev scons -RUN mkdir /cryptopp562 -RUN cd /cryptopp562 && wget http://www.cryptopp.com/cryptopp562.zip && unzip cryptopp562.zip -RUN cd /cryptopp562 && make -j $(cat /proc/cpuinfo | grep processor | wc -l) && make install +# NCurses based GUI (not optional though for a succesful compilation, see https://github.com/ethereum/cpp-ethereum/issues/452 ) +RUN apt-get install -qy libncurses5-dev +# Qt-based GUI +# RUN apt-get install -qy qtbase5-dev qt5-default qtdeclarative5-dev libqt5webkit5-dev + +# Cryptopp +RUN git clone --depth=1 https://github.com/mmoss/cryptopp.git +RUN cd cryptopp && scons --shared --prefix=/usr + +# JSONRPC (version 0.2.1, see https://github.com/ethereum/cpp-ethereum/issues/453 ) +RUN apt-get install -qy libjsoncpp-dev libargtable2-dev +RUN git clone --depth=1 --branch=0.2.1 https://github.com/cinemast/libjson-rpc-cpp.git +RUN mkdir -p libjson-rpc-cpp/build +RUN cd libjson-rpc-cpp/build && cmake .. && make && make install + +# Build Ethereum (HEADLESS) RUN git clone --depth=1 https://github.com/ethereum/cpp-ethereum -RUN mkdir cpp-ethereum/build -RUN cd cpp-ethereum/build && cmake .. -DCMAKE_BUILD_TYPE=Release && make -j $(cat /proc/cpuinfo | grep processor | wc -l) && make install +RUN mkdir -p cpp-ethereum/build +RUN cd cpp-ethereum/build && cmake .. -DCMAKE_BUILD_TYPE=Release -DHEADLESS=1 && make -j $(cat /proc/cpuinfo | grep processor | wc -l) && make install +RUN ldconfig ENTRYPOINT ["/usr/local/bin/eth"] diff --git a/eth/BigInteger.js b/eth/BigInteger.js deleted file mode 100644 index e4a9d1c7b..000000000 --- a/eth/BigInteger.js +++ /dev/null @@ -1,379 +0,0 @@ -var bigInt = (function () { - var base = 10000000, logBase = 7; - var sign = { - positive: false, - negative: true - }; - - var normalize = function (first, second) { - var a = first.value, b = second.value; - var length = a.length > b.length ? a.length : b.length; - for (var i = 0; i < length; i++) { - a[i] = a[i] || 0; - b[i] = b[i] || 0; - } - for (var i = length - 1; i >= 0; i--) { - if (a[i] === 0 && b[i] === 0) { - a.pop(); - b.pop(); - } else break; - } - if (!a.length) a = [0], b = [0]; - first.value = a; - second.value = b; - }; - - var parse = function (text, first) { - if (typeof text === "object") return text; - text += ""; - var s = sign.positive, value = []; - if (text[0] === "-") { - s = sign.negative; - text = text.slice(1); - } - var base = 10; - if (text.slice(0, 2) == "0x") { - base = 16; - text = text.slice(2); - } - else { - var texts = text.split("e"); - if (texts.length > 2) throw new Error("Invalid integer"); - if (texts[1]) { - var exp = texts[1]; - if (exp[0] === "+") exp = exp.slice(1); - exp = parse(exp); - if (exp.lesser(0)) throw new Error("Cannot include negative exponent part for integers"); - while (exp.notEquals(0)) { - texts[0] += "0"; - exp = exp.prev(); - } - } - text = texts[0]; - } - if (text === "-0") text = "0"; - text = text.toUpperCase(); - var isValid = (base == 16 ? /^[0-9A-F]*$/ : /^[0-9]+$/).test(text); - if (!isValid) throw new Error("Invalid integer"); - if (base == 16) { - var val = bigInt(0); - while (text.length) { - v = text.charCodeAt(0) - 48; - if (v > 9) - v -= 7; - text = text.slice(1); - val = val.times(16).plus(v); - } - return val; - } - else { - while (text.length) { - var divider = text.length > logBase ? text.length - logBase : 0; - value.push(+text.slice(divider)); - text = text.slice(0, divider); - } - var val = bigInt(value, s); - if (first) normalize(first, val); - return val; - } - }; - - var goesInto = function (a, b) { - var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive); - if (a.equals(0)) throw new Error("Cannot divide by 0"); - var n = 0; - do { - var inc = 1; - var c = bigInt(a.value, sign.positive), t = c.times(10); - while (t.lesser(b)) { - c = t; - inc *= 10; - t = t.times(10); - } - while (c.lesserOrEquals(b)) { - b = b.minus(c); - n += inc; - } - } while (a.lesserOrEquals(b)); - - return { - remainder: b.value, - result: n - }; - }; - - var bigInt = function (value, s) { - var self = { - value: value, - sign: s - }; - var o = { - value: value, - sign: s, - negate: function (m) { - var first = m || self; - return bigInt(first.value, !first.sign); - }, - abs: function (m) { - var first = m || self; - return bigInt(first.value, sign.positive); - }, - add: function (n, m) { - var s, first = self, second; - if (m) (first = parse(n)) && (second = parse(m)); - else second = parse(n, first); - s = first.sign; - if (first.sign !== second.sign) { - first = bigInt(first.value, sign.positive); - second = bigInt(second.value, sign.positive); - return s === sign.positive ? - o.subtract(first, second) : - o.subtract(second, first); - } - normalize(first, second); - var a = first.value, b = second.value; - var result = [], - carry = 0; - for (var i = 0; i < a.length || carry > 0; i++) { - var sum = (a[i] || 0) + (b[i] || 0) + carry; - carry = sum >= base ? 1 : 0; - sum -= carry * base; - result.push(sum); - } - return bigInt(result, s); - }, - plus: function (n, m) { - return o.add(n, m); - }, - subtract: function (n, m) { - var first = self, second; - if (m) (first = parse(n)) && (second = parse(m)); - else second = parse(n, first); - if (first.sign !== second.sign) return o.add(first, o.negate(second)); - if (first.sign === sign.negative) return o.subtract(o.negate(second), o.negate(first)); - if (o.compare(first, second) === -1) return o.negate(o.subtract(second, first)); - var a = first.value, b = second.value; - var result = [], - borrow = 0; - for (var i = 0; i < a.length; i++) { - var tmp = a[i] - borrow; - borrow = tmp < b[i] ? 1 : 0; - var minuend = (borrow * base) + tmp - b[i]; - result.push(minuend); - } - return bigInt(result, sign.positive); - }, - minus: function (n, m) { - return o.subtract(n, m); - }, - multiply: function (n, m) { - var s, first = self, second; - if (m) (first = parse(n)) && (second = parse(m)); - else second = parse(n, first); - s = first.sign !== second.sign; - var a = first.value, b = second.value; - var resultSum = []; - for (var i = 0; i < a.length; i++) { - resultSum[i] = []; - var j = i; - while (j--) { - resultSum[i].push(0); - } - } - var carry = 0; - for (var i = 0; i < a.length; i++) { - var x = a[i]; - for (var j = 0; j < b.length || carry > 0; j++) { - var y = b[j]; - var product = y ? (x * y) + carry : carry; - carry = product > base ? Math.floor(product / base) : 0; - product -= carry * base; - resultSum[i].push(product); - } - } - var max = -1; - for (var i = 0; i < resultSum.length; i++) { - var len = resultSum[i].length; - if (len > max) max = len; - } - var result = [], carry = 0; - for (var i = 0; i < max || carry > 0; i++) { - var sum = carry; - for (var j = 0; j < resultSum.length; j++) { - sum += resultSum[j][i] || 0; - } - carry = sum > base ? Math.floor(sum / base) : 0; - sum -= carry * base; - result.push(sum); - } - return bigInt(result, s); - }, - times: function (n, m) { - return o.multiply(n, m); - }, - divmod: function (n, m) { - var s, first = self, second; - if (m) (first = parse(n)) && (second = parse(m)); - else second = parse(n, first); - s = first.sign !== second.sign; - if (bigInt(first.value, first.sign).equals(0)) return { - quotient: bigInt([0], sign.positive), - remainder: bigInt([0], sign.positive) - }; - if (second.equals(0)) throw new Error("Cannot divide by zero"); - var a = first.value, b = second.value; - var result = [], remainder = []; - for (var i = a.length - 1; i >= 0; i--) { - var n = [a[i]].concat(remainder); - var quotient = goesInto(b, n); - result.push(quotient.result); - remainder = quotient.remainder; - } - result.reverse(); - return { - quotient: bigInt(result, s), - remainder: bigInt(remainder, first.sign) - }; - }, - divide: function (n, m) { - return o.divmod(n, m).quotient; - }, - over: function (n, m) { - return o.divide(n, m); - }, - mod: function (n, m) { - return o.divmod(n, m).remainder; - }, - pow: function (n, m) { - var first = self, second; - if (m) (first = parse(n)) && (second = parse(m)); - else second = parse(n, first); - var a = first, b = second; - if (b.lesser(0)) return ZERO; - if (b.equals(0)) return ONE; - var result = bigInt(a.value, a.sign); - - if (b.mod(2).equals(0)) { - var c = result.pow(b.over(2)); - return c.times(c); - } else { - return result.times(result.pow(b.minus(1))); - } - }, - next: function (m) { - var first = m || self; - return o.add(first, 1); - }, - prev: function (m) { - var first = m || self; - return o.subtract(first, 1); - }, - compare: function (n, m) { - var first = self, second; - if (m) (first = parse(n)) && (second = parse(m, first)); - else second = parse(n, first); - normalize(first, second); - if (first.value.length === 1 && second.value.length === 1 && first.value[0] === 0 && second.value[0] === 0) return 0; - if (second.sign !== first.sign) return first.sign === sign.positive ? 1 : -1; - var multiplier = first.sign === sign.positive ? 1 : -1; - var a = first.value, b = second.value; - for (var i = a.length - 1; i >= 0; i--) { - if (a[i] > b[i]) return 1 * multiplier; - if (b[i] > a[i]) return -1 * multiplier; - } - return 0; - }, - compareAbs: function (n, m) { - var first = self, second; - if (m) (first = parse(n)) && (second = parse(m, first)); - else second = parse(n, first); - first.sign = second.sign = sign.positive; - return o.compare(first, second); - }, - equals: function (n, m) { - return o.compare(n, m) === 0; - }, - notEquals: function (n, m) { - return !o.equals(n, m); - }, - lesser: function (n, m) { - return o.compare(n, m) < 0; - }, - greater: function (n, m) { - return o.compare(n, m) > 0; - }, - greaterOrEquals: function (n, m) { - return o.compare(n, m) >= 0; - }, - lesserOrEquals: function (n, m) { - return o.compare(n, m) <= 0; - }, - isPositive: function (m) { - var first = m || self; - return first.sign === sign.positive; - }, - isNegative: function (m) { - var first = m || self; - return first.sign === sign.negative; - }, - isEven: function (m) { - var first = m || self; - return first.value[0] % 2 === 0; - }, - isOdd: function (m) { - var first = m || self; - return first.value[0] % 2 === 1; - }, - toString: function (m) { - var first = m || self; - var str = "", len = first.value.length; - while (len--) { - if (first.value[len].toString().length === 8) str += first.value[len]; - else str += (base.toString() + first.value[len]).slice(-logBase); - } - while (str[0] === "0") { - str = str.slice(1); - } - if (!str.length) str = "0"; - var s = (first.sign === sign.positive || str == "0") ? "" : "-"; - return s + str; - }, - toHex: function (m) { - var first = m || self; - var str = ""; - var l = this.abs(); - while (l > 0) { - var qr = l.divmod(256); - var b = qr.remainder.toJSNumber(); - str = (b >> 4).toString(16) + (b & 15).toString(16) + str; - l = qr.quotient; - } - return (this.isNegative() ? "-" : "") + "0x" + str; - }, - toJSNumber: function (m) { - return +o.toString(m); - }, - valueOf: function (m) { - return o.toJSNumber(m); - } - }; - return o; - }; - - var ZERO = bigInt([0], sign.positive); - var ONE = bigInt([1], sign.positive); - var MINUS_ONE = bigInt([1], sign.negative); - - var fnReturn = function (a) { - if (typeof a === "undefined") return ZERO; - return parse(a); - }; - fnReturn.zero = ZERO; - fnReturn.one = ONE; - fnReturn.minusOne = MINUS_ONE; - return fnReturn; -})(); - -if (typeof module !== "undefined") { - module.exports = bigInt; -} diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index eee1d258b..c98f3cbec 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -1,49 +1,33 @@ cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) aux_source_directory(. SRC_LIST) +include_directories(${Boost_INCLUDE_DIRS}) +include_directories(${JSON_RPC_CPP_INCLUDE_DIRS}) include_directories(..) -link_directories(../libethcore) -link_directories(../libwebthree) set(EXECUTABLE eth) -add_executable(${EXECUTABLE} ${SRC_LIST}) +file(GLOB HEADERS "*.h") -target_link_libraries(${EXECUTABLE} webthree) -target_link_libraries(${EXECUTABLE} secp256k1) -target_link_libraries(${EXECUTABLE} gmp) -if(MINIUPNPC_LS) - target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) -endif() -target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) -if(JSONRPC_LS) -target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) +add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) + +add_dependencies(${EXECUTABLE} BuildInfo.h) + +target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES}) +target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES}) + +if (READLINE_FOUND) + target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES}) endif() -if(READLINE_LS) -target_link_libraries(${EXECUTABLE} ${READLINE_LS}) + +if (JSONRPC) + target_link_libraries(${EXECUTABLE} web3jsonrpc) endif() -if ("${TARGET_PLATFORM}" STREQUAL "w64") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") - target_link_libraries(${EXECUTABLE} boost_system-mt-s) - target_link_libraries(${EXECUTABLE} boost_filesystem-mt-s) - target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s) - target_link_libraries(${EXECUTABLE} gcc) - target_link_libraries(${EXECUTABLE} gdi32) - target_link_libraries(${EXECUTABLE} ws2_32) - target_link_libraries(${EXECUTABLE} mswsock) - target_link_libraries(${EXECUTABLE} shlwapi) - target_link_libraries(${EXECUTABLE} iphlpapi) - set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) -elseif (UNIX) -else () - target_link_libraries(${EXECUTABLE} boost_system) - target_link_libraries(${EXECUTABLE} boost_filesystem) - find_package(Threads REQUIRED) - target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) -endif () +target_link_libraries(${EXECUTABLE} webthree) +target_link_libraries(${EXECUTABLE} secp256k1) install( TARGETS ${EXECUTABLE} DESTINATION bin ) diff --git a/eth/CommonJS.cpp b/eth/CommonJS.cpp deleted file mode 100644 index 57958a117..000000000 --- a/eth/CommonJS.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file CommonJS.cpp - * @authors: - * Gav Wood - * @date 2014 - */ - -#include "CommonJS.h" -using namespace std; -using namespace dev; -using namespace dev::eth; - -bytes dev::eth::jsToBytes(string const& _s) -{ - if (_s.substr(0, 2) == "0x") - // Hex - return fromHex(_s.substr(2)); - else if (_s.find_first_not_of("0123456789") == string::npos) - // Decimal - return toCompactBigEndian(bigint(_s)); - else - // Binary - return asBytes(_s); -} - -string dev::eth::jsPadded(string const& _s, unsigned _l, unsigned _r) -{ - bytes b = jsToBytes(_s); - while (b.size() < _l) - b.insert(b.begin(), 0); - while (b.size() < _r) - b.push_back(0); - return asString(b).substr(b.size() - max(_l, _r)); -} - -string dev::eth::jsPadded(string const& _s, unsigned _l) -{ - if (_s.substr(0, 2) == "0x" || _s.find_first_not_of("0123456789") == string::npos) - // Numeric: pad to right - return jsPadded(_s, _l, _l); - else - // Text: pad to the left - return jsPadded(_s, 0, _l); -} - -string dev::eth::jsUnpadded(string _s) -{ - auto p = _s.find_last_not_of((char)0); - _s.resize(p == string::npos ? 0 : (p + 1)); - return _s; -} diff --git a/eth/EthStubServer.cpp b/eth/EthStubServer.cpp deleted file mode 100644 index ad6a87781..000000000 --- a/eth/EthStubServer.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file EthStubServer.cpp - * @authors: - * Gav Wood - * @date 2014 - */ - -#if ETH_JSONRPC -#include "EthStubServer.h" -#include -#include -#include -#include -#include "CommonJS.h" -using namespace std; -using namespace dev; -using namespace dev::eth; - -EthStubServer::EthStubServer(jsonrpc::AbstractServerConnector* _conn, WebThreeDirect& _web3): - AbstractEthStubServer(_conn), - m_web3(_web3) -{ -} - -//only works with a json spec that doesn't have notifications for now -Json::Value EthStubServer::procedures() -{ - Json::Value ret; - - for (auto proc: this->GetProtocolHanlder()->GetProcedures()) - { - Json::Value proc_j; - - proc_j[proc.second->GetProcedureType() == 0 ? "method" : "notification"] = proc.first; - - Json::Value params_j; - for (auto params: proc.second->GetParameters()) - params_j[params.first] = jsontypeToValue(params.second); - proc_j["params"] = params_j; - - proc_j["returns"] = jsontypeToValue(proc.second->GetReturnType()); - - ret.append(proc_j); - } - return ret; -} - -dev::eth::Client& EthStubServer::ethereum() const -{ - return *m_web3.ethereum(); -} - -std::string EthStubServer::coinbase() -{ - return toJS(ethereum().address()); -} - -std::string EthStubServer::balanceAt(std::string const& _a) -{ - return toJS(ethereum().balanceAt(jsToAddress(_a), 0)); -} - -Json::Value EthStubServer::check(Json::Value const& _as) -{ - // TODO -// if (ethereum().changed()) - return _as; -/* else - { - Json::Value ret; - ret.resize(0); - return ret; - }*/ -} - -std::string EthStubServer::create(const std::string& _bCode, const std::string& _sec, const std::string& _xEndowment, const std::string& _xGas, const std::string& _xGasPrice) -{ - Address ret = ethereum().transact(jsToSecret(_sec), jsToU256(_xEndowment), jsToBytes(_bCode), jsToU256(_xGas), jsToU256(_xGasPrice)); - return toJS(ret); -} - -std::string EthStubServer::lll(const std::string& _s) -{ - return "0x" + toHex(dev::eth::compileLLL(_s)); -} - -std::string EthStubServer::gasPrice() -{ - return "100000000000000"; -} - -bool EthStubServer::isContractAt(const std::string& _a) -{ - return ethereum().codeAt(jsToAddress(_a), 0).size(); -} - -bool EthStubServer::isListening() -{ - return m_web3.haveNetwork(); -} - -bool EthStubServer::isMining() -{ - return ethereum().isMining(); -} - -std::string EthStubServer::key() -{ - if (!m_keys.size()) - return std::string(); - return toJS(m_keys[0].sec()); -} - -Json::Value EthStubServer::keys() -{ - Json::Value ret; - for (auto i: m_keys) - ret.append(toJS(i.secret())); - return ret; -} - -int EthStubServer::peerCount() -{ - return m_web3.peerCount(); -} - -std::string EthStubServer::storageAt(const std::string& _a, const std::string& x) -{ - return toJS(ethereum().stateAt(jsToAddress(_a), jsToU256(x), 0)); -} - -std::string EthStubServer::stateAt(const std::string& _a, const std::string& x, const std::string& s) -{ - return toJS(ethereum().stateAt(jsToAddress(_a), jsToU256(x), std::atol(s.c_str()))); -} - -Json::Value EthStubServer::transact(const std::string& _aDest, const std::string& _bData, const std::string& _sec, const std::string& _xGas, const std::string& _xGasPrice, const std::string& _xValue) -{ - ethereum().transact(jsToSecret(_sec), jsToU256(_xValue), jsToAddress(_aDest), jsToBytes(_bData), jsToU256(_xGas), jsToU256(_xGasPrice)); - return Json::Value(); -} - -std::string EthStubServer::txCountAt(const std::string& _a) -{ - return toJS(ethereum().countAt(jsToAddress(_a), 0)); -} - -std::string EthStubServer::secretToAddress(const std::string& _a) -{ - return toJS(KeyPair(jsToSecret(_a)).address()); -} - -Json::Value EthStubServer::lastBlock() -{ - return blockJson(""); -} - -Json::Value EthStubServer::block(const std::string& _hash) -{ - return blockJson(_hash); -} - -Json::Value EthStubServer::blockJson(const std::string& _hash) -{ - Json::Value res; - auto const& bc = ethereum().blockChain(); - - auto b = _hash.length() ? bc.block(h256(_hash)) : bc.block(); - - auto bi = BlockInfo(b); - res["number"] = boost::lexical_cast(bi.number); - res["hash"] = boost::lexical_cast(bi.hash); - res["parentHash"] = boost::lexical_cast(bi.parentHash); - res["sha3Uncles"] = boost::lexical_cast(bi.sha3Uncles); - res["coinbaseAddress"] = boost::lexical_cast(bi.coinbaseAddress); - res["stateRoot"] = boost::lexical_cast(bi.stateRoot); - res["transactionsRoot"] = boost::lexical_cast(bi.transactionsRoot); - res["minGasPrice"] = boost::lexical_cast(bi.minGasPrice); - res["gasLimit"] = boost::lexical_cast(bi.gasLimit); - res["gasUsed"] = boost::lexical_cast(bi.gasUsed); - res["difficulty"] = boost::lexical_cast(bi.difficulty); - res["timestamp"] = boost::lexical_cast(bi.timestamp); - res["nonce"] = boost::lexical_cast(bi.nonce); - - return res; -} - -Json::Value EthStubServer::jsontypeToValue(int _jsontype) -{ - switch (_jsontype) - { - case jsonrpc::JSON_STRING: return ""; //Json::stringValue segfault, fuck knows why - case jsonrpc::JSON_BOOLEAN: return Json::booleanValue; - case jsonrpc::JSON_INTEGER: return Json::intValue; - case jsonrpc::JSON_REAL: return Json::realValue; - case jsonrpc::JSON_OBJECT: return Json::objectValue; - case jsonrpc::JSON_ARRAY: return Json::arrayValue; - default: return Json::nullValue; - } -} - -#endif diff --git a/eth/EthStubServer.h b/eth/EthStubServer.h deleted file mode 100644 index 469abed07..000000000 --- a/eth/EthStubServer.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - This file is part of cpp-ethereum. - - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . -*/ -/** @file EthStubServer.h - * @author Gav Wood - * @date 2014 - */ - -#pragma once - -#include -#include -#include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-parameter" -#include "abstractethstubserver.h" -#pragma GCC diagnostic pop - -namespace dev { class WebThreeDirect; namespace eth { class Client; } class KeyPair; } - -class EthStubServer: public AbstractEthStubServer -{ -public: - EthStubServer(jsonrpc::AbstractServerConnector* _conn, dev::WebThreeDirect& _web3); - - virtual Json::Value procedures(); - virtual std::string balanceAt(std::string const& _a); - virtual Json::Value check(Json::Value const& _as); - virtual std::string coinbase(); - virtual std::string create(const std::string& bCode, const std::string& sec, const std::string& xEndowment, const std::string& xGas, const std::string& xGasPrice); - virtual std::string gasPrice(); - virtual bool isContractAt(const std::string& a); - virtual bool isListening(); - virtual bool isMining(); - virtual std::string key(); - virtual Json::Value keys(); - virtual int peerCount(); - virtual std::string storageAt(const std::string& a, const std::string& x); - virtual std::string stateAt(const std::string& a, const std::string& x, const std::string& s); - virtual Json::Value transact(const std::string& aDest, const std::string& bData, const std::string& sec, const std::string& xGas, const std::string& xGasPrice, const std::string& xValue); - virtual std::string txCountAt(const std::string& a); - virtual std::string secretToAddress(const std::string& a); - virtual Json::Value lastBlock(); - virtual std::string lll(const std::string& s); - virtual Json::Value block(const std::string&); - void setKeys(std::vector _keys) { m_keys = _keys; } -private: - dev::eth::Client& ethereum() const; - dev::WebThreeDirect& m_web3; - std::vector m_keys; - Json::Value jsontypeToValue(int); - Json::Value blockJson(const std::string&); -}; diff --git a/eth/abstractethstubserver.h b/eth/abstractethstubserver.h deleted file mode 100644 index 7f110513d..000000000 --- a/eth/abstractethstubserver.h +++ /dev/null @@ -1,162 +0,0 @@ -/** - * THIS FILE IS GENERATED BY jsonrpcstub, DO NOT CHANGE IT!!!!! - */ - -#ifndef _ABSTRACTETHSTUBSERVER_H_ -#define _ABSTRACTETHSTUBSERVER_H_ - -#include - -class AbstractEthStubServer : public jsonrpc::AbstractServer -{ - public: - AbstractEthStubServer(jsonrpc::AbstractServerConnector* conn) : - jsonrpc::AbstractServer(conn) - { - this->bindAndAddMethod(new jsonrpc::Procedure("balanceAt", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "a",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::balanceAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("block", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "a",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::blockI); - this->bindAndAddMethod(new jsonrpc::Procedure("check", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_ARRAY, "a",jsonrpc::JSON_ARRAY, NULL), &AbstractEthStubServer::checkI); - this->bindAndAddMethod(new jsonrpc::Procedure("coinbase", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::coinbaseI); - this->bindAndAddMethod(new jsonrpc::Procedure("create", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "bCode",jsonrpc::JSON_STRING,"sec",jsonrpc::JSON_STRING,"xEndowment",jsonrpc::JSON_STRING,"xGas",jsonrpc::JSON_STRING,"xGasPrice",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::createI); - this->bindAndAddMethod(new jsonrpc::Procedure("gasPrice", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::gasPriceI); - this->bindAndAddMethod(new jsonrpc::Procedure("isContractAt", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_BOOLEAN, "a",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::isContractAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("isListening", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_BOOLEAN, NULL), &AbstractEthStubServer::isListeningI); - this->bindAndAddMethod(new jsonrpc::Procedure("isMining", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_BOOLEAN, NULL), &AbstractEthStubServer::isMiningI); - this->bindAndAddMethod(new jsonrpc::Procedure("key", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::keyI); - this->bindAndAddMethod(new jsonrpc::Procedure("keys", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_ARRAY, NULL), &AbstractEthStubServer::keysI); - this->bindAndAddMethod(new jsonrpc::Procedure("lastBlock", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, NULL), &AbstractEthStubServer::lastBlockI); - this->bindAndAddMethod(new jsonrpc::Procedure("lll", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "s",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::lllI); - this->bindAndAddMethod(new jsonrpc::Procedure("peerCount", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_INTEGER, NULL), &AbstractEthStubServer::peerCountI); - this->bindAndAddMethod(new jsonrpc::Procedure("procedures", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_ARRAY, NULL), &AbstractEthStubServer::proceduresI); - this->bindAndAddMethod(new jsonrpc::Procedure("secretToAddress", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "a",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::secretToAddressI); - this->bindAndAddMethod(new jsonrpc::Procedure("storageAt", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "a",jsonrpc::JSON_STRING,"x",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::storageAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("stateAt", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "a",jsonrpc::JSON_STRING,"x",jsonrpc::JSON_STRING,"s",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::stateAtI); - this->bindAndAddMethod(new jsonrpc::Procedure("transact", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_OBJECT, "aDest",jsonrpc::JSON_STRING,"bData",jsonrpc::JSON_STRING,"sec",jsonrpc::JSON_STRING,"xGas",jsonrpc::JSON_STRING,"xGasPrice",jsonrpc::JSON_STRING,"xValue",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::transactI); - this->bindAndAddMethod(new jsonrpc::Procedure("txCountAt", jsonrpc::PARAMS_BY_NAME, jsonrpc::JSON_STRING, "a",jsonrpc::JSON_STRING, NULL), &AbstractEthStubServer::txCountAtI); - - } - - inline virtual void balanceAtI(const Json::Value& request, Json::Value& response) - { - response = this->balanceAt(request["a"].asString()); - } - - inline virtual void blockI(const Json::Value& request, Json::Value& response) - { - response = this->block(request["a"].asString()); - } - - inline virtual void checkI(const Json::Value& request, Json::Value& response) - { - response = this->check(request["a"]); - } - - inline virtual void coinbaseI(const Json::Value& request, Json::Value& response) - { - response = this->coinbase(); - } - - inline virtual void createI(const Json::Value& request, Json::Value& response) - { - response = this->create(request["bCode"].asString(), request["sec"].asString(), request["xEndowment"].asString(), request["xGas"].asString(), request["xGasPrice"].asString()); - } - - inline virtual void gasPriceI(const Json::Value& request, Json::Value& response) - { - response = this->gasPrice(); - } - - inline virtual void isContractAtI(const Json::Value& request, Json::Value& response) - { - response = this->isContractAt(request["a"].asString()); - } - - inline virtual void isListeningI(const Json::Value& request, Json::Value& response) - { - response = this->isListening(); - } - - inline virtual void isMiningI(const Json::Value& request, Json::Value& response) - { - response = this->isMining(); - } - - inline virtual void keyI(const Json::Value& request, Json::Value& response) - { - response = this->key(); - } - - inline virtual void keysI(const Json::Value& request, Json::Value& response) - { - response = this->keys(); - } - - inline virtual void lastBlockI(const Json::Value& request, Json::Value& response) - { - response = this->lastBlock(); - } - - inline virtual void lllI(const Json::Value& request, Json::Value& response) - { - response = this->lll(request["s"].asString()); - } - - inline virtual void peerCountI(const Json::Value& request, Json::Value& response) - { - response = this->peerCount(); - } - - inline virtual void proceduresI(const Json::Value& request, Json::Value& response) - { - response = this->procedures(); - } - - inline virtual void secretToAddressI(const Json::Value& request, Json::Value& response) - { - response = this->secretToAddress(request["a"].asString()); - } - - inline virtual void storageAtI(const Json::Value& request, Json::Value& response) - { - response = this->storageAt(request["a"].asString(), request["x"].asString()); - } - - inline virtual void stateAtI(const Json::Value& request, Json::Value& response) - { - response = this->stateAt(request["a"].asString(), request["x"].asString(), request["s"].asString()); - } - - inline virtual void transactI(const Json::Value& request, Json::Value& response) - { - response = this->transact(request["aDest"].asString(), request["bData"].asString(), request["sec"].asString(), request["xGas"].asString(), request["xGasPrice"].asString(), request["xValue"].asString()); - } - - inline virtual void txCountAtI(const Json::Value& request, Json::Value& response) - { - response = this->txCountAt(request["a"].asString()); - } - - - virtual std::string balanceAt(const std::string& a) = 0; - virtual Json::Value block(const std::string& a) = 0; - virtual Json::Value check(const Json::Value& a) = 0; - virtual std::string coinbase() = 0; - virtual std::string create(const std::string& bCode, const std::string& sec, const std::string& xEndowment, const std::string& xGas, const std::string& xGasPrice) = 0; - virtual std::string gasPrice() = 0; - virtual bool isContractAt(const std::string& a) = 0; - virtual bool isListening() = 0; - virtual bool isMining() = 0; - virtual std::string key() = 0; - virtual Json::Value keys() = 0; - virtual Json::Value lastBlock() = 0; - virtual std::string lll(const std::string& s) = 0; - virtual int peerCount() = 0; - virtual Json::Value procedures() = 0; - virtual std::string secretToAddress(const std::string& a) = 0; - virtual std::string storageAt(const std::string& a, const std::string& x) = 0; - virtual std::string stateAt(const std::string& a, const std::string& x, const std::string& b) = 0; - virtual Json::Value transact(const std::string& aDest, const std::string& bData, const std::string& sec, const std::string& xGas, const std::string& xGasPrice, const std::string& xValue) = 0; - virtual std::string txCountAt(const std::string& a) = 0; - -}; -#endif //_ABSTRACTETHSTUBSERVER_H_ diff --git a/eth/eth.js b/eth/eth.js deleted file mode 100644 index 791386a0b..000000000 --- a/eth/eth.js +++ /dev/null @@ -1,137 +0,0 @@ -if (typeof(window.eth) === "undefined") -{ -if (typeof(require) !== "undefined") - require( ['ethString'], function() {} ) -else if (typeof(String.prototype.pad) === "undefined") -{ - var scriptTag = document.getElementsByTagName('script'); - scriptTag = scriptTag[scriptTag.length - 1]; - var scriptPath = scriptTag.src; - var path = scriptPath.substr(0, scriptPath.lastIndexOf( '/' )); - var start = '