Browse Source

Merge branch 'develop'

cl-refactor
Gav Wood 10 years ago
parent
commit
68a2377cdd
  1. 10
      .gitignore
  2. 487
      CMakeLists.txt
  3. 22
      CodingStandards.txt
  4. 0
      EthereumMacOSXBundleInfo.plist.in
  5. 14
      README.md
  6. 131
      alethzero/CMakeLists.txt
  7. 6
      alethzero/DownloadView.cpp
  8. 355
      alethzero/Main.ui
  9. 693
      alethzero/MainWin.cpp
  10. 40
      alethzero/MainWin.h
  11. 28
      alethzero/OurWebThreeStubServer.cpp
  12. 38
      alethzero/OurWebThreeStubServer.h
  13. BIN
      alethzero/alethzero.ico
  14. 1
      alethzero/alethzero.rc
  15. 1
      alethzero/main.cpp
  16. 4
      astylerc
  17. 27
      build.py
  18. 39
      cmake/EthCompilerSettings.cmake
  19. 148
      cmake/EthDependencies.cmake
  20. 152
      cmake/EthExecutableHelper.cmake
  21. 49
      cmake/FindCURL.cmake
  22. 108
      cmake/FindCryptoPP.cmake
  23. 34
      cmake/FindGmp.cmake
  24. 99
      cmake/FindJsonRpcCpp.cmake
  25. 48
      cmake/FindJsoncpp.cmake
  26. 48
      cmake/FindLevelDB.cmake
  27. 34
      cmake/FindMiniupnpc.cmake
  28. 34
      cmake/FindReadline.cmake
  29. 31
      docker/Dockerfile
  30. 379
      eth/BigInteger.js
  31. 52
      eth/CMakeLists.txt
  32. 66
      eth/CommonJS.cpp
  33. 217
      eth/EthStubServer.cpp
  34. 66
      eth/EthStubServer.h
  35. 162
      eth/abstractethstubserver.h
  36. 137
      eth/eth.js
  37. 62
      eth/ethString.js
  38. 150
      eth/main.cpp
  39. 24
      eth/spec.json
  40. 30
      exp/CMakeLists.txt
  41. 90
      exp/main.cpp
  42. 55
      extdep/CMakeLists.txt
  43. 16
      extdep/Readme.md
  44. 9
      extdep/cmake/FindCURL.cmake
  45. 13
      extdep/compile/argtable2.cmake
  46. 19
      extdep/compile/boost.cmake
  47. 33
      extdep/compile/cryptopp.cmake
  48. 29
      extdep/compile/curl.cmake
  49. 17
      extdep/compile/icu.cmake
  50. 16
      extdep/compile/jom.cmake
  51. 40
      extdep/compile/json-rpc-cpp.cmake
  52. 16
      extdep/compile/jsoncpp.cmake
  53. 23
      extdep/compile/leveldb.cmake
  54. 18
      extdep/compile/leveldb_osx.patch
  55. 32
      extdep/compile/qt.cmake
  56. 111
      extdep/compile/qt_configure.bat
  57. 11
      extdep/compile/qt_osx.patch
  58. 2
      extdep/compile/qt_tools.bat
  59. 14
      extdep/compile/snappy.cmake
  60. 74
      extdep/eth_download.cmake
  61. 11
      extdep/miniupnpc.cmake
  62. 29
      extdep/scripts/json-rpc-cpp_osx.sh
  63. 12
      extdep/scripts/leveldb_osx.sh
  64. 8
      extdep/scripts/snappy_osx.sh
  65. 117
      iethxi/CMakeLists.txt
  66. 38
      iethxi/EthereumMacOSXBundleInfo.plist.in
  67. 168
      iethxi/Main.ui
  68. 59
      iethxi/MainWin.cpp
  69. 18
      iethxi/MainWin.h
  70. 5
      iethxi/Resources.qrc
  71. 9
      iethxi/Simple.qml
  72. 9
      iethxi/main.cpp
  73. 8
      libdevcore/All.h
  74. 48
      libdevcore/CMakeLists.txt
  75. 2
      libdevcore/Common.cpp
  76. 45
      libdevcore/Common.h
  77. 30
      libdevcore/CommonData.cpp
  78. 32
      libdevcore/CommonData.h
  79. 4
      libdevcore/CommonIO.cpp
  80. 12
      libdevcore/CommonIO.h
  81. 117
      libdevcore/CommonJS.cpp
  82. 77
      libdevcore/CommonJS.h
  83. 39
      libdevcore/Exceptions.h
  84. 49
      libdevcore/FixedHash.h
  85. 1
      libdevcore/Log.h
  86. 11
      libdevcore/RLP.cpp
  87. 38
      libdevcore/RLP.h
  88. 39
      libdevcore/RangeMask.h
  89. 4
      libdevcore/Worker.cpp
  90. 19
      libdevcore/Worker.h
  91. 10
      libdevcore/_libdevcore.cpp
  92. 121
      libdevcore/debugbreak.h
  93. 1
      libdevcore/vector_ref.h
  94. 60
      libdevcrypto/AES.cpp
  95. 89
      libdevcrypto/AES.h
  96. 9
      libdevcrypto/All.h
  97. 59
      libdevcrypto/CMakeLists.txt
  98. 189
      libdevcrypto/Common.cpp
  99. 78
      libdevcrypto/Common.h
  100. 232
      libdevcrypto/CryptoPP.cpp

10
.gitignore

@ -18,15 +18,23 @@ ipch
*.sdf *.sdf
*.opensdf *.opensdf
*.suo *.suo
*.vcxproj
*.vcxproj.filters
*.sln
#Xcode stuff # VIM stuff
*.swp
# Xcode stuff
build_xc build_xc
*.user *.user
*.user.* *.user.*
*~ *~
# build system
build.*/ build.*/
extdep/install
*.pyc *.pyc

487
CMakeLists.txt

@ -1,384 +1,187 @@
# cmake global # 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) project(ethereum)
cmake_minimum_required(VERSION 2.8.9)
set(CMAKE_AUTOMOC ON)
cmake_policy(SET CMP0015 NEW)
# user defined, defaults list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Normally, set(...CACHE...) creates cache variables, but does not modify them.
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) # user defined, defaults
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") # Normally, set(...CACHE...) creates cache variables, but does not modify them.
add_definitions(-DETH_PARANOIA) function(createDefaultCacheConfig)
else () set(HEADLESS OFF CACHE BOOL "Do not compile GUI (AlethZero)")
message(FATAL_ERROR "Paranoia requires debug.") 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 ()
endif ()
if (VMTRACE) if (VMTRACE)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") if ("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
add_definitions(-DETH_VMTRACE) 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 () else ()
message(FATAL_ERROR "VM tracing requires debug.") set(ETH_BUILD_PLATFORM "${ETH_BUILD_PLATFORM}/unknown")
endif () endif ()
endif ()
message("LANGUAGES: ${LANGUAGES}; VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}")
# Default TARGET_PLATFORM to "linux". #cmake build type may be not specified when using msvc
set(TARGET_PLATFORM CACHE STRING "linux") if (${CMAKE_BUILD_TYPE})
if ("x${TARGET_PLATFORM}" STREQUAL "x") set(_cmake_build_type ${CMAKE_BUILD_TYPE})
set(TARGET_PLATFORM "linux") else()
endif () set(_cmake_build_type "undefined")
endif()
if ("${TARGET_PLATFORM}" STREQUAL "linux") # Generate header file containing useful build information
set(CMAKE_THREAD_LIBS_INIT pthread) 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})
endif () include_directories(${CMAKE_CURRENT_BINARY_DIR})
# Set default build type to Release w/debug info set(CMAKE_INCLUDE_CURRENT_DIR ON)
# if(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) set(SRC_LIST BuildInfo.h)
# set(CMAKE_BUILD_TYPE RelWithDebInfo) endfunction()
# 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 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 set(CMAKE_AUTOMOC ON)
/usr/include cmake_policy(SET CMP0015 NEW)
/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 ()
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 createDefaultCacheConfig()
/usr/include configureProject()
/usr/local/include message("-- VMTRACE: ${VMTRACE}; PARANOIA: ${PARANOIA}; HEADLESS: ${HEADLESS}; JSONRPC: ${JSONRPC}")
)
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 ()
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 # Default TARGET_PLATFORM to "linux".
/usr/include set(TARGET_PLATFORM CACHE STRING "linux")
/usr/local/include if ("x${TARGET_PLATFORM}" STREQUAL "x")
) set(TARGET_PLATFORM "linux")
if ( READLINE_ID ) endif ()
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 ()
if (LANGUAGES) if ("${TARGET_PLATFORM}" STREQUAL "linux")
find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time) set(CMAKE_THREAD_LIBS_INIT pthread)
else() endif ()
find_package(Boost 1.53 REQUIRED COMPONENTS thread date_time system regex)
endif()
set(QTQML 1) include(EthCompilerSettings)
endif() 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 # this must be an include, as a function it would messs up with variable scope!
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(EthDependencies)
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include(EthExecutableHelper)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") createBuildInfo()
link_directories(/usr/local/lib)
include_directories(/usr/local/include)
endif()
add_subdirectory(libdevcore) add_subdirectory(libdevcore)
add_subdirectory(libevmface) add_subdirectory(libevmcore)
add_subdirectory(liblll) add_subdirectory(liblll)
add_subdirectory(libserpent) add_subdirectory(libserpent)
if(NOT APPLE) add_subdirectory(libsolidity)
if(PYTHON_LS)
add_subdirectory(libpyserpent)
endif()
endif()
add_subdirectory(lllc) add_subdirectory(lllc)
add_subdirectory(solc)
add_subdirectory(sc) 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 (JSONRPC)
if ("${TARGET_PLATFORM}" STREQUAL "w64") add_subdirectory(libweb3jsonrpc)
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()
endif() endif()
set(CMAKE_INCLUDE_CURRENT_DIR ON) add_subdirectory(secp256k1)
set(SRC_LIST BuildInfo.h) 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() enable_testing()
add_test(NAME alltests WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth) add_test(NAME alltests WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/test COMMAND testeth)
#unset(TARGET_PLATFORM CACHE) #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)

22
CodingStandards.txt

@ -1,7 +1,7 @@
0. Formatting 0. Formatting
a. Use tabs for indentation! 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. - One indentation level -> exactly one byte (i.e. a tab character) in the source file.
b. Line widths: b. Line widths:
- Don't worry about having lines of code > 80-char wide. - 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. 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. f. No spaces when fewer than intra-expression three parens together; when three or more, space according to clarity.
g. No spaces for subscripting. g. No spaces for subscripting.
h. Space all other operators. h. No space before ':' but one after it, except in the ternary operator: one on both sides.
i. Braces, when used, always have their own lines and are at same indentation level as "parent" scope. i. Space all other operators.
j. Braces, when used, always have their own lines and are at same indentation level as "parent" scope.
(WRONG) (WRONG)
if( a==b[ i ] ) { printf ("Hello\n"); } if( a==b[ i ] ) { printf ("Hello\n"); }
@ -71,8 +72,8 @@ All other entities' first alpha is lower case.
4. Variable prefixes: 4. Variable prefixes:
a. Leading underscore "_" to parameter names (both normal and template). a. Leading underscore "_" to parameter names (both normal and template).
- Exception: "o_parameterName" when it is used exclusively for 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 7(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). b. Leading "c_" to const variables (unless part of an external API).
c. Leading "g_" to global (non-const) variables. c. Leading "g_" to global (non-const) variables.
d. Leading "s_" to static (non-const, non-global) 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. - 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<int>; rather than typedef std::vector<int> ints;
b. Generally avoid shortening a standard form that already includes all important information:
- e.g. stick to shared_ptr<X> rather than shortening to ptr<X>.
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<std::mutex>; ///< 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. a. Comments should be doxygen-compilable, using @notation rather than \notation.

0
alethzero/EthereumMacOSXBundleInfo.plist.in → EthereumMacOSXBundleInfo.plist.in

14
README.md

@ -2,9 +2,13 @@
By Gav Wood, 2014. 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 ### 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). 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
```

131
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) set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST) aux_source_directory(. SRC_LIST)
include_directories(..)
if (APPLE) include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
# Add homebrew path for qt5 include_directories(..)
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)
qt5_wrap_ui(ui_Main.h Main.ui) qt5_wrap_ui(ui_Main.h Main.ui)
# Set name of binary and add_executable() file(GLOB HEADERS "*.h")
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)
if (APPLE) if (APPLE)
# First have qt5 install plugins and frameworks set(EXECUTABLE AlethZero)
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)
else () else ()
target_link_libraries(${EXECUTEABLE} boost_system) set(EXECUTABLE alethzero)
target_link_libraries(${EXECUTEABLE} boost_filesystem)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTEABLE} ${CMAKE_THREAD_LIBS_INIT})
install( TARGETS ${EXECUTEABLE} RUNTIME DESTINATION bin )
endif () 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})

6
alethzero/DownloadView.cpp

@ -45,13 +45,13 @@ void DownloadView::paintEvent(QPaintEvent*)
double ratio = (double)rect().width() / rect().height(); double ratio = (double)rect().width() / rect().height();
if (ratio < 1) if (ratio < 1)
ratio = 1 / ratio; 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(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n));
QSizeF area(n, n); QSizeF area(n, n);
QPointF pos(0, 0); 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) for (unsigned i = bg.all().first, ei = bg.all().second; i < ei; ++i)
{ {
@ -63,7 +63,7 @@ void DownloadView::paintEvent(QPaintEvent*)
unsigned h = 0; unsigned h = 0;
m_man->foreachSub([&](DownloadSub const& sub) m_man->foreachSub([&](DownloadSub const& sub)
{ {
if (sub.asked().contains(i)) if (sub.askedContains(i))
s = h; s = h;
h++; h++;
}); });

355
alethzero/Main.ui

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1711</width> <width>1617</width>
<height>1138</height> <height>1371</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -116,7 +116,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1711</width> <width>1617</width>
<height>25</height> <height>25</height>
</rect> </rect>
</property> </property>
@ -130,6 +130,8 @@
<property name="title"> <property name="title">
<string>&amp;Network</string> <string>&amp;Network</string>
</property> </property>
<addaction name="go"/>
<addaction name="separator"/>
<addaction name="upnp"/> <addaction name="upnp"/>
<addaction name="usePast"/> <addaction name="usePast"/>
<addaction name="localNetworking"/> <addaction name="localNetworking"/>
@ -141,15 +143,12 @@
<string>T&amp;ools</string> <string>T&amp;ools</string>
</property> </property>
<addaction name="mine"/> <addaction name="mine"/>
<addaction name="preview"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="create"/> <addaction name="create"/>
<addaction name="importKey"/> <addaction name="importKey"/>
<addaction name="importKeyFile"/>
<addaction name="exportKey"/> <addaction name="exportKey"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="showAll"/>
<addaction name="showAllAccounts"/>
<addaction name="separator"/>
<addaction name="loadJS"/> <addaction name="loadJS"/>
</widget> </widget>
<widget class="QMenu" name="menu_Help"> <widget class="QMenu" name="menu_Help">
@ -162,7 +161,32 @@
<property name="title"> <property name="title">
<string>Deb&amp;ug</string> <string>Deb&amp;ug</string>
</property> </property>
<widget class="QMenu" name="menuDump_Trace"> <addaction name="debugDumpState"/>
<addaction name="debugDumpStatePre"/>
<addaction name="separator"/>
<addaction name="paranoia"/>
<addaction name="killBlockchain"/>
<addaction name="inject"/>
<addaction name="forceMining"/>
<addaction name="turboMining"/>
<addaction name="enableOptimizer"/>
<addaction name="separator"/>
<addaction name="usePrivate"/>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
<string>&amp;View</string>
</property>
<addaction name="showAll"/>
<addaction name="showAllAccounts"/>
<addaction name="separator"/>
<addaction name="preview"/>
</widget>
<widget class="QMenu" name="menuDebugger">
<property name="title">
<string>D&amp;ebugger</string>
</property>
<widget class="QMenu" name="menu_Dump_Trace">
<property name="title"> <property name="title">
<string>&amp;Dump Trace</string> <string>&amp;Dump Trace</string>
</property> </property>
@ -171,8 +195,7 @@
<addaction name="dumpTracePretty"/> <addaction name="dumpTracePretty"/>
</widget> </widget>
<addaction name="debugCurrent"/> <addaction name="debugCurrent"/>
<addaction name="debugDumpState"/> <addaction name="menu_Dump_Trace"/>
<addaction name="debugDumpStatePre"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="debugStep"/> <addaction name="debugStep"/>
<addaction name="debugStepInto"/> <addaction name="debugStepInto"/>
@ -180,20 +203,19 @@
<addaction name="debugStepBack"/> <addaction name="debugStepBack"/>
<addaction name="debugStepBackInto"/> <addaction name="debugStepBackInto"/>
<addaction name="debugStepBackOut"/> <addaction name="debugStepBackOut"/>
<addaction name="menuDump_Trace"/> </widget>
<addaction name="separator"/> <widget class="QMenu" name="menuWhispe">
<addaction name="paranoia"/> <property name="title">
<addaction name="killBlockchain"/> <string>&amp;Whisper</string>
<addaction name="inject"/> </property>
<addaction name="forceMining"/> <addaction name="newIdentity"/>
<addaction name="turboMining"/>
<addaction name="enableOptimizer"/>
<addaction name="separator"/>
<addaction name="usePrivate"/>
</widget> </widget>
<addaction name="menu_File"/> <addaction name="menu_File"/>
<addaction name="menu_View"/>
<addaction name="menu_Network"/> <addaction name="menu_Network"/>
<addaction name="menu_Tools"/> <addaction name="menu_Tools"/>
<addaction name="menuDebugger"/>
<addaction name="menuWhispe"/>
<addaction name="menu_Debug"/> <addaction name="menu_Debug"/>
<addaction name="menu_Help"/> <addaction name="menu_Help"/>
</widget> </widget>
@ -507,8 +529,7 @@
<attribute name="toolBarBreak"> <attribute name="toolBarBreak">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
<addaction name="net"/> <addaction name="go"/>
<addaction name="connect"/>
<addaction name="preview"/> <addaction name="preview"/>
<addaction name="mine"/> <addaction name="mine"/>
<addaction name="refresh"/> <addaction name="refresh"/>
@ -1466,6 +1487,276 @@ font-size: 14pt</string>
</layout> </layout>
</widget> </widget>
</widget> </widget>
<widget class="QDockWidget" name="dockWidget_13">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Nodes</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_13">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="nodes">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_14">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Whisper</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_14">
<layout class="QGridLayout" name="gridLayout_4">
<item row="2" column="4">
<widget class="QSpinBox" name="shhWork">
<property name="suffix">
<string> ms</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_9">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Topic</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>data</cstring>
</property>
</widget>
</item>
<item row="3" column="1" colspan="4">
<widget class="QPlainTextEdit" name="shhTopic">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
</item>
<item row="5" column="1" colspan="4">
<widget class="QPlainTextEdit" name="shhData">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
</item>
<item row="6" column="4">
<widget class="QPushButton" name="post">
<property name="text">
<string>Post</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label5_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TTL</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label5_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>From</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label5_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>To</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
<widget class="QComboBox" name="shhFrom">
<property name="editable">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="1" colspan="4">
<widget class="QComboBox" name="shhTo">
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0" rowspan="2">
<widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Data</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>data</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="shhTtl">
<property name="suffix">
<string> seconds</string>
</property>
<property name="minimum">
<number>5</number>
</property>
<property name="maximum">
<number>259200</number>
</property>
</widget>
</item>
<item row="2" column="2" colspan="2">
<widget class="QLabel" name="label5_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Work to Prove</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_15">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Active Whispers</string>
</property>
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_15">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="whispers">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<action name="quit"> <action name="quit">
<property name="text"> <property name="text">
<string>&amp;Quit</string> <string>&amp;Quit</string>
@ -1521,7 +1812,7 @@ font-size: 14pt</string>
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>&amp;Preview</string> <string>&amp;Preview Pending Transactions</string>
</property> </property>
</action> </action>
<action name="debugStep"> <action name="debugStep">
@ -1740,6 +2031,24 @@ font-size: 14pt</string>
<string>Enable Local Addresses</string> <string>Enable Local Addresses</string>
</property> </property>
</action> </action>
<action name="importKeyFile">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Claim Ether Presale &amp;Wallet...</string>
</property>
</action>
<action name="go">
<property name="text">
<string>Go!</string>
</property>
</action>
<action name="newIdentity">
<property name="text">
<string>New Identity</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

693
alethzero/MainWin.cpp

File diff suppressed because it is too large

40
alethzero/MainWin.h

@ -21,6 +21,9 @@
#pragma once #pragma once
#ifdef Q_MOC_RUN
#define BOOST_MPL_IF_HPP_INCLUDED
#endif
#include <map> #include <map>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
@ -30,6 +33,7 @@
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libethcore/CommonEth.h> #include <libethcore/CommonEth.h>
#include <libethereum/State.h> #include <libethereum/State.h>
#include <libethereum/Executive.h>
#include <libqethereum/QEthereum.h> #include <libqethereum/QEthereum.h>
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
@ -40,10 +44,10 @@ class Main;
namespace dev { namespace eth { namespace dev { namespace eth {
class Client; class Client;
class State; class State;
class MessageFilter;
}} }}
class QQuickView; class QQuickView;
class OurWebThreeStubServer;
struct WorldState struct WorldState
{ {
@ -65,22 +69,23 @@ struct WorldState
class Main : public QMainWindow class Main : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit Main(QWidget *parent = 0); explicit Main(QWidget *parent = 0);
~Main(); ~Main();
dev::WebThreeDirect* web3() const { return m_webThree.get(); } dev::WebThreeDirect* web3() const { return m_webThree.get(); }
dev::eth::Client* ethereum() const { return m_webThree->ethereum(); } dev::eth::Client* ethereum() const { return m_webThree->ethereum(); }
dev::shh::WhisperHost* whisper() const { return m_webThree->whisper(); } std::shared_ptr<dev::shh::WhisperHost> whisper() const { return m_webThree->whisper(); }
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
QList<dev::KeyPair> const& owned() const { return m_myKeys; }
public slots: public slots:
void load(QString _file); void load(QString _file);
void note(QString _entry); void note(QString _entry);
void debug(QString _entry); void debug(QString _entry);
void warn(QString _entry); void warn(QString _entry);
QString contents(QString _file);
void onKeysChanged(); void onKeysChanged();
@ -141,9 +146,17 @@ private slots:
void on_debugDumpState_triggered(int _add = 1); void on_debugDumpState_triggered(int _add = 1);
void on_debugDumpStatePre_triggered(); void on_debugDumpStatePre_triggered();
void on_refresh_triggered(); void on_refresh_triggered();
void on_usePrivate_triggered(); void on_usePrivate_triggered();
void on_enableOptimizer_triggered(); void on_enableOptimizer_triggered();
void on_turboMining_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: signals:
void poll(); void poll();
@ -176,8 +189,11 @@ private:
dev::u256 value() const; dev::u256 value() const;
dev::u256 gasPrice() const; dev::u256 gasPrice() const;
unsigned installWatch(dev::eth::MessageFilter const& _tf, std::function<void()> const& _f); unsigned installWatch(dev::eth::LogFilter const& _tf, std::function<void()> const& _f);
unsigned installWatch(dev::h256 _tf, std::function<void()> const& _f); unsigned installWatch(dev::h256 _tf, std::function<void()> const& _f);
void uninstallWatch(unsigned _w);
void keysChanged();
void onNewPending(); void onNewPending();
void onNewBlock(); void onNewBlock();
@ -194,12 +210,12 @@ private:
void refreshNetwork(); void refreshNetwork();
void refreshMining(); void refreshMining();
void refreshWhispers();
void refreshAll(); void refreshAll();
void refreshPending(); void refreshPending();
void refreshAccounts(); void refreshAccounts();
void refreshDestination(); void refreshDestination();
void refreshBlockChain();
void refreshBlockCount(); void refreshBlockCount();
void refreshBalances(); void refreshBalances();
@ -215,8 +231,8 @@ private:
QByteArray m_peers; QByteArray m_peers;
QStringList m_servers; QStringList m_servers;
QList<dev::KeyPair> m_myKeys; QList<dev::KeyPair> m_myKeys;
QList<dev::KeyPair> m_myIdentities;
QString m_privateChain; QString m_privateChain;
bool m_keysChanged = false;
dev::bytes m_data; dev::bytes m_data;
dev::Address m_nameReg; dev::Address m_nameReg;
@ -240,5 +256,9 @@ private:
QString m_logHistory; QString m_logHistory;
bool m_logChanged = true; bool m_logChanged = true;
QEthereum* m_ethereum = nullptr; std::unique_ptr<QWebThreeConnector> m_qwebConnector;
std::unique_ptr<OurWebThreeStubServer> m_server;
QWebThree* m_qweb = nullptr;
static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr);
}; };

28
libethereum/Manifest.cpp → alethzero/OurWebThreeStubServer.cpp

@ -14,33 +14,23 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file Manifest.cpp /** @file OurWebThreeStubServer.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
*/ */
#include "Manifest.h" #include "OurWebThreeStubServer.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
Manifest::Manifest(bytesConstRef _r) OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts):
{ WebThreeStubServer(_conn, _web3, _accounts)
RLP r(_r); {}
from = r[0].toHash<Address>();
to = r[1].toHash<Address>();
value = r[2].toInt<u256>();
altered = r[3].toVector<u256>();
input = r[4].toBytes();
output = r[5].toBytes();
for (auto const& i: r[6])
internal.emplace_back(i.data());
}
void Manifest::streamOut(RLPStream& _s) const std::string OurWebThreeStubServer::shh_newIdentity()
{ {
_s.appendList(7) << from << to << value << altered << input << output; dev::KeyPair kp = dev::KeyPair::create();
_s.appendList(internal.size()); emit onNewId(QString::fromStdString(toJS(kp.sec())));
for (auto const& i: internal) return toJS(kp.pub());
i.streamOut(_s);
} }

38
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 <http://www.gnu.org/licenses/>.
*/
/** @file OurWebThreeStubServer.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include <QtCore/QObject>
#include <libdevcore/CommonJS.h>
#include <libdevcrypto/Common.h>
#include <libweb3jsonrpc/WebThreeStubServer.h>
class OurWebThreeStubServer: public QObject, public WebThreeStubServer
{
Q_OBJECT
public:
OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, dev::WebThreeDirect& _web3, std::vector<dev::KeyPair> const& _accounts);
virtual std::string shh_newIdentity() override;
signals:
void onNewId(QString _s);
};

BIN
alethzero/alethzero.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

1
alethzero/alethzero.rc

@ -0,0 +1 @@
APP_ICON ICON DISCARDABLE "alethzero.ico"

1
alethzero/main.cpp

@ -4,6 +4,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
Q_INIT_RESOURCE(js);
Main w; Main w;
w.show(); w.show();

4
astylerc

@ -6,6 +6,6 @@ min-conditional-indent=1
pad-oper pad-oper
pad-header pad-header
unpad-paren unpad-paren
delete-empty-lines
align-pointer=type align-pointer=type
keep-one-line-blocks
close-templates

27
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()

39
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 ()

148
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()

152
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}" "$<TARGET_FILE_DIR:${EXECUTABLE}>"
)
endforeach()
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy_directory
"${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms"
$<TARGET_FILE_DIR:${EXECUTABLE}>/platforms
)
# ugly way, improve that
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy_directory
"${ETH_DEPENDENCY_INSTALL_DIR}/qml"
$<TARGET_FILE_DIR:${EXECUTABLE}>
)
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()

49
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)

108
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)

34
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)

99
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)

48
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)

48
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)

34
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)

34
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)

31
docker/Dockerfile

@ -4,17 +4,30 @@ ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update RUN apt-get update
RUN apt-get upgrade -y RUN apt-get upgrade -y
RUN apt-get install -qy wget # Ethereum dependencies
RUN apt-get install -qy build-essential g++-4.8 automake libtool unzip git cmake RUN apt-get install -qy build-essential g++-4.8 git cmake libboost-all-dev libcurl4-openssl-dev wget
RUN apt-get install -qy libncurses5-dev libgmp-dev libgmp3-dev libboost-all-dev libleveldb-dev yasm libminiupnpc-dev RUN apt-get install -qy automake unzip libgmp-dev libtool libleveldb-dev yasm libminiupnpc-dev libreadline-dev scons
RUN apt-get install -qy qtbase5-dev qt5-default qtdeclarative5-dev libqt5webkit5-dev
RUN mkdir /cryptopp562 # NCurses based GUI (not optional though for a succesful compilation, see https://github.com/ethereum/cpp-ethereum/issues/452 )
RUN cd /cryptopp562 && wget http://www.cryptopp.com/cryptopp562.zip && unzip cryptopp562.zip RUN apt-get install -qy libncurses5-dev
RUN cd /cryptopp562 && make -j $(cat /proc/cpuinfo | grep processor | wc -l) && make install
# 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 git clone --depth=1 https://github.com/ethereum/cpp-ethereum
RUN mkdir cpp-ethereum/build RUN mkdir -p 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 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"] ENTRYPOINT ["/usr/local/bin/eth"]

379
eth/BigInteger.js

@ -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;
}

52
eth/CMakeLists.txt

@ -1,49 +1,33 @@
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0015 NEW)
set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST) aux_source_directory(. SRC_LIST)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
include_directories(..) include_directories(..)
link_directories(../libethcore)
link_directories(../libwebthree)
set(EXECUTABLE eth) set(EXECUTABLE eth)
add_executable(${EXECUTABLE} ${SRC_LIST}) file(GLOB HEADERS "*.h")
target_link_libraries(${EXECUTABLE} webthree) add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} gmp) add_dependencies(${EXECUTABLE} BuildInfo.h)
if(MINIUPNPC_LS)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) target_link_libraries(${EXECUTABLE} ${Boost_REGEX_LIBRARIES})
endif() target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if (READLINE_FOUND)
if(JSONRPC_LS) target_link_libraries(${EXECUTABLE} ${READLINE_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${JSONRPC_LS})
endif() endif()
if(READLINE_LS)
target_link_libraries(${EXECUTABLE} ${READLINE_LS}) if (JSONRPC)
target_link_libraries(${EXECUTABLE} web3jsonrpc)
endif() endif()
if ("${TARGET_PLATFORM}" STREQUAL "w64") target_link_libraries(${EXECUTABLE} webthree)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") target_link_libraries(${EXECUTABLE} secp256k1)
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 ()
install( TARGETS ${EXECUTABLE} DESTINATION bin ) install( TARGETS ${EXECUTABLE} DESTINATION bin )

66
eth/CommonJS.cpp

@ -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 <http://www.gnu.org/licenses/>.
*/
/** @file CommonJS.cpp
* @authors:
* Gav Wood <i@gavwood.com>
* @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;
}

217
eth/EthStubServer.cpp

@ -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 <http://www.gnu.org/licenses/>.
*/
/** @file EthStubServer.cpp
* @authors:
* Gav Wood <i@gavwood.com>
* @date 2014
*/
#if ETH_JSONRPC
#include "EthStubServer.h"
#include <libevmface/Instruction.h>
#include <liblll/Compiler.h>
#include <libethereum/Client.h>
#include <libwebthree/WebThree.h>
#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<string>(bi.number);
res["hash"] = boost::lexical_cast<string>(bi.hash);
res["parentHash"] = boost::lexical_cast<string>(bi.parentHash);
res["sha3Uncles"] = boost::lexical_cast<string>(bi.sha3Uncles);
res["coinbaseAddress"] = boost::lexical_cast<string>(bi.coinbaseAddress);
res["stateRoot"] = boost::lexical_cast<string>(bi.stateRoot);
res["transactionsRoot"] = boost::lexical_cast<string>(bi.transactionsRoot);
res["minGasPrice"] = boost::lexical_cast<string>(bi.minGasPrice);
res["gasLimit"] = boost::lexical_cast<string>(bi.gasLimit);
res["gasUsed"] = boost::lexical_cast<string>(bi.gasUsed);
res["difficulty"] = boost::lexical_cast<string>(bi.difficulty);
res["timestamp"] = boost::lexical_cast<string>(bi.timestamp);
res["nonce"] = boost::lexical_cast<string>(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

66
eth/EthStubServer.h

@ -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 <http://www.gnu.org/licenses/>.
*/
/** @file EthStubServer.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <iostream>
#include <jsonrpc/rpc.h>
#include <libdevcrypto/Common.h>
#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<dev::KeyPair> _keys) { m_keys = _keys; }
private:
dev::eth::Client& ethereum() const;
dev::WebThreeDirect& m_web3;
std::vector<dev::KeyPair> m_keys;
Json::Value jsontypeToValue(int);
Json::Value blockJson(const std::string&);
};

162
eth/abstractethstubserver.h

@ -1,162 +0,0 @@
/**
* THIS FILE IS GENERATED BY jsonrpcstub, DO NOT CHANGE IT!!!!!
*/
#ifndef _ABSTRACTETHSTUBSERVER_H_
#define _ABSTRACTETHSTUBSERVER_H_
#include <jsonrpc/rpc.h>
class AbstractEthStubServer : public jsonrpc::AbstractServer<AbstractEthStubServer>
{
public:
AbstractEthStubServer(jsonrpc::AbstractServerConnector* conn) :
jsonrpc::AbstractServer<AbstractEthStubServer>(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_

137
eth/eth.js

@ -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 = '<script src="' + path + '/';
var slash = '"><'+'/script>';
document.write(start + 'BigInteger.js' + slash);
document.write(start + 'ethString.js' + slash);
}
var spec = [
{ "method": "procedures", "params": null, "order": [], "returns": [] },
{ "method": "coinbase", "params": null, "order": [], "returns" : "" },
{ "method": "isListening", "params": null, "order": [], "returns" : false },
{ "method": "isMining", "params": null, "order": [], "returns" : false },
{ "method": "gasPrice", "params": null, "order": [], "returns" : "" },
{ "method": "key", "params": null, "order": [], "returns" : "" },
{ "method": "keys", "params": null, "order": [], "returns" : [] },
{ "method": "peerCount", "params": null, "order": [], "returns" : 0 },
{ "method": "balanceAt", "params": { "a": "" }, "order": ["a"], "returns" : "" },
{ "method": "storageAt", "params": { "a": "", "x": "" }, "order": ["a", "x"], "returns" : "" },
{ "method": "stateAt", "params": { "a": "", "x": "", "s": "" }, "order": ["a", "x", "s"], "returns" : "" },
{ "method": "txCountAt", "params": { "a": "" },"order": ["a"], "returns" : "" },
{ "method": "isContractAt", "params": { "a": "" }, "order": ["a"], "returns" : false },
{ "method": "create", "params": { "sec": "", "xEndowment": "", "bCode": "", "xGas": "", "xGasPrice": "" }, "order": ["sec", "xEndowment", "bCode", "xGas", "xGasPrice"] , "returns": "" },
{ "method": "transact", "params": { "sec": "", "xValue": "", "aDest": "", "bData": "", "xGas": "", "xGasPrice": "" }, "order": ["sec", "xValue", "aDest", "bData", "xGas", "xGasPrice"], "returns": {} },
{ "method": "secretToAddress", "params": { "a": "" }, "order": ["a"], "returns" : "" },
{ "method": "lll", "params": { "s": "" }, "order": ["s"], "returns" : "" }
];
window.eth = (function ethScope() {
var m_reqId = 0
var ret = {}
function reformat(m, d) { return m == "lll" ? d.bin() : d; }
function reqSync(m, p) {
var req = { "jsonrpc": "2.0", "method": m, "params": p, "id": m_reqId }
m_reqId++
var request = new XMLHttpRequest();
request.open("POST", "http://localhost:8080", false)
// console.log("Sending " + JSON.stringify(req))
request.send(JSON.stringify(req))
return reformat(m, JSON.parse(request.responseText).result)
}
function reqAsync(m, p, f) {
var req = { "jsonrpc": "2.0", "method": m, "params": p, "id": m_reqId }
m_reqId++
var request = new XMLHttpRequest();
request.open("POST", "http://localhost:8080", true)
request.send(JSON.stringify(req))
request.onreadystatechange = function() {
if (request.readyState === 4)
f(reformat(m, JSON.parse(request.responseText).result))
};
}
function isEmpty(obj) {
for (var prop in obj)
if (obj.hasOwnProperty(prop))
return false
return true
}
var m_watching = {};
for (si in spec) (function(s) {
var m = s.method;
var am = "get" + m.slice(0, 1).toUpperCase() + m.slice(1);
var getParams = function(a) {
var p = s.params ? {} : null;
if (m == "stateAt")
if (a.length == 2)
a[2] = "0";
else
a[2] = String(a[2]);
for (j in s.order)
p[s.order[j]] = (s.order[j][0] === "b") ? a[j].unbin() : a[j];
return p
};
if (m == "create" || m == "transact")
ret[m] = function() { return reqAsync(m, getParams(arguments), arguments[s.order.length]) }
else
{
ret[am] = function() { return reqAsync(m, getParams(arguments), arguments[s.order.length]) }
if (s.params)
ret[m] = function() { return reqSync(m, getParams(arguments)) }
else
Object.defineProperty(ret, m, {
get: function() { return reqSync(m, {}); },
set: function(v) {}
})
}
})(spec[si]);
ret.check = function(force) {
if (!force && isEmpty(m_watching))
return
var watching = [];
for (var w in m_watching)
watching.push(w)
var changed = reqSync("check", { "a": watching } );
// console.log("Got " + JSON.stringify(changed));
for (var c in changed)
m_watching[changed[c]]()
var that = this;
setTimeout(function() { that.check() }, 12000)
}
ret.watch = function(a, fx, f) {
var old = isEmpty(m_watching)
if (f)
m_watching[a + fx] = f
else
m_watching[a] = fx
(f ? f : fx)()
if (isEmpty(m_watching) != old)
this.check()
}
ret.unwatch = function(f, fx) {
delete m_watching[fx ? f + fx : f];
}
ret.newBlock = function(f) {
var old = isEmpty(m_watching)
m_watching[""] = f
f()
if (isEmpty(m_watching) != old)
this.check()
}
return ret;
}());
}

62
eth/ethString.js

@ -1,62 +0,0 @@
if (typeof(require) !== "undefined")
require( ['BigInteger'], function() {} )
else if (typeof(bigInt) === "undefined")
alert("You need to have included BigInteger.js for eth to work.")
String.prototype.pad = function(l, r) {
if (r === null) {
r = l
if (!(this.substr(0, 2) == "0x" || /^\d+$/.test(this)))
l = 0
}
var ret = this.bin();
while (ret.length < l)
ret = "\0" + ret
while (ret.length < r)
ret = ret + "\0"
return ret;
}
String.prototype.unpad = function() {
var i = this.length;
while (i && this[i - 1] == "\0")
--i
return this.substr(0, i)
}
String.prototype.bin = function() {
if (this.substr(0, 2) == "0x") {
bytes = []
var i = 2;
// Check if it's odd - pad with a zero if so.
if (this.length % 2)
bytes.push(parseInt(this.substr(i++, 1), 16))
for (; i < this.length - 1; i += 2)
bytes.push(parseInt(this.substr(i, 2), 16));
return String.fromCharCode.apply(String, bytes);
} else if (/^\d+$/.test(this))
return bigInt(this.substr(0)).toHex().bin()
// Otherwise we'll return the "String" object instead of an actual string
return this.substr(0, this.length)
}
String.prototype.unbin = function() {
var i, l, o = '';
for(i = 0, l = this.length; i < l; i++) {
var n = this.charCodeAt(i).toString(16);
o += n.length < 2 ? '0' + n : n;
}
return "0x" + o;
}
String.prototype.dec = function() {
return bigInt(this.substr(0)).toString()
}
String.prototype.hex = function() {
return bigInt(this.substr(0)).toHex()
}

150
eth/main.cpp

@ -24,13 +24,11 @@
#include <chrono> #include <chrono>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <signal.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp> #include <boost/algorithm/string/trim_all.hpp>
#if ETH_JSONRPC
#include <jsonrpc/connectors/httpserver.h>
#endif
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
#include <libevmface/Instruction.h> #include <libevmcore/Instruction.h>
#include <libevm/VM.h> #include <libevm/VM.h>
#include <libethereum/All.h> #include <libethereum/All.h>
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
@ -39,7 +37,8 @@
#include <readline/history.h> #include <readline/history.h>
#endif #endif
#if ETH_JSONRPC #if ETH_JSONRPC
#include "EthStubServer.h" #include <libweb3jsonrpc/WebThreeStubServer.h>
#include <libweb3jsonrpc/CorsHttpServer.h>
#endif #endif
#include "BuildInfo.h" #include "BuildInfo.h"
using namespace std; using namespace std;
@ -166,6 +165,13 @@ string pretty(h160 _a, dev::eth::State _st)
return ns; return ns;
} }
bool g_exit = false;
void sighandler(int)
{
g_exit = true;
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
unsigned short listenPort = 30303; unsigned short listenPort = 30303;
@ -300,7 +306,13 @@ int main(int argc, char** argv)
cout << credits(); cout << credits();
NetworkPreferences netPrefs(listenPort, publicIP, upnp, useLocal); NetworkPreferences netPrefs(listenPort, publicIP, upnp, useLocal);
dev::WebThreeDirect web3("Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), dbPath, false, mode == NodeMode::Full ? set<string>{"eth", "shh"} : set<string>{}, netPrefs); dev::WebThreeDirect web3(
"Ethereum(++)/" + clientName + "v" + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM),
dbPath,
false,
mode == NodeMode::Full ? set<string>{"eth", "shh"} : set<string>(),
netPrefs
);
web3.setIdealPeerCount(peers); web3.setIdealPeerCount(peers);
eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr; eth::Client* c = mode == NodeMode::Full ? web3.ethereum() : nullptr;
@ -310,6 +322,9 @@ int main(int argc, char** argv)
c->setAddress(coinbase); c->setAddress(coinbase);
} }
auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/nodeState.rlp");
web3.restoreNodes(&nodesState);
cout << "Address: " << endl << toHex(us.address().asArray()) << endl; cout << "Address: " << endl << toHex(us.address().asArray()) << endl;
web3.startNetwork(); web3.startNetwork();
@ -319,20 +334,26 @@ int main(int argc, char** argv)
web3.connect(remoteHost, remotePort); web3.connect(remoteHost, remotePort);
#if ETH_JSONRPC #if ETH_JSONRPC
auto_ptr<EthStubServer> jsonrpcServer; shared_ptr<WebThreeStubServer> jsonrpcServer;
unique_ptr<jsonrpc::AbstractServerConnector> jsonrpcConnector;
if (jsonrpc > -1) if (jsonrpc > -1)
{ {
jsonrpcServer = auto_ptr<EthStubServer>(new EthStubServer(new jsonrpc::HttpServer(jsonrpc), web3)); jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc));
jsonrpcServer->setKeys({us}); jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({us})));
jsonrpcServer->setIdentities({us});
jsonrpcServer->StartListening(); jsonrpcServer->StartListening();
} }
#endif #endif
signal(SIGABRT, &sighandler);
signal(SIGTERM, &sighandler);
signal(SIGINT, &sighandler);
if (interactive) if (interactive)
{ {
string logbuf; string logbuf;
string l; string l;
while (true) while (!g_exit)
{ {
g_logPost = [](std::string const& a, char const*) { cout << "\r \r" << a << endl << "Press Enter" << flush; }; g_logPost = [](std::string const& a, char const*) { cout << "\r \r" << a << endl << "Press Enter" << flush; };
cout << logbuf << "Press Enter" << flush; cout << logbuf << "Press Enter" << flush;
@ -406,8 +427,9 @@ int main(int argc, char** argv)
{ {
if (jsonrpc < 0) if (jsonrpc < 0)
jsonrpc = 8080; jsonrpc = 8080;
jsonrpcServer = auto_ptr<EthStubServer>(new EthStubServer(new jsonrpc::HttpServer(jsonrpc), web3)); jsonrpcConnector = unique_ptr<jsonrpc::AbstractServerConnector>(new jsonrpc::HttpServer(jsonrpc));
jsonrpcServer->setKeys({us}); jsonrpcServer = shared_ptr<WebThreeStubServer>(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector<KeyPair>({us})));
jsonrpcServer->setIdentities({us});
jsonrpcServer->StartListening(); jsonrpcServer->StartListening();
} }
else if (cmd == "jsonstop") else if (cmd == "jsonstop")
@ -419,9 +441,8 @@ int main(int argc, char** argv)
#endif #endif
else if (cmd == "address") else if (cmd == "address")
{ {
cout << "Current address:" << endl; cout << "Current address:" << endl
const char* addchr = toHex(us.address().asArray()).c_str(); << toHex(us.address().asArray()) << endl;
cout << addchr << endl;
} }
else if (cmd == "secret") else if (cmd == "secret")
{ {
@ -470,14 +491,12 @@ int main(int argc, char** argv)
cnote << ssbd.str(); cnote << ssbd.str();
int ssize = sechex.length(); int ssize = sechex.length();
int size = hexAddr.length(); int size = hexAddr.length();
u256 minGas = (u256)Client::txGas(data.size(), 0); u256 minGas = (u256)Client::txGas(data, 0);
if (size < 40) if (size < 40)
{ {
if (size > 0) if (size > 0)
cwarn << "Invalid address length:" << size; cwarn << "Invalid address length:" << size;
} }
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else if (ssize < 40) else if (ssize < 40)
@ -537,9 +556,9 @@ int main(int argc, char** argv)
auto h = bc.currentHash(); auto h = bc.currentHash();
auto blockData = bc.block(h); auto blockData = bc.block(h);
BlockInfo info(blockData); BlockInfo info(blockData);
u256 minGas = (u256)Client::txGas(0, 0); u256 minGas = (u256)Client::txGas(bytes(), 0);
Address dest = h160(fromHex(hexAddr)); Address dest = h160(fromHex(hexAddr));
c->transact(us.secret(), amount, dest, bytes(), minGas, info.minGasPrice); c->transact(us.secret(), amount, dest, bytes(), minGas);
} }
} }
else else
@ -576,11 +595,9 @@ int main(int argc, char** argv)
cnote << "Init:"; cnote << "Init:";
cnote << ssc.str(); cnote << ssc.str();
} }
u256 minGas = (u256)Client::txGas(init.size(), 0); u256 minGas = (u256)Client::txGas(init, 0);
if (endowment < 0) if (endowment < 0)
cwarn << "Invalid endowment"; cwarn << "Invalid endowment";
else if (gasPrice < info.minGasPrice)
cwarn << "Minimum gas price is" << info.minGasPrice;
else if (gas < minGas) else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas; cwarn << "Minimum gas amount is" << minGas;
else else
@ -602,46 +619,54 @@ int main(int argc, char** argv)
dev::eth::State state =c->state(index + 1,c->blockChain().numberHash(block)); dev::eth::State state =c->state(index + 1,c->blockChain().numberHash(block));
if (index < state.pending().size()) if (index < state.pending().size())
{ {
Executive e(state); Executive e(state, 0);
Transaction t = state.pending()[index]; Transaction t = state.pending()[index];
state = state.fromPending(index); state = state.fromPending(index);
bytes r = t.rlp(); bytes r = t.rlp();
e.setup(&r); try
{
OnOpFunc oof; e.setup(&r);
if (format == "pretty")
oof = [&](uint64_t steps, Instruction instr, bigint newMemSize, bigint gasCost, void* vvm, void const* vextVM) OnOpFunc oof;
{ if (format == "pretty")
dev::eth::VM* vm = (VM*)vvm; oof = [&](uint64_t steps, Instruction instr, bigint newMemSize, bigint gasCost, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM)
dev::eth::ExtVM const* ext = (ExtVM const*)vextVM; {
f << endl << " STACK" << endl; dev::eth::VM* vm = vvm;
for (auto i: vm->stack()) dev::eth::ExtVM const* ext = static_cast<ExtVM const*>(vextVM);
f << (h256)i << endl; f << endl << " STACK" << endl;
f << " MEMORY" << endl << dev::memDump(vm->memory()); for (auto i: vm->stack())
f << " STORAGE" << endl; f << (h256)i << endl;
for (auto const& i: ext->state().storage(ext->myAddress)) f << " MEMORY" << endl << dev::memDump(vm->memory());
f << showbase << hex << i.first << ": " << i.second << endl; f << " STORAGE" << endl;
f << dec << ext->level << " | " << ext->myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm->curPC() << " : " << dev::eth::instructionInfo(instr).name << " | " << dec << vm->gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32";
};
else if (format == "standard")
oof = [&](uint64_t, Instruction instr, bigint, bigint, void* vvm, void const* vextVM)
{
dev::eth::VM* vm = (VM*)vvm;
dev::eth::ExtVM const* ext = (ExtVM const*)vextVM;
f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)vm->gas(), 1)) << endl;
};
else if (format == "standard+")
oof = [&](uint64_t, Instruction instr, bigint, bigint, void* vvm, void const* vextVM)
{
dev::eth::VM* vm = (VM*)vvm;
dev::eth::ExtVM const* ext = (ExtVM const*)vextVM;
if (instr == Instruction::STOP || instr == Instruction::RETURN || instr == Instruction::SUICIDE)
for (auto const& i: ext->state().storage(ext->myAddress)) for (auto const& i: ext->state().storage(ext->myAddress))
f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl; f << showbase << hex << i.first << ": " << i.second << endl;
f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)vm->gas(), 1)) << endl; f << dec << ext->depth << " | " << ext->myAddress << " | #" << steps << " | " << hex << setw(4) << setfill('0') << vm->curPC() << " : " << dev::eth::instructionInfo(instr).name << " | " << dec << vm->gas() << " | -" << dec << gasCost << " | " << newMemSize << "x32";
}; };
e.go(oof); else if (format == "standard")
e.finalize(oof); oof = [&](uint64_t, Instruction instr, bigint, bigint, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM)
{
dev::eth::VM* vm = vvm;
dev::eth::ExtVM const* ext = static_cast<ExtVM const*>(vextVM);
f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)vm->gas(), 1)) << endl;
};
else if (format == "standard+")
oof = [&](uint64_t, Instruction instr, bigint, bigint, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM)
{
dev::eth::VM* vm = (VM*)vvm;
dev::eth::ExtVM const* ext = static_cast<ExtVM const*>(vextVM);
if (instr == Instruction::STOP || instr == Instruction::RETURN || instr == Instruction::SUICIDE)
for (auto const& i: ext->state().storage(ext->myAddress))
f << toHex(dev::toCompactBigEndian(i.first, 1)) << " " << toHex(dev::toCompactBigEndian(i.second, 1)) << endl;
f << ext->myAddress << " " << hex << toHex(dev::toCompactBigEndian(vm->curPC(), 1)) << " " << hex << toHex(dev::toCompactBigEndian((int)(byte)instr, 1)) << " " << hex << toHex(dev::toCompactBigEndian((uint64_t)vm->gas(), 1)) << endl;
};
e.go(oof);
e.finalize(oof);
}
catch(Exception const& _e)
{
// TODO: a bit more information here. this is probably quite worrying as the transaction is already in the blockchain.
cwarn << diagnostic_information(_e);
}
} }
} }
else if (c && cmd == "inspect") else if (c && cmd == "inspect")
@ -671,7 +696,7 @@ int main(int argc, char** argv)
cnote << "Saved" << rechex << "to" << outFile; cnote << "Saved" << rechex << "to" << outFile;
} }
catch (dev::eth::InvalidTrie) catch (dev::InvalidTrie)
{ {
cwarn << "Corrupted trie."; cwarn << "Corrupted trie.";
} }
@ -751,7 +776,7 @@ int main(int argc, char** argv)
unsigned n =c->blockChain().details().number; unsigned n =c->blockChain().details().number;
if (mining) if (mining)
c->startMining(); c->startMining();
while (true) while (!g_exit)
{ {
if ( c->isMining() &&c->blockChain().details().number - n == mining) if ( c->isMining() &&c->blockChain().details().number - n == mining)
c->stopMining(); c->stopMining();
@ -759,9 +784,10 @@ int main(int argc, char** argv)
} }
} }
else else
while (true) while (!g_exit)
this_thread::sleep_for(chrono::milliseconds(1000)); this_thread::sleep_for(chrono::milliseconds(1000));
writeFile((dbPath.size() ? dbPath : getDataDir()) + "/nodeState.rlp", web3.saveNodes());
return 0; return 0;
} }

24
eth/spec.json

@ -1,24 +0,0 @@
[
{ "method": "procedures", "params": null, "order": [], "returns": [] },
{ "method": "coinbase", "params": null, "order": [], "returns" : "" },
{ "method": "isListening", "params": null, "order": [], "returns" : false },
{ "method": "isMining", "params": null, "order": [], "returns" : false },
{ "method": "gasPrice", "params": null, "order": [], "returns" : "" },
{ "method": "key", "params": null, "order": [], "returns" : "" },
{ "method": "keys", "params": null, "order": [], "returns" : [] },
{ "method": "peerCount", "params": null, "order": [], "returns" : 0 },
{ "method": "balanceAt", "params": { "a": "" }, "order": ["a"], "returns" : "" },
{ "method": "storageAt", "params": { "a": "", "x": "" }, "order": ["a", "x"], "returns" : "" },
{ "method": "txCountAt", "params": { "a": "" },"order": ["a"], "returns" : "" },
{ "method": "isContractAt", "params": { "a": "" }, "order": ["a"], "returns" : false },
{ "method": "create", "params": { "sec": "", "xEndowment": "", "bCode": "", "xGas": "", "xGasPrice": "" }, "order": ["sec", "xEndowment", "bCode", "xGas", "xGasPrice"] , "returns": "" },
{ "method": "transact", "params": { "sec": "", "xValue": "", "aDest": "", "bData": "", "xGas": "", "xGasPrice": "" }, "order": ["sec", "xValue", "aDest", "bData", "xGas", "xGasPrice"], "returns": {} },
{ "method": "secretToAddress", "params": { "a": "" }, "order": ["a"], "returns" : "" },
{ "method": "lll", "params": { "s": "" }, "order": ["s"], "returns" : "" }
,
{ "method": "check", "params": { "a": [] }, "order": ["a"], "returns" : [] },
{ "method": "lastBlock", "params": null, "order": [], "returns": {}},
{ "method": "block", "params": {"a":""}, "order": ["a"], "returns": {}}
]

30
exp/CMakeLists.txt

@ -1,7 +1,9 @@
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0015 NEW)
set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST) aux_source_directory(. SRC_LIST)
include_directories(${LEVELDB_INCLUDE_DIRS})
include_directories(..) include_directories(..)
set(EXECUTABLE exp) set(EXECUTABLE exp)
@ -10,32 +12,6 @@ add_executable(${EXECUTABLE} ${SRC_LIST})
target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} ethereum)
target_link_libraries(${EXECUTABLE} p2p) target_link_libraries(${EXECUTABLE} p2p)
target_link_libraries(${EXECUTABLE} gmp)
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS})
if(MINIUPNPC_LS)
target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS})
endif()
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
if ("${TARGET_PLATFORM}" STREQUAL "w64") install( TARGETS ${EXECUTABLE} DESTINATION bin)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
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)
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)
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 ()
install( TARGETS ${EXECUTABLE} DESTINATION bin )

90
exp/main.cpp

@ -20,20 +20,26 @@
* Ethereum client. * Ethereum client.
*/ */
#include <functional> #include <functional>
#include <libethereum/AccountDiff.h>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcore/CommonIO.h>
#include <libp2p/All.h> #include <libp2p/All.h>
#include <libdevcore/RangeMask.h> #include <libdevcore/RangeMask.h>
#include <libethereum/DownloadMan.h> #include <libethereum/DownloadMan.h>
#include <libethereum/All.h>
#include <liblll/All.h>
#include <libwhisper/WhisperPeer.h> #include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
using namespace dev::p2p; using namespace dev::p2p;
using namespace dev::shh; using namespace dev::shh;
#if 0
int main() int main()
{ {
DownloadMan man; DownloadMan man;
@ -41,18 +47,19 @@ int main()
DownloadSub s1(man); DownloadSub s1(man);
DownloadSub s2(man); DownloadSub s2(man);
man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)})); man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}));
cnote << s0.nextFetch(2); assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8}));
cnote << s1.nextFetch(2); assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6}));
cnote << s2.nextFetch(2); assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4}));
s0.noteBlock(u256(0)); s0.noteBlock(u256(8));
s0.doneFetch(); s0.doneFetch();
cnote << s0.nextFetch(2); assert((s0.nextFetch(2) == h256Set{(u256)2, (u256)7}));
s1.noteBlock(u256(2)); s1.noteBlock(u256(6));
s1.noteBlock(u256(3)); s1.noteBlock(u256(5));
s1.doneFetch(); s1.doneFetch();
cnote << s1.nextFetch(2); assert((s1.nextFetch(2) == h256Set{(u256)0, (u256)1}));
s0.doneFetch(); s0.doneFetch(); // TODO: check exact semantics of doneFetch & nextFetch. Not sure if they're right -> doneFetch calls resetFetch which kills all the info of past fetches.
cnote << s0.nextFetch(2); cdebug << s0.nextFetch(2);
assert((s0.nextFetch(2) == h256Set{(u256)3, (u256)4}));
/* RangeMask<unsigned> m(0, 100); /* RangeMask<unsigned> m(0, 100);
cnote << m; cnote << m;
@ -68,48 +75,25 @@ int main()
cnote << i;*/ cnote << i;*/
return 0; return 0;
} }
#else
/* int main()
int main(int argc, char** argv)
{ {
g_logVerbosity = 20; KeyPair u = KeyPair::create();
KeyPair cb = KeyPair::create();
short listenPort = 30303; OverlayDB db;
string remoteHost; State s(cb.address(), db, BaseState::Empty);
short remotePort = 30303; cnote << s.rootHash();
s.addBalance(u.address(), 1 * ether);
for (int i = 1; i < argc; ++i) Address c = s.newContract(1000 * ether, compileLLL("(suicide (caller))"));
{ s.commit();
string arg = argv[i]; State before = s;
if (arg == "-l" && i + 1 < argc) cnote << "State before transaction: " << before;
listenPort = (short)atoi(argv[++i]); Transaction t(0, 10000, 10000, c, bytes(), 0, u.secret());
else if (arg == "-r" && i + 1 < argc) cnote << "Transaction: " << t;
remoteHost = argv[++i]; cnote << s.balance(c);
else if (arg == "-p" && i + 1 < argc) s.execute(t.rlp());
remotePort = (short)atoi(argv[++i]); cnote << "State after transaction: " << s;
else cnote << before.diff(s);
remoteHost = argv[i];
}
Host ph("Test", NetworkPreferences(listenPort, "", false, true));
ph.registerCapability(new WhisperHost());
auto wh = ph.cap<WhisperHost>();
ph.start();
if (!remoteHost.empty())
ph.connect(remoteHost, remotePort);
/// Only interested in the packet if the lowest bit is 1
auto w = wh->installWatch(MessageFilter(std::vector<std::pair<bytes, bytes> >({{fromHex("0000000000000000000000000000000000000000000000000000000000000001"), fromHex("0000000000000000000000000000000000000000000000000000000000000001")}})));
for (int i = 0; ; ++i)
{
wh->sendRaw(h256(u256(i * i)).asBytes(), h256(u256(i)).asBytes(), 1000);
for (auto i: wh->checkWatch(w))
cnote << "New message:" << (u256)h256(wh->message(i).payload);
}
return 0;
} }
*/ #endif

55
extdep/CMakeLists.txt

@ -0,0 +1,55 @@
cmake_minimum_required(VERSION 2.8.12)
include(ExternalProject)
include(CMakeParseArguments)
include(eth_download.cmake)
# all dependencies will be installed into this directory, separated by platform
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name)
set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}")
set(ETH_DEPENDENCY_SERVER "http://poc-7.ethdev.com/precompiled/${_system_name}")
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin)
if (ETH_COMPILE)
# json-rpc-cpp and its dependencies
include(compile/jsoncpp.cmake)
include(compile/argtable2.cmake)
include(compile/curl.cmake)
include(compile/json-rpc-cpp.cmake)
# qt and its dependencies
include(compile/icu.cmake)
include(compile/jom.cmake)
include(compile/qt.cmake)
# leveldb and its dependencies
include(compile/snappy.cmake)
include(compile/leveldb.cmake)
# cryptopp
include(compile/cryptopp.cmake)
# boost
include(compile/boost.cmake)
else()
eth_download(jsoncpp)
eth_download(json-rpc-cpp OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh)
if (APPLE)
eth_download(snappy OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/snappy_osx.sh)
endif()
eth_download(leveldb OSX_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/scripts/leveldb_osx.sh)
eth_download(qt)
eth_download(cryptopp)
eth_download(boost)
eth_download(curl)
endif()
# will be re-eanbled later
# include(miniupnpc.cmake)
# if install phase of extep fails, even if libs are already created, the ethereum install will fail

16
extdep/Readme.md

@ -0,0 +1,16 @@
# cpp-ethereum external dependencies
**This is Work-in-Progress!**
This directory hosts the external libraries that are needed to build cpp-ethereum.
To automatically download, build, and link libraries, do
```
cd extdep; mkdir build; cd build; cmake ..; make
```
this will take some time.
To check which libraries are already included, check `CMakeLists.txt`. Other libraries still need to be fetched via the system's package manager.
Libraries will be installed in `cpp-ethereum/extdep/install/<platform-name>`

9
extdep/cmake/FindCURL.cmake

@ -0,0 +1,9 @@
# hacky way to resolve nested dependencies - needed for json-rpc-cpp
find_library(CURL_LIBRARY NAMES curl
PATHS
${ETH_DEPENDENCY_INSTALL_DIR}/lib
)
set(CURL_LIBRARIES ${CURL_LIBRARY})
set(CURL_INCLUDE_DIRS ${ETH_DEPENDENCY_INSTALL_DIR}/include)

13
extdep/compile/argtable2.cmake

@ -0,0 +1,13 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(argtable2
GIT_REPOSITORY https://github.com/debris/argtable.git
GIT_TAG master
BINARY_DIR argtable2-prefix/src/argtable2
CONFIGURE_COMMAND cmake .
BUILD_COMMAND devenv argtable2.sln /build release
INSTALL_COMMAND cmd /c cp src/Release/argtable2.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp src/argtable2.h ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
endif()

19
extdep/compile/boost.cmake

@ -0,0 +1,19 @@
if (APPLE)
elseif (WIN32)
set(boost_address_model)
# on windows 64:
# set(boost_address_model address-model=64)
set(boost_targets --with-filesystem --with-system --with-thread --with-date_time --with-regex --with-test --with-chrono --with-program_options)
ExternalProject_Add(boost
URL http://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.gz
BINARY_DIR boost-prefix/src/boost
CONFIGURE_COMMAND ./bootstrap.bat
BUILD_COMMAND ./b2.exe -j4 --build-type=complete link=static runtime-link=shared variant=debug,release threading=multi ${boost_addressModel} ${boost_targets} install --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
INSTALL_COMMAND cmake -E rename ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost-1_55/boost ${ETH_DEPENDENCY_INSTALL_DIR}/include/boost
)
else()
endif()

33
extdep/compile/cryptopp.cmake

@ -0,0 +1,33 @@
# CryptoPP does not have good cross-platform support, there exist several different other projects to make it work ...
# TODO the OS X build throws a lot of warnings, but compiles fine
if (APPLE)
ExternalProject_Add(cryptopp
URL https://downloads.sourceforge.net/project/cryptopp/cryptopp/5.6.2/cryptopp562.zip
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND ""
BUILD_COMMAND make CXX=clang++ CXXFLAGS=-DCRYPTOPP_DISABLE_ASM
INSTALL_COMMAND make install PREFIX=${ETH_DEPENDENCY_INSTALL_DIR}
)
elseif (WIN32)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp)
ExternalProject_Add(cryptopp
SVN_REPOSITORY http://svn.code.sf.net/p/cryptopp/code/trunk/c5
SVN_REVISION -r "541"
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND devenv cryptest.sln /upgrade
BUILD_COMMAND devenv cryptest.sln /build release
INSTALL_COMMAND cmd /c cp Win32/DLL_Output/Release/cryptopp.dll ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp Win32/DLL_Output/Release/cryptopp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp *.h ${ETH_DEPENDENCY_INSTALL_DIR}/include/cryptopp
)
# on Linux, the default Makefile does not work.
else()
ExternalProject_Add(cryptopp
URL https://github.com/mmoss/cryptopp/archive/v5.6.2.zip
BINARY_DIR cryptopp-prefix/src/cryptopp
CONFIGURE_COMMAND ""
BUILD_COMMAND scons --shared --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
INSTALL_COMMAND ""
)
endif()

29
extdep/compile/curl.cmake

@ -0,0 +1,29 @@
if (APPLE)
ExternalProject_Add(curl
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND ./configure --with-darwinssl --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
elseif (WIN32)
ExternalProject_Add(curl
GIT_REPOSITORY https://github.com/debris/libcurl-7.29
GIT_TAG master
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmd /c cp lib/release/libcurl.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/curl ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
ExternalProject_Add(curl
URL http://curl.haxx.se/download/curl-7.38.0.tar.bz2
BINARY_DIR curl-prefix/src/curl
CONFIGURE_COMMAND CONFIG_CMD ./configure --prefix=${ETH_DEPENDENCY_INSTALL_DIR} --exec-prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
endif()

17
extdep/compile/icu.cmake

@ -0,0 +1,17 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(icu
GIT_REPOSITORY https://github.com/debris/icu-win32.git
GIT_TAG master
BINARY_DIR icu-prefix/src/icu
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR}
)
else()
endif()

16
extdep/compile/jom.cmake

@ -0,0 +1,16 @@
if (APPLE)
elseif (WIN32)
ExternalProject_Add(jom
URL http://download.qt-project.org/official_releases/jom/jom.zip
BINARY_DIR jom-prefix/src/jom
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmake -E copy jom.exe ${ETH_DEPENDENCY_INSTALL_DIR}/bin
)
else()
endif()

40
extdep/compile/json-rpc-cpp.cmake

@ -0,0 +1,40 @@
# json-rpc-cpp is under heavy development, not yet stable, and multiplatform builds are not yet available.
# DO NOT MESS WITH THESE SETTINGS! IF YOU HAVE TO MAKE CHANGES HERE, CONSULT sven@ethdev.com BEFOREHAND!!
# DO NOT CHANGE ANYTHING HERE!
if(APPLE)
ExternalProject_Add(json-rpc-cpp
# DEPENDS argtable2 jsoncpp
# DEPENDS curl # re-enable later, when we build curl again
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git
GIT_TAG v0.3.2
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST -Wno-dev .
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install && ${CMAKE_CURRENT_SOURCE_DIR}/scripts/json-rpc-cpp_osx.sh . ${ETH_DEPENDENCY_INSTALL_DIR}
)
elseif (WIN32)
ExternalProject_Add(json-rpc-cpp
DEPENDS argtable2 jsoncpp curl
GIT_REPOSITORY https://github.com/debris/libjson-rpc-cpp.git
GIT_TAG windows
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_PREFIX_PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCURL_LIBRARIES=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libcurl.lib .
BUILD_COMMAND devenv libjson-rpc-cpp.sln /build release
INSTALL_COMMAND cmd /c cp lib/Release/* ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R src/jsonrpccpp ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
ExternalProject_Add(json-rpc-cpp
# DEPENDS argtable2 jsoncpp
# DEPENDS curl # re-enable later, when we build curl again
GIT_REPOSITORY https://github.com/cinemast/libjson-rpc-cpp.git
GIT_TAG v0.3.2
BINARY_DIR json-rpc-cpp-prefix/src/json-rpc-cpp
CONFIGURE_COMMAND cmake -DCMAKE_INSTALL_PREFIX=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_MODULE_PATH:PATH=${CMAKE_CURRENT_SOURCE_DIR}/cmake -DETH_DEPENDENCY_INSTALL_DIR:PATH=${ETH_DEPENDENCY_INSTALL_DIR} -DCMAKE_BUILD_TYPE=None -DCMAKE_FIND_FRAMEWORK=LAST .
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install
)
endif()

16
extdep/compile/jsoncpp.cmake

@ -0,0 +1,16 @@
if (APPLE)
elseif (WIN32)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp)
ExternalProject_Add(jsoncpp
GIT_REPOSITORY https://github.com/open-source-parsers/jsoncpp
GIT_TAG svn-import
BINARY_DIR jsoncpp-prefix/src/jsoncpp
CONFIGURE_COMMAND cmake .
BUILD_COMMAND devenv jsoncpp.sln /build release
INSTALL_COMMAND cmd /c cp lib/Release/jsoncpp.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp -R include/json ${ETH_DEPENDENCY_INSTALL_DIR}/include/jsoncpp
)
else()
endif()

23
extdep/compile/leveldb.cmake

@ -0,0 +1,23 @@
if (APPLE)
ExternalProject_Add(leveldb
#DEPENDS snappy
URL https://leveldb.googlecode.com/files/leveldb-1.15.0.tar.gz
BINARY_DIR leveldb-prefix/src/leveldb
#CONFIGURE_COMMAND patch < ${CMAKE_CURRENT_SOURCE_DIR}/compile/leveldb_osx.patch
CONFIGURE_COMMAND ""
BUILD_COMMAND export ETH_DEPENDENCY_INSTALL_DIR=${ETH_DEPENDENCY_INSTALL_DIR} && make -j 3
INSTALL_COMMAND cp -rf include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include/ && cp libleveldb.a ${ETH_DEPENDENCY_INSTALL_DIR}/lib && cp libleveldb.dylib.1.15 ${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib
)
elseif (WIN32)
ExternalProject_Add(leveldb
GIT_REPOSITORY https://github.com/debris/leveldb-win32.git
GIT_TAG master
BINARY_DIR leveldb-prefix/src/leveldb
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND cmd /c cp lib/LibLevelDB.lib ${ETH_DEPENDENCY_INSTALL_DIR}/lib/leveldb.lib && cp -R include/leveldb ${ETH_DEPENDENCY_INSTALL_DIR}/include
)
else()
endif()

18
extdep/compile/leveldb_osx.patch

@ -0,0 +1,18 @@
--- Makefile 2014-11-07 00:54:05.000000000 +0100
+++ MakefilePatch 2014-11-07 00:56:59.000000000 +0100
@@ -17,11 +17,11 @@
# this file is generated by the previous line to set build flags and sources
include build_config.mk
-CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
-CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)
+CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)
+CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) -DSNAPPY -I$(ETH_DEPENDENCY_INSTALL_DIR)/include
-LDFLAGS += $(PLATFORM_LDFLAGS)
-LIBS += $(PLATFORM_LIBS)
+LDFLAGS += $(PLATFORM_LDFLAGS) -L$(ETH_DEPENDENCY_INSTALL_DIR)/lib
+LIBS += $(PLATFORM_LIBS) -lsnappy
LIBOBJECTS = $(SOURCES:.cc=.o)
MEMENVOBJECTS = $(MEMENV_SOURCES:.cc=.o)

32
extdep/compile/qt.cmake

@ -0,0 +1,32 @@
if (APPLE)
ExternalProject_add(qt
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz
BINARY_DIR qt-prefix/src/qt
PATCH_COMMAND patch -d qtmultimedia/src/plugins/avfoundation/mediaplayer < ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_osx.patch
CONFIGURE_COMMAND ./configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -system-zlib -qt-libpng -qt-libjpeg -confirm-license -opensource -nomake tests -release -nomake examples -no-xcb -arch x86_64
BUILD_COMMAND make
INSTALL_COMMAND make install
)
elseif(WIN32)
ExternalProject_Add(qt
DEPENDS icu jom
URL http://qtmirror.ics.com/pub/qtproject/official_releases/qt/5.3/5.3.2/single/qt-everywhere-opensource-src-5.3.2.tar.gz
BINARY_DIR qt-prefix/src/qt
UPDATE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_tools.bat
#PATCH_COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/compile/qt_configure.bat qtbase/configure.bat
CONFIGURE_COMMAND configure -prefix ${ETH_DEPENDENCY_INSTALL_DIR} -opensource -confirm-license -release -opengl desktop -platform win32-msvc2013 -icu -I ${ETH_DEPENDENCY_INSTALL_DIR}/include -L ${ETH_DEPENDENCY_INSTALL_DIR}/lib -nomake tests -nomake examples
BUILD_COMMAND nmake
INSTALL_COMMAND nmake install
)
ExternalProject_Add_Step(qt configure_paths
COMMAND set PATH=${ETH_DEPENDENCY_INSTALL_DIR}/bin;%cd%/gnuwin32/bin;%cd%/qtbase/bin;%PATH%
DEPENDEES patch
DEPENDERS configure
)
else()
endif()

111
extdep/compile/qt_configure.bat

@ -0,0 +1,111 @@
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
::
:: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
:: Contact: http://www.qt-project.org/legal
::
:: This file is part of the tools applications of the Qt Toolkit.
::
:: $QT_BEGIN_LICENSE:LGPL$
:: Commercial License Usage
:: Licensees holding valid commercial Qt licenses may use this file in
:: accordance with the commercial license agreement provided with the
:: Software or, alternatively, in accordance with the terms contained in
:: a written agreement between you and Digia. For licensing terms and
:: conditions see http://qt.digia.com/licensing. For further information
:: use the contact form at http://qt.digia.com/contact-us.
::
:: GNU Lesser General Public License Usage
:: Alternatively, this file may be used under the terms of the GNU Lesser
:: General Public License version 2.1 as published by the Free Software
:: Foundation and appearing in the file LICENSE.LGPL included in the
:: packaging of this file. Please review the following information to
:: ensure the GNU Lesser General Public License version 2.1 requirements
:: will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
::
:: In addition, as a special exception, Digia gives you certain additional
:: rights. These rights are described in the Digia Qt LGPL Exception
:: version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
::
:: GNU General Public License Usage
:: Alternatively, this file may be used under the terms of the GNU
:: General Public License version 3.0 as published by the Free Software
:: Foundation and appearing in the file LICENSE.GPL included in the
:: packaging of this file. Please review the following information to
:: ensure the GNU General Public License version 3.0 requirements will be
:: met: http://www.gnu.org/copyleft/gpl.html.
::
::
:: $QT_END_LICENSE$
::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@echo off
set QTSRC=%~dp0
set QTDIR=%CD%
::if not exist %QTSRC%\.gitignore goto sconf
echo Please wait while bootstrapping configure ...
for %%C in (cl.exe icl.exe g++.exe perl.exe) do set %%C=%%~$PATH:C
if "%perl.exe%" == "" (
echo Perl not found in PATH. Aborting. >&2
exit /b 1
)
if not exist mkspecs (
md mkspecs
if errorlevel 1 goto exit
)
perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir %QTDIR% %QTSRC%
if errorlevel 1 goto exit
if not exist tools\configure (
md tools\configure
if errorlevel 1 goto exit
)
cd tools\configure
if errorlevel 1 goto exit
echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile
echo/>> Makefile
for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%\src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile
if not "%cl.exe%" == "" (
echo CXX = cl>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
set make=nmake
) else if not "%icl.exe%" == "" (
echo CXX = icl>>Makefile
echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile
rem This must have a trailing space.
echo QTSRC = %QTSRC% >> Makefile
set tmpl=win32
set make=nmake
) else if not "%g++.exe%" == "" (
echo CXX = g++>>Makefile
echo EXTRA_CXXFLAGS =>>Makefile
rem This must NOT have a trailing space.
echo QTSRC = %QTSRC:\=/%>> Makefile
set tmpl=mingw
set make=mingw32-make
) else (
echo No suitable compiler found in PATH. Aborting. >&2
cd ..\..
exit /b 1
)
echo/>> Makefile
type %QTSRC%tools\configure\Makefile.%tmpl% >> Makefile
%make%
if errorlevel 1 (cd ..\.. & exit /b 1)
cd ..\..
:conf
configure.exe -srcdir %QTSRC% %*
goto exit
:sconf
%QTSRC%\configure.exe %*
:exit

11
extdep/compile/qt_osx.patch

@ -0,0 +1,11 @@
--- avfmediaplayersession.mm 2014-09-11 12:48:26.000000000 +0200
+++ avfmediaplayersessionPatch.mm 2014-12-01 12:53:14.000000000 +0100
@@ -295,7 +295,7 @@
//AVPlayerItem "status" property value observer.
if (context == AVFMediaPlayerSessionObserverStatusObservationContext)
{
- AVPlayerStatus status = [[change objectForKey:NSKeyValueChangeNewKey] integerValue];
+ AVPlayerStatus status = (AVPlayerStatus)[[change objectForKey:NSKeyValueChangeNewKey] integerValue];
switch (status)
{
//Indicates that the status of the player is not yet known because

2
extdep/compile/qt_tools.bat

@ -0,0 +1,2 @@
rem : import VC environment vars
call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86

14
extdep/compile/snappy.cmake

@ -0,0 +1,14 @@
if (APPLE)
ExternalProject_Add(snappy
URL https://snappy.googlecode.com/files/snappy-1.1.1.tar.gz
BINARY_DIR snappy-prefix/src/snappy
CONFIGURE_COMMAND ./configure --disable-dependency-tracking --prefix=${ETH_DEPENDENCY_INSTALL_DIR}
BUILD_COMMAND ""
INSTALL_COMMAND make install
)
elseif(WIN32)
else()
endif()

74
extdep/eth_download.cmake

@ -0,0 +1,74 @@
# this macro requires the following variables to be specified:
#
# ETH_DEPENDENCY_SERVER - server from which dependencies should be downloaded
# ETH_DEPENDENCY_INSTALL_DIR - install location for all dependencies
#
# usage:
#
# eth_download("json-rpc-cpp")
# eth_download("json-rpc-cpp" VERSION "0.3.2")
#
# params:
# VERSION - exact version we want to use
# OSX_SCRIPT - script which will be executed on apple in install phase
# UNIX_SCRIPT - script which will be executed on unix in install phase
# WIN_SCRIPT - script which will be executed on win in install phase
# OSX_SCRIPT, WIN_SCRIPT, UNIX_SCRIPT are taking 2 params:
# $1 is package_source,
# $2 is ETH_DEPENDENCY_INSTALL_DIR
#
# parsing arguments
# http://www.cmake.org/cmake/help/v3.0/module/CMakeParseArguments.html
#
# for macos you may need to specify OSX_SCRIPT with install_name_tool to fix dylib
# http://stackoverflow.com/questions/2985315/using-install-name-tool-whats-going-wrong
#
# TODO:
# check if install_command is handling symlinks correctly on linux and windows
macro(eth_download eth_package_name)
set (extra_macro_args ${ARGN})
set (options)
set (one_value_args VERSION OSX_SCRIPT UNIX_SCRIPT WIN_SCRIPT)
set (multi_value_args)
cmake_parse_arguments (ETH_DOWNLOAD "${options}" "${one_value_args}" "${multi_value_args}" ${extra_macro_args})
if (ETH_DOWNLOAD_VERSION)
set(eth_tar_name "${eth_package_name}-${ETH_DOWNLOAD_VERSION}.tar.gz")
else()
set(eth_tar_name "${eth_package_name}.tar.gz")
endif()
message(STATUS "download path for ${eth_package_name} is : ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}")
# we need that to copy symlinks
# see http://superuser.com/questions/138587/how-to-copy-symbolic-links
if (APPLE)
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_OSX_SCRIPT})
elseif (UNIX)
set (eth_package_copy cp -a . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_UNIX_SCRIPT})
else ()
set (eth_package_copy cmake -E copy_directory . ${ETH_DEPENDENCY_INSTALL_DIR})
set (eth_package_install ${ETH_DOWNLOAD_WIN_SCRIPT})
endif()
if (eth_package_install)
message(STATUS "install script: ${eth_package_install}")
set (eth_package_install ${eth_package_install} . ${ETH_DEPENDENCY_INSTALL_DIR})
else ()
set (eth_package_install echo 0) # cause empty string is not handled properly
endif()
ExternalProject_Add(${eth_package_name}
URL ${ETH_DEPENDENCY_SERVER}/${eth_tar_name}
BINARY_DIR ${eth_package_name}-prefix/src/${eth_package_name}
CONFIGURE_COMMAND ""
BUILD_COMMAND ${eth_package_copy}
INSTALL_COMMAND ${eth_package_install}
)
endmacro()

11
extdep/miniupnpc.cmake

@ -0,0 +1,11 @@
# TODO this file is not used yet, but will be in future
include(ExternalProject)
ExternalProject_Add(miniupnpc
URL http://miniupnp.tuxfamily.org/files/download.php?file=miniupnpc-1.9.20141027.tar.gz
BINARY_DIR miniupnpc-prefix/src/miniupnpc
CONFIGURE_COMMAND ""
BUILD_COMMAND make -j 3
INSTALL_COMMAND make install INSTALLPREFIX=${ETH_DEPENDENCY_INSTALL_DIR}
)

29
extdep/scripts/json-rpc-cpp_osx.sh

@ -0,0 +1,29 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
OLD_COMMON_DYLIB="libjsonrpccpp-common.0.dylib"
COMMON_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-common.0.dylib
SERVER_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-server.0.dylib
CLIENT_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libjsonrpccpp-client.0.dylib
# fix bin
STAB_EXEC=${ETH_DEPENDENCY_INSTALL_DIR}/bin/jsonrpcstub
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${STAB_EXEC}
# fix common
install_name_tool -id ${COMMON_DYLIB} ${COMMON_DYLIB}
# fix server
install_name_tool -id ${SERVER_DYLIB} ${SERVER_DYLIB}
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${SERVER_DYLIB}
# fix client
install_name_tool -id ${CLIENT_DYLIB} ${CLIENT_DYLIB}
install_name_tool -change ${OLD_COMMON_DYLIB} ${COMMON_DYLIB} ${CLIENT_DYLIB}
# TODO fix argtable and jsoncpp once they are downloaded as dependencies

12
extdep/scripts/leveldb_osx.sh

@ -0,0 +1,12 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
OLD_SNAPPY_DYLIB="/Users/marekkotewicz/ethereum/cpp-ethereum/extdep/install/darwin/lib/libsnappy.1.dylib"
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib
LEVELDB_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libleveldb.dylib
install_name_tool -id ${LEVELDB_DYLIB} ${LEVELDB_DYLIB}
install_name_tool -change ${OLD_SNAPPY_DYLIB} ${SNAPPY_DYLIB} ${LEVELDB_DYLIB}

8
extdep/scripts/snappy_osx.sh

@ -0,0 +1,8 @@
#!/bin/bash
ETH_DEPENDENCY_SOURCE_DIR=$1
ETH_DEPENDENCY_INSTALL_DIR=$2
SNAPPY_DYLIB=${ETH_DEPENDENCY_INSTALL_DIR}/lib/libsnappy.dylib
install_name_tool -id ${SNAPPY_DYLIB} ${SNAPPY_DYLIB}

117
iethxi/CMakeLists.txt

@ -1,117 +0,0 @@
cmake_policy(SET CMP0015 NEW)
if ("${TARGET_PLATFORM}" STREQUAL "w64")
cmake_policy(SET CMP0020 NEW)
endif ()
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST)
include_directories(..)
link_directories(../libethcore)
link_directories(../libethereum)
link_directories(../libqethereum)
# Find Qt5 for Apple and update src_list for windows
if (APPLE)
# homebrew defaults to qt4 and installs qt5 as 'keg-only'
# which places it into /usr/local/opt insteadof /usr/local.
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)
elseif (UNIX)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ";$ENV{QTDIR}/lib/cmake")
endif ()
find_package(Qt5Widgets REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Quick REQUIRED)
find_package(Qt5Qml REQUIRED)
find_package(Qt5Network REQUIRED)
qt5_wrap_ui(ui_Main.h Main.ui)
qt5_add_resources(RESOURCE_ADDED Resources.qrc)
# Set name of binary and add_executable()
if (APPLE)
set(EXECUTEABLE IEthXi)
set(CMAKE_INSTALL_PREFIX ./)
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})
include(BundleUtilities)
add_executable(${EXECUTEABLE} MACOSX_BUNDLE Main.ui ${RESOURCE_ADDED} ${SRC_LIST})
else ()
set(EXECUTEABLE iethxi)
add_executable(${EXECUTEABLE} Main.ui ${RESOURCE_ADDED} ${SRC_LIST})
endif ()
qt5_use_modules(${EXECUTEABLE} Core Gui Widgets Network Quick Qml)
target_link_libraries(${EXECUTEABLE} qethereum ethereum secp256k1 ${CRYPTOPP_LS})
if (APPLE)
if (${ADDFRAMEWORKS})
set_target_properties(${EXECUTEABLE} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/EthereumMacOSXBundleInfo.plist.in")
endif ()
SET_SOURCE_FILES_PROPERTIES(${EXECUTEABLE} PROPERTIES MACOSX_PACKAGE_LOCATION MacOS)
# This is a workaround for when the build-type defaults to Debug, and when a multi-config generator like xcode is used, where the type
# will not be set but defaults to release.
set(generator_lowercase "${CMAKE_GENERATOR}")
string(TOLOWER "${CMAKE_GENERATOR}" generator_lowercase)
if ("${generator_lowercase}" STREQUAL "xcode")
# TODO: Not sure how to resolve this. Possibly \${TARGET_BUILD_DIR}
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}/Debug")
else ()
set(binary_build_dir "${CMAKE_CURRENT_BINARY_DIR}")
endif ()
set(APPS ${binary_build_dir}/${EXECUTEABLE}.app)
# This tool and the next will automatically looked at the linked libraries in order to determine what dependencies are required. Thus, target_link_libaries only needs to add ethereum and secp256k1 (above)
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS 1)
fixup_bundle(\"${APPS}\" \"${BUNDLELIBS}\" \"../libqethereum ../libethereum ../secp256k1\")
" COMPONENT RUNTIME )
if (${ADDFRAMEWORKS})
add_custom_target(addframeworks ALL
COMMAND /usr/local/opt/qt5/bin/macdeployqt ${binary_build_dir}/${EXECUTEABLE}.app
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
DEPENDS ${PROJECT_NAME}
)
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 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} Qt5PlatformSupport)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
elseif (UNIX)
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 )
endif ()

38
iethxi/EthereumMacOSXBundleInfo.plist.in

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSRequiresCarbon</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

168
iethxi/Main.ui

@ -1,168 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Main</class>
<widget class="QMainWindow" name="Main">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>562</width>
<height>488</height>
</rect>
</property>
<property name="windowTitle">
<string>Walleth</string>
</property>
<property name="dockNestingEnabled">
<bool>true</bool>
</property>
<property name="dockOptions">
<set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::VerticalTabs</set>
</property>
<property name="sizeGripEnabled" stdset="0">
<bool>true</bool>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout" name="fullDisplay">
<item>
<widget class="QLabel" name="balance">
<property name="text">
<string>0 wei</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="peerCount">
<property name="text">
<string>0 peers</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="blockCount">
<property name="text">
<string>1 block</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>562</width>
<height>25</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
<property name="title">
<string>&amp;File</string>
</property>
<addaction name="quit"/>
</widget>
<widget class="QMenu" name="menu_Network">
<property name="title">
<string>&amp;Network</string>
</property>
<addaction name="upnp"/>
<addaction name="net"/>
<addaction name="connect"/>
</widget>
<widget class="QMenu" name="menu_Tools">
<property name="title">
<string>T&amp;ools</string>
</property>
<addaction name="mine"/>
<addaction name="create"/>
<addaction name="preview"/>
</widget>
<widget class="QMenu" name="menu_Help">
<property name="title">
<string>&amp;Help</string>
</property>
<addaction name="about"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Network"/>
<addaction name="menu_Tools"/>
<addaction name="menu_Help"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="quit">
<property name="text">
<string>&amp;Quit</string>
</property>
</action>
<action name="upnp">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>Use &amp;UPnP</string>
</property>
</action>
<action name="connect">
<property name="text">
<string>&amp;Connect to Peer...</string>
</property>
</action>
<action name="net">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Enable &amp;Network</string>
</property>
</action>
<action name="mine">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Mine</string>
</property>
</action>
<action name="create">
<property name="text">
<string>&amp;New Address</string>
</property>
</action>
<action name="about">
<property name="text">
<string>&amp;About...</string>
</property>
</action>
<action name="preview">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Preview</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

59
iethxi/MainWin.cpp

@ -1,59 +0,0 @@
#include <QtNetwork/QNetworkReply>
#include <QtQuick/QQuickView>
#include <QtQml/QQmlContext>
#include <QtQml/QQmlEngine>
#include <QtQml/QtQml>
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
#include <QtGui/QClipboard>
#include <QtCore/QtCore>
#include <libethcore/FileSystem.h>
#include <libethcore/Dagger.h>
#include <libevmface/Instruction.h>
#include <libethereum/Client.h>
#include <libethereum/EthereumHost.h>
#include "BuildInfo.h"
#include "MainWin.h"
#include "ui_Main.h"
using namespace std;
using namespace eth;
Main::Main(QWidget *parent) :
QObject(parent)
{
/* qRegisterMetaType<eth::u256>("eth::u256");
qRegisterMetaType<eth::KeyPair>("eth::KeyPair");
qRegisterMetaType<eth::Secret>("eth::Secret");
qRegisterMetaType<eth::Address>("eth::Address");
qRegisterMetaType<QmlAccount*>("QmlAccount*");
qRegisterMetaType<QmlEthereum*>("QmlEthereum*");
qmlRegisterType<QmlEthereum>("org.ethereum", 1, 0, "Ethereum");
qmlRegisterType<QmlAccount>("org.ethereum", 1, 0, "Account");
qmlRegisterSingletonType<QmlU256Helper>("org.ethereum", 1, 0, "Balance", QmlEthereum::constructU256Helper);
qmlRegisterSingletonType<QmlKeyHelper>("org.ethereum", 1, 0, "Key", QmlEthereum::constructKeyHelper);
*/
/*
ui->librariesView->setModel(m_libraryMan);
ui->graphsView->setModel(m_graphMan);
*/
// QQmlContext* context = m_view->rootContext();
// context->setContextProperty("u256", new U256Helper(this));
}
Main::~Main()
{
}
// extra bits needed to link on VS
#ifdef _MSC_VER
// include moc file, ofuscated to hide from automoc
#include\
"moc_MainWin.cpp"
#endif

18
iethxi/MainWin.h

@ -1,18 +0,0 @@
#ifndef MAIN_H
#define MAIN_H
#include <QtQml/QQmlApplicationEngine>
class Main: public QObject
{
Q_OBJECT
public:
explicit Main(QWidget *parent = 0);
~Main();
private:
QQmlApplicationEngine* m_view;
};
#endif // MAIN_H

5
iethxi/Resources.qrc

@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/">
<file>Simple.qml</file>
</qresource>
</RCC>

9
iethxi/Simple.qml

@ -1,9 +0,0 @@
import QtQuick.Controls 1.1
ApplicationWindow {
title: "My App"
Button {
text: "Push Me"
anchors.centerIn: parent
}
}

9
iethxi/main.cpp

@ -1,9 +0,0 @@
#include <QtQml/QQmlApplicationEngine>
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QQmlApplicationEngine app(QUrl("qrc:/Simple.qml"));
return a.exec();
}

8
libdevcore/All.h

@ -1,8 +0,0 @@
#pragma once
#include "Common.h"
#include "CommonData.h"
#include "CommonIO.h"
#include "FixedHash.h"
#include "Log.h"
#include "RLP.h"

48
libdevcore/CMakeLists.txt

@ -1,50 +1,42 @@
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0015 NEW)
# this policy was introduced in cmake 3.0
if (CMAKE_MAJOR_VERSION GREATER 1 AND CMAKE_MINOR_VERSION GREATER 7 AND CMAKE_PATCH_VERSION GREATER 11) # remove if, once 3.0 will be used on unix
cmake_policy(SET CMP0022 NEW) if (${CMAKE_MAJOR_VERSION} GREATER 2)
# old policy do not use MACOSX_RPATH
cmake_policy(SET CMP0042 OLD)
endif() endif()
set(CMAKE_AUTOMOC OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSTATICLIB")
aux_source_directory(. SRC_LIST) aux_source_directory(. SRC_LIST)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(..)
set(EXECUTABLE devcore) set(EXECUTABLE devcore)
# set(CMAKE_INSTALL_PREFIX ../lib) file(GLOB HEADERS "*.h")
if(ETH_STATIC) if(ETH_STATIC)
add_library(${EXECUTABLE} STATIC ${SRC_LIST}) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
else() else()
add_library(${EXECUTABLE} SHARED ${SRC_LIST}) add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
endif() endif()
file(GLOB HEADERS "*.h")
include_directories(..) target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${Boost_CHRONO_LIBRARIES})
target_link_libraries(${EXECUTABLE} devcore) if (APPLE)
if("${TARGET_PLATFORM}" STREQUAL "w64")
include_directories(/usr/x86_64-w64-mingw32/include/cryptopp)
target_link_libraries(${EXECUTABLE} boost_system-mt-s)
target_link_libraries(${EXECUTABLE} boost_thread_win32-mt-s)
target_link_libraries(${EXECUTABLE} iphlpapi)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
elseif (APPLE)
# Latest mavericks boost libraries only come with -mt
target_link_libraries(${EXECUTABLE} boost_system-mt)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt)
target_link_libraries(${EXECUTABLE} boost_thread-mt)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
elseif (UNIX) elseif (UNIX)
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY})
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
else ()
target_link_libraries(${EXECUTABLE} boost_thread)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT}) target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif () endif()
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev namespace dev
{ {
char const* Version = "0.6.9"; char const* Version = "0.7.13";
} }

45
libdevcore/Common.h

@ -38,8 +38,9 @@
#include <set> #include <set>
#include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_int.hpp>
#include "vector_ref.h" #include "vector_ref.h"
#include "debugbreak.h"
// CryptoPP defines byte in the global namespace, so so must we. // CryptoPP defines byte in the global namespace, so must we.
using byte = uint8_t; using byte = uint8_t;
// Quote a given token stream to turn it into a string. // Quote a given token stream to turn it into a string.
@ -58,6 +59,7 @@ using bytesConstRef = vector_ref<byte const>;
// Numeric types. // Numeric types.
using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>; using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
using u128 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>; using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>; using u160 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<160, 160, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
@ -103,4 +105,45 @@ inline unsigned int toLog2(u256 _x)
return ret; return ret;
} }
// Assertions...
#if defined(_MSC_VER)
#define ETH_FUNC __FUNCSIG__
#elif defined(__GNUC__)
#define ETH_FUNC __PRETTY_FUNCTION__
#else
#define ETH_FUNC __func__
#endif
#define asserts(A) ::dev::assertAux(A, #A, __LINE__, __FILE__, ETH_FUNC)
#define assertsEqual(A, B) ::dev::assertEqualAux(A, B, #A, #B, __LINE__, __FILE__, ETH_FUNC)
inline bool assertAux(bool _a, char const* _aStr, unsigned _line, char const* _file, char const* _func)
{
bool ret = _a;
if (!ret)
{
std::cerr << "Assertion failed:" << _aStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
#if ETH_DEBUG
debug_break();
#endif
}
return !ret;
}
template<class A, class B>
inline bool assertEqualAux(A const& _a, B const& _b, char const* _aStr, char const* _bStr, unsigned _line, char const* _file, char const* _func)
{
bool ret = _a == _b;
if (!ret)
{
std::cerr << "Assertion failed: " << _aStr << " == " << _bStr << " [func=" << _func << ", line=" << _line << ", file=" << _file << "]" << std::endl;
std::cerr << " Fail equality: " << _a << "==" << _b << std::endl;
#if ETH_DEBUG
debug_break();
#endif
}
return !ret;
}
} }

30
libdevcore/CommonData.cpp

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file Common.cpp /** @file CommonData.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
*/ */
@ -23,19 +23,27 @@
#include <random> #include <random>
#include "Exceptions.h" #include "Exceptions.h"
#include "Log.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
std::string dev::escaped(std::string const& _s, bool _all) std::string dev::escaped(std::string const& _s, bool _all)
{ {
static const map<char, char> prettyEscapes{{'\r', 'r'}, {'\n', 'n'}, {'\t', 't'}, {'\v', 'v'}};
std::string ret; std::string ret;
ret.reserve(_s.size()); ret.reserve(_s.size() + 2);
ret.push_back('"'); ret.push_back('"');
for (auto i: _s) for (auto i: _s)
if (i == '"' && !_all) if (i == '"' && !_all)
ret += "\\\""; ret += "\\\"";
else if (i == '\\' && !_all) else if (i == '\\' && !_all)
ret += "\\\\"; ret += "\\\\";
else if (prettyEscapes.count(i))
{
ret += '\\';
ret += prettyEscapes.find(i)->second;
}
else if (i < ' ' || _all) else if (i < ' ' || _all)
{ {
ret += "\\x"; ret += "\\x";
@ -67,7 +75,7 @@ int dev::fromHex(char _i)
return _i - 'a' + 10; return _i - 'a' + 10;
if (_i >= 'A' && _i <= 'F') if (_i >= 'A' && _i <= 'F')
return _i - 'A' + 10; return _i - 'A' + 10;
throw BadHexCharacter(); BOOST_THROW_EXCEPTION(BadHexCharacter() << errinfo_invalidSymbol(_i));
} }
bytes dev::fromHex(std::string const& _s) bytes dev::fromHex(std::string const& _s)
@ -81,13 +89,25 @@ bytes dev::fromHex(std::string const& _s)
{ {
ret.push_back(fromHex(_s[s++])); ret.push_back(fromHex(_s[s++]));
} }
catch (...){ ret.push_back(0); } catch (...)
{
ret.push_back(0);
// msvc does not support it
#ifndef BOOST_NO_EXCEPTIONS
cwarn << boost::current_exception_diagnostic_information();
#endif
}
for (unsigned i = s; i < _s.size(); i += 2) for (unsigned i = s; i < _s.size(); i += 2)
try try
{ {
ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1]))); ret.push_back((byte)(fromHex(_s[i]) * 16 + fromHex(_s[i + 1])));
} }
catch (...){ ret.push_back(0); } catch (...){
ret.push_back(0);
#ifndef BOOST_NO_EXCEPTIONS
cwarn << boost::current_exception_diagnostic_information();
#endif
}
return ret; return ret;
} }

32
libdevcore/CommonData.h

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file Common.h /** @file CommonData.h
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
* *
@ -190,7 +190,7 @@ void pushFront(_T& _t, _U _e)
_t[0] = _e; _t[0] = _e;
} }
/// Concatenate two vectors of elements. _T must be POD. /// Concatenate two vectors of elements of POD types.
template <class _T> template <class _T>
inline std::vector<_T>& operator+=(std::vector<typename std::enable_if<std::is_pod<_T>::value, _T>::type>& _a, std::vector<_T> const& _b) inline std::vector<_T>& operator+=(std::vector<typename std::enable_if<std::is_pod<_T>::value, _T>::type>& _a, std::vector<_T> const& _b)
{ {
@ -201,30 +201,38 @@ inline std::vector<_T>& operator+=(std::vector<typename std::enable_if<std::is_p
} }
/// Concatenate two vectors of elements. _T must be POD. /// Concatenate two vectors of elements.
template <class _T> template <class _T>
inline std::vector<_T> operator+(std::vector<typename std::enable_if<std::is_pod<_T>::value, _T>::type> const& _a, std::vector<_T> const& _b) inline std::vector<_T>& operator+=(std::vector<typename std::enable_if<!std::is_pod<_T>::value, _T>::type>& _a, std::vector<_T> const& _b)
{
_a.reserve(_a.size() + _b.size());
for (auto& i: _b)
_a.push_back(i);
return _a;
}
/// Concatenate two vectors of elements.
template <class _T>
inline std::vector<_T> operator+(std::vector<_T> const& _a, std::vector<_T> const& _b)
{ {
std::vector<_T> ret(_a); std::vector<_T> ret(_a);
return ret += _b; return ret += _b;
} }
/// Concatenate two vectors of elements. _T must be POD. /// Merge two sets of elements.
template <class _T> template <class _T>
inline std::vector<_T>& operator+=(std::vector<typename std::enable_if<!std::is_pod<_T>::value, _T>::type>& _a, std::vector<_T> const& _b) inline std::set<_T>& operator+=(std::set<_T>& _a, std::set<_T> const& _b)
{ {
_a.reserve(_a.size() + _b.size());
for (auto& i: _b) for (auto& i: _b)
_a.push_back(i); _a.insert(i);
return _a; return _a;
} }
/// Concatenate two vectors of elements. _T must be POD. /// Merge two sets of elements.
template <class _T> template <class _T>
inline std::vector<_T> operator+(std::vector<typename std::enable_if<!std::is_pod<_T>::value, _T>::type> const& _a, std::vector<_T> const& _b) inline std::set<_T> operator+(std::set<_T> const& _a, std::set<_T> const& _b)
{ {
std::vector<_T> ret(_a); std::set<_T> ret(_a);
return ret += _b; return ret += _b;
} }

4
libdevcore/CommonIO.cpp

@ -19,7 +19,7 @@
* @date 2014 * @date 2014
*/ */
#include "Common.h" #include "CommonIO.h"
#include <fstream> #include <fstream>
#include "Exceptions.h" #include "Exceptions.h"
@ -30,7 +30,7 @@ string dev::memDump(bytes const& _b, unsigned _w, bool _html)
{ {
stringstream ret; stringstream ret;
if (_html) if (_html)
ret << "<pre style=\"font-family: Monospace, sans-serif; font-size: small\">"; ret << "<pre style=\"font-family: Monospace,Lucida Console,Courier,Courier New,sans-serif; font-size: small\">";
for (unsigned i = 0; i < _b.size(); i += _w) for (unsigned i = 0; i < _b.size(); i += _w)
{ {
ret << hex << setw(4) << setfill('0') << i << " "; ret << hex << setw(4) << setfill('0') << i << " ";

12
libdevcore/CommonIO.h

@ -55,6 +55,18 @@ std::string memDump(bytes const& _b, unsigned _w = 8, bool _html = false);
template <class S, class T> struct StreamOut { static S& bypass(S& _out, T const& _t) { _out << _t; return _out; } }; template <class S, class T> struct StreamOut { static S& bypass(S& _out, T const& _t) { _out << _t; return _out; } };
template <class S> struct StreamOut<S, uint8_t> { static S& bypass(S& _out, uint8_t const& _t) { _out << (int)_t; return _out; } }; template <class S> struct StreamOut<S, uint8_t> { static S& bypass(S& _out, uint8_t const& _t) { _out << (int)_t; return _out; } };
template <class T> inline std::ostream& operator<<(std::ostream& _out, std::vector<T> const& _e);
template <class T, unsigned Z> inline std::ostream& operator<<(std::ostream& _out, std::array<T, Z> const& _e);
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::pair<T, U> const& _e);
template <class T> inline std::ostream& operator<<(std::ostream& _out, std::list<T> const& _e);
template <class T1, class T2, class T3> inline std::ostream& operator<<(std::ostream& _out, std::tuple<T1, T2, T3> const& _e);
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::map<T, U> const& _e);
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::unordered_map<T, U> const& _e);
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::set<T, U> const& _e);
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::unordered_set<T, U> const& _e);
template <class T, class U> inline std::ostream& operator<<(std::ostream& _out, std::multimap<T, U> const& _e);
template <class _S, class _T> _S& operator<<(_S& _out, std::shared_ptr<_T> const& _p);
template <class S, class T> template <class S, class T>
inline S& streamout(S& _out, std::vector<T> const& _e) inline S& streamout(S& _out, std::vector<T> const& _e)
{ {

117
libdevcore/CommonJS.cpp

@ -0,0 +1,117 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/** @file CommonJS.cpp
* @authors:
* Gav Wood <i@gavwood.com>
* Marek Kotewicz <marek@ethdev.com>
* @date 2014
*/
#include "CommonJS.h"
namespace dev
{
bytes jsToBytes(std::string const& _s)
{
if (_s.substr(0, 2) == "0x")
// Hex
return fromHex(_s.substr(2));
else if (_s.find_first_not_of("0123456789") == std::string::npos)
// Decimal
return toCompactBigEndian(bigint(_s));
else
return bytes();
}
bytes padded(bytes _b, unsigned _l)
{
while (_b.size() < _l)
_b.insert(_b.begin(), 0);
while (_b.size() < _l)
_b.push_back(0);
return asBytes(asString(_b).substr(_b.size() - std::max(_l, _l)));
}
bytes unpadded(bytes _b)
{
auto p = asString(_b).find_last_not_of((char)0);
_b.resize(p == std::string::npos ? 0 : (p + 1));
return _b;
}
std::string prettyU256(u256 _n)
{
unsigned inc = 0;
std::string raw;
std::ostringstream s;
if (!(_n >> 64))
s << " " << (uint64_t)_n << " (0x" << (uint64_t)_n << ")";
else if (!~(_n >> 64))
s << " " << (int64_t)_n << " (0x" << (int64_t)_n << ")";
else if ((_n >> 160) == 0)
{
Address a = right160(_n);
std::string n = a.abridged();
if (n.empty())
s << "0x" << a;
else
s << n << "(0x" << a.abridged() << ")";
}
else if ((raw = fromRaw((h256)_n, &inc)).size())
return "\"" + raw + "\"" + (inc ? " + " + std::to_string(inc) : "");
else
s << "" << (h256)_n;
return s.str();
}
std::string fromRaw(h256 _n, unsigned* _inc)
{
if (_n)
{
std::string s((char const*)_n.data(), 32);
auto l = s.find_first_of('\0');
if (!l)
return "";
if (l != std::string::npos)
{
auto p = s.find_first_not_of('\0', l);
if (!(p == std::string::npos || (_inc && p == 31)))
return "";
if (_inc)
*_inc = (byte)s[31];
s.resize(l);
}
for (auto i: s)
if (i < 32)
return "";
return s;
}
return "";
}
Address fromString(std::string const& _sn)
{
if (_sn.size() == 40)
return Address(fromHex(_sn));
else
return Address();
}
}

77
eth/CommonJS.h → libdevcore/CommonJS.h

@ -17,27 +17,41 @@
/** @file CommonJS.h /** @file CommonJS.h
* @authors: * @authors:
* Gav Wood <i@gavwood.com> * Gav Wood <i@gavwood.com>
* Marek Kotewicz <marek@ethdev.com>
* @date 2014 * @date 2014
*/ */
#pragma once #pragma once
#include <string> #include <string>
#include <libdevcore/Common.h> #include <libethereum/Interface.h>
#include <libdevcore/CommonIO.h> #include "Common.h"
#include <libdevcore/CommonData.h> #include "CommonData.h"
#include <libdevcore/FixedHash.h>
#include <libethcore/CommonEth.h>
namespace dev namespace dev
{ {
namespace eth
template <unsigned S> std::string toJS(FixedHash<S> const& _h)
{
return "0x" + toHex(_h.ref());
}
template <unsigned N> std::string toJS(boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N, N, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>> const& _n)
{
return "0x" + toHex(toCompactBigEndian(_n));
}
inline std::string toJS(dev::bytes const& _n)
{ {
return "0x" + dev::toHex(_n);
}
bytes jsToBytes(std::string const& _s); bytes jsToBytes(std::string const& _s);
std::string jsPadded(std::string const& _s, unsigned _l, unsigned _r); bytes padded(bytes _b, unsigned _l);
std::string jsPadded(std::string const& _s, unsigned _l); bytes unpadded(bytes _s);
std::string jsUnpadded(std::string _s); std::string prettyU256(u256 _n);
std::string fromRaw(h256 _n, unsigned* _inc = nullptr);
Address fromString(std::string const& _a);
template <unsigned N> FixedHash<N> jsToFixed(std::string const& _s) template <unsigned N> FixedHash<N> jsToFixed(std::string const& _s)
{ {
@ -49,7 +63,12 @@ template <unsigned N> FixedHash<N> jsToFixed(std::string const& _s)
return (typename FixedHash<N>::Arith)(_s); return (typename FixedHash<N>::Arith)(_s);
else else
// Binary // Binary
return FixedHash<N>(asBytes(jsPadded(_s, N))); return FixedHash<N>(); // FAIL
}
inline std::string jsToFixed(double _s)
{
return toJS(dev::u256(_s * (double)(dev::u256(1) << 128)));
} }
template <unsigned N> boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>> jsToInt(std::string const& _s) template <unsigned N> boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>> jsToInt(std::string const& _s)
@ -62,30 +81,48 @@ template <unsigned N> boost::multiprecision::number<boost::multiprecision::cpp_i
return boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>(_s); return boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>(_s);
else else
// Binary // Binary
return fromBigEndian<boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>>(asBytes(jsPadded(_s, N))); return 0; // FAIL
} }
inline Address jsToAddress(std::string const& _s) { return jsToFixed<20>(_s); } inline Address jsToAddress(std::string const& _s) { return jsToFixed<sizeof(dev::Address)>(_s); }
inline Secret jsToSecret(std::string const& _s) { return jsToFixed<32>(_s); } inline Public jsToPublic(std::string const& _s) { return jsToFixed<sizeof(dev::Public)>(_s); }
inline Secret jsToSecret(std::string const& _s) { return jsToFixed<sizeof(dev::Secret)>(_s); }
inline u256 jsToU256(std::string const& _s) { return jsToInt<32>(_s); } inline u256 jsToU256(std::string const& _s) { return jsToInt<32>(_s); }
template <unsigned S> std::string toJS(FixedHash<S> const& _h) { return "0x" + toHex(_h.ref()); }
template <unsigned N> std::string toJS(boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N, N, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>> const& _n) { return "0x" + toHex(toCompactBigEndian(_n)); }
inline std::string jsToBinary(std::string const& _s) inline std::string jsToBinary(std::string const& _s)
{ {
return asString(jsToBytes(_s)); return dev::toString(unpadded(jsToBytes(_s)));
} }
inline std::string jsToDecimal(std::string const& _s) inline std::string jsToDecimal(std::string const& _s)
{ {
return toString(jsToU256(_s)); return dev::toString(jsToU256(_s));
} }
inline std::string jsToHex(std::string const& _s) inline std::string jsFromBinary(dev::bytes _s, unsigned _padding = 32)
{ {
return "0x" + toHex(asBytes(_s)); _s.resize(std::max<unsigned>(_s.size(), _padding));
return "0x" + dev::toHex(_s);
} }
inline std::string jsFromBinary(std::string const& _s, unsigned _padding = 32)
{
return jsFromBinary(asBytes(_s), _padding);
} }
inline double jsFromFixed(std::string const& _s)
{
return (double)jsToU256(_s) / (double)(dev::u256(1) << 128);
}
struct TransactionSkeleton
{
Address from;
Address to;
u256 value;
bytes data;
u256 gas;
u256 gasPrice;
};
} }

39
libdevcore/Exceptions.h

@ -22,27 +22,30 @@
#pragma once #pragma once
#include <exception> #include <exception>
#include "CommonIO.h" #include <boost/exception/all.hpp>
#include <boost/throw_exception.hpp>
#include "CommonData.h" #include "CommonData.h"
#include "FixedHash.h" #include "FixedHash.h"
namespace dev namespace dev
{ {
// base class for all exceptions
class Exception: public std::exception struct Exception: virtual std::exception, virtual boost::exception {};
{
public: struct BadHexCharacter: virtual Exception {};
virtual std::string description() const { return typeid(*this).name(); } struct RLPException: virtual Exception {};
virtual char const* what() const noexcept { return typeid(*this).name(); } struct BadCast: virtual RLPException {};
}; struct BadRLP: virtual RLPException {};
struct NoNetworking: virtual Exception {};
class BadHexCharacter: public Exception {}; struct NoUPnPDevice: virtual Exception {};
struct RootNotFound: virtual Exception {};
class RLPException: public Exception {}; struct FileError: virtual Exception {};
class BadCast: public RLPException {};
class BadRLP: public RLPException {}; // error information to be added to exceptions
class NoNetworking: public Exception {}; typedef boost::error_info<struct tag_invalidSymbol, char> errinfo_invalidSymbol;
class NoUPnPDevice: public Exception {}; typedef boost::error_info<struct tag_address, std::string> errinfo_wrongAddress;
class RootNotFound: public Exception {}; typedef boost::error_info<struct tag_comment, std::string> errinfo_comment;
typedef boost::error_info<struct tag_required, bigint> errinfo_required;
typedef boost::error_info<struct tag_got, bigint> errinfo_got;
typedef boost::tuple<errinfo_required, errinfo_got> RequirementError;
} }

49
libdevcore/FixedHash.h

@ -59,7 +59,7 @@ public:
FixedHash() { m_data.fill(0); } FixedHash() { m_data.fill(0); }
/// Construct from another hash, filling with zeroes or cropping as necessary. /// Construct from another hash, filling with zeroes or cropping as necessary.
template <unsigned M> FixedHash(FixedHash<M> const& _h, ConstructFromHashType _t = AlignLeft) { m_data.fill(0); unsigned c = std::min(M, N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i]; } template <unsigned M> explicit FixedHash(FixedHash<M> const& _h, ConstructFromHashType _t = AlignLeft) { m_data.fill(0); unsigned c = std::min(M, N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i]; }
/// Convert from the corresponding arithmetic type. /// Convert from the corresponding arithmetic type.
FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); } FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); }
@ -83,6 +83,7 @@ public:
bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; } bool operator==(FixedHash const& _c) const { return m_data == _c.m_data; }
bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; } bool operator!=(FixedHash const& _c) const { return m_data != _c.m_data; }
bool operator<(FixedHash const& _c) const { return m_data < _c.m_data; } bool operator<(FixedHash const& _c) const { return m_data < _c.m_data; }
bool operator>=(FixedHash const& _c) const { return m_data >= _c.m_data; }
// The obvious binary operators. // The obvious binary operators.
FixedHash& operator^=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] ^= _c.m_data[i]; return *this; } FixedHash& operator^=(FixedHash const& _c) { for (unsigned i = 0; i < N; ++i) m_data[i] ^= _c.m_data[i]; return *this; }
@ -158,6 +159,49 @@ public:
return ret; return ret;
} }
template <unsigned P, unsigned M> inline FixedHash& shiftBloom(FixedHash<M> const& _h)
{
return (*this |= _h.template nbloom<P, N>());
}
template <unsigned P, unsigned M> inline bool containsBloom(FixedHash<M> const& _h)
{
return contains(_h.template nbloom<P, N>());
}
template <unsigned P, unsigned M> inline FixedHash<M> nbloom() const
{
static const unsigned c_bloomBits = M * 8;
unsigned mask = c_bloomBits - 1;
unsigned bloomBytes = (dev::toLog2(c_bloomBits) + 7) / 8;
FixedHash<M> ret;
byte const* p = data();
for (unsigned i = 0; i < P; ++i)
{
unsigned index = 0;
for (unsigned j = 0; j < bloomBytes; ++j, ++p)
index = (index << 8) | *p;
index &= mask;
ret[M - 1 - index / 8] |= (1 << (index % 8));
}
return ret;
}
/// Returns the index of the first bit set to one, or size() * 8 if no bits are set.
inline unsigned firstBitSet() const
{
unsigned ret = 0;
for (auto d: m_data)
if (d)
for (;; ++ret, d <<= 1)
if (d & 0x80)
return ret;
else {}
else
ret += 8;
return ret;
}
private: private:
std::array<byte, N> m_data; ///< The binary data. std::array<byte, N> m_data; ///< The binary data.
}; };
@ -193,9 +237,12 @@ inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)
} }
// Common types of FixedHash. // Common types of FixedHash.
using h520 = FixedHash<65>;
using h512 = FixedHash<64>; using h512 = FixedHash<64>;
using h256 = FixedHash<32>; using h256 = FixedHash<32>;
using h160 = FixedHash<20>; using h160 = FixedHash<20>;
using h128 = FixedHash<16>;
using h512s = std::vector<h512>;
using h256s = std::vector<h256>; using h256s = std::vector<h256>;
using h160s = std::vector<h160>; using h160s = std::vector<h160>;
using h256Set = std::set<h256>; using h256Set = std::set<h256>;

1
libdevcore/Log.h

@ -27,6 +27,7 @@
#include <chrono> #include <chrono>
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include "vector_ref.h" #include "vector_ref.h"
#include "CommonIO.h"
namespace dev namespace dev
{ {

11
libdevcore/RLP.cpp

@ -104,13 +104,13 @@ bool RLP::isInt() const
else if (n <= c_rlpDataIndLenZero) else if (n <= c_rlpDataIndLenZero)
{ {
if (m_data.size() <= 1) if (m_data.size() <= 1)
throw BadRLP(); BOOST_THROW_EXCEPTION(BadRLP());
return m_data[1] != 0; return m_data[1] != 0;
} }
else if (n < c_rlpListStart) else if (n < c_rlpListStart)
{ {
if ((int)m_data.size() <= 1 + n - c_rlpDataIndLenZero) if ((int)m_data.size() <= 1 + n - c_rlpDataIndLenZero)
throw BadRLP(); BOOST_THROW_EXCEPTION(BadRLP());
return m_data[1 + n - c_rlpDataIndLenZero] != 0; return m_data[1 + n - c_rlpDataIndLenZero] != 0;
} }
else else
@ -131,7 +131,7 @@ unsigned RLP::length() const
else if (n < c_rlpListStart) else if (n < c_rlpListStart)
{ {
if ((int)m_data.size() <= n - c_rlpDataIndLenZero) if ((int)m_data.size() <= n - c_rlpDataIndLenZero)
throw BadRLP(); BOOST_THROW_EXCEPTION(BadRLP());
for (int i = 0; i < n - c_rlpDataIndLenZero; ++i) for (int i = 0; i < n - c_rlpDataIndLenZero; ++i)
ret = (ret << 8) | m_data[i + 1]; ret = (ret << 8) | m_data[i + 1];
} }
@ -140,7 +140,7 @@ unsigned RLP::length() const
else else
{ {
if ((int)m_data.size() <= n - c_rlpListIndLenZero) if ((int)m_data.size() <= n - c_rlpListIndLenZero)
throw BadRLP(); BOOST_THROW_EXCEPTION(BadRLP());
for (int i = 0; i < n - c_rlpListIndLenZero; ++i) for (int i = 0; i < n - c_rlpListIndLenZero; ++i)
ret = (ret << 8) | m_data[i + 1]; ret = (ret << 8) | m_data[i + 1];
} }
@ -176,7 +176,8 @@ void RLPStream::noteAppended(unsigned _itemCount)
// cdebug << "noteAppended(" << _itemCount << ")"; // cdebug << "noteAppended(" << _itemCount << ")";
while (m_listStack.size()) while (m_listStack.size())
{ {
assert(m_listStack.back().first >= _itemCount); if (m_listStack.back().first < _itemCount)
BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("itemCount too large"));
m_listStack.back().first -= _itemCount; m_listStack.back().first -= _itemCount;
if (m_listStack.back().first) if (m_listStack.back().first)
break; break;

38
libdevcore/RLP.h

@ -28,10 +28,10 @@
#include <exception> #include <exception>
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <libdevcore/vector_ref.h> #include "vector_ref.h"
#include <libdevcore/Common.h> #include "Common.h"
#include <libdevcore/Exceptions.h> #include "Exceptions.h"
#include <libdevcore/FixedHash.h> #include "FixedHash.h"
namespace dev namespace dev
{ {
@ -100,11 +100,11 @@ public:
/// @returns the number of items in the list, or zero if it isn't a list. /// @returns the number of items in the list, or zero if it isn't a list.
unsigned itemCount() const { return isList() ? items() : 0; } unsigned itemCount() const { return isList() ? items() : 0; }
unsigned itemCountStrict() const { if (!isList()) throw BadCast(); return items(); } unsigned itemCountStrict() const { if (!isList()) BOOST_THROW_EXCEPTION(BadCast()); return items(); }
/// @returns the number of bytes in the data, or zero if it isn't data. /// @returns the number of bytes in the data, or zero if it isn't data.
unsigned size() const { return isData() ? length() : 0; } unsigned size() const { return isData() ? length() : 0; }
unsigned sizeStrict() const { if (!isData()) throw BadCast(); return length(); } unsigned sizeStrict() const { if (!isData()) BOOST_THROW_EXCEPTION(BadCast()); return length(); }
/// Equality operators; does best-effort conversion and checks for equality. /// Equality operators; does best-effort conversion and checks for equality.
bool operator==(char const* _s) const { return isData() && toString() == _s; } bool operator==(char const* _s) const { return isData() && toString() == _s; }
@ -158,8 +158,13 @@ public:
/// Best-effort conversion operators. /// Best-effort conversion operators.
explicit operator std::string() const { return toString(); } explicit operator std::string() const { return toString(); }
explicit operator bytes() const { return toBytes(); }
explicit operator RLPs() const { return toList(); } explicit operator RLPs() const { return toList(); }
explicit operator byte() const { return toInt<byte>(); } explicit operator uint8_t() const { return toInt<uint8_t>(); }
explicit operator uint16_t() const { return toInt<uint16_t>(); }
explicit operator uint32_t() const { return toInt<uint32_t>(); }
explicit operator uint64_t() const { return toInt<uint64_t>(); }
explicit operator u160() const { return toInt<u160>(); }
explicit operator u256() const { return toInt<u256>(); } explicit operator u256() const { return toInt<u256>(); }
explicit operator bigint() const { return toInt<bigint>(); } explicit operator bigint() const { return toInt<bigint>(); }
template <unsigned _N> explicit operator FixedHash<_N>() const { return toHash<FixedHash<_N>>(); } template <unsigned _N> explicit operator FixedHash<_N>() const { return toHash<FixedHash<_N>>(); }
@ -175,7 +180,7 @@ public:
/// Converts to string. @returns the empty string if not a string. /// Converts to string. @returns the empty string if not a string.
std::string toString() const { if (!isData()) return std::string(); return payload().cropped(0, length()).toString(); } std::string toString() const { if (!isData()) return std::string(); return payload().cropped(0, length()).toString(); }
/// Converts to string. @throws BadCast if not a string. /// Converts to string. @throws BadCast if not a string.
std::string toStringStrict() const { if (!isData()) throw BadCast(); return payload().cropped(0, length()).toString(); } std::string toStringStrict() const { if (!isData()) BOOST_THROW_EXCEPTION(BadCast()); return payload().cropped(0, length()).toString(); }
template <class T> template <class T>
std::vector<T> toVector() const std::vector<T> toVector() const
@ -222,7 +227,7 @@ public:
std::array<T, N> toArray() const std::array<T, N> toArray() const
{ {
if (itemCount() != N || !isList()) if (itemCount() != N || !isList())
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
std::array<T, N> ret; std::array<T, N> ret;
for (unsigned i = 0; i < N; ++i) for (unsigned i = 0; i < N; ++i)
{ {
@ -246,7 +251,7 @@ public:
{ {
if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull()) if ((!isInt() && !(_flags & AllowNonCanon)) || isList() || isNull())
if (_flags & ThrowOnFail) if (_flags & ThrowOnFail)
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
else else
return 0; return 0;
else {} else {}
@ -254,7 +259,7 @@ public:
auto p = payload(); auto p = payload();
if (p.size() > intTraits<_T>::maxSize && (_flags & FailIfTooBig)) if (p.size() > intTraits<_T>::maxSize && (_flags & FailIfTooBig))
if (_flags & ThrowOnFail) if (_flags & ThrowOnFail)
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
else else
return 0; return 0;
else {} else {}
@ -266,7 +271,7 @@ public:
{ {
if (!isData() || (length() > _N::size && (_flags & FailIfTooBig))) if (!isData() || (length() > _N::size && (_flags & FailIfTooBig)))
if (_flags & ThrowOnFail) if (_flags & ThrowOnFail)
throw BadCast(); BOOST_THROW_EXCEPTION(BadCast());
else else
return _N(); return _N();
else{} else{}
@ -288,6 +293,9 @@ public:
unsigned actualSize() const; unsigned actualSize() const;
private: private:
/// Disable construction from rvalue
explicit RLP(bytes const&&) {}
/// Single-byte data payload. /// Single-byte data payload.
bool isSingleByte() const { return !isNull() && m_data[0] < c_rlpDataImmLenStart; } bool isSingleByte() const { return !isNull() && m_data[0] < c_rlpDataImmLenStart; }
@ -334,7 +342,7 @@ public:
RLPStream& append(char const* _s) { return append(std::string(_s)); } RLPStream& append(char const* _s) { return append(std::string(_s)); }
template <unsigned N> RLPStream& append(FixedHash<N> _s, bool _compact = false, bool _allOrNothing = false) { return _allOrNothing && !_s ? append(bytesConstRef()) : append(_s.ref(), _compact); } template <unsigned N> RLPStream& append(FixedHash<N> _s, bool _compact = false, bool _allOrNothing = false) { return _allOrNothing && !_s ? append(bytesConstRef()) : append(_s.ref(), _compact); }
/// Appends an arbitrary RLP fragment - this *must* be a single item. /// Appends an arbitrary RLP fragment - this *must* be a single item unless @a _itemCount is given.
RLPStream& append(RLP const& _rlp, unsigned _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); } RLPStream& append(RLP const& _rlp, unsigned _itemCount = 1) { return appendRaw(_rlp.data(), _itemCount); }
/// Appends a sequence of data to the stream as a list. /// Appends a sequence of data to the stream as a list.
@ -361,10 +369,10 @@ public:
void clear() { m_out.clear(); m_listStack.clear(); } void clear() { m_out.clear(); m_listStack.clear(); }
/// Read the byte stream. /// Read the byte stream.
bytes const& out() const { assert(m_listStack.empty()); return m_out; } bytes const& out() const { if(!m_listStack.empty()) BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("listStack is not empty")); return m_out; }
/// Swap the contents of the output stream out for some other byte array. /// Swap the contents of the output stream out for some other byte array.
void swapOut(bytes& _dest) { assert(m_listStack.empty()); swap(m_out, _dest); } void swapOut(bytes& _dest) { if(!m_listStack.empty()) BOOST_THROW_EXCEPTION(RLPException() << errinfo_comment("listStack is not empty")); swap(m_out, _dest); }
private: private:
void noteAppended(unsigned _itemCount = 1); void noteAppended(unsigned _itemCount = 1);

39
libdevcore/RangeMask.h

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file EthereumHost.h /** @file RangeMask.h
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
*/ */
@ -43,10 +43,11 @@ public:
using Range = std::pair<T, T>; using Range = std::pair<T, T>;
using Ranges = std::vector<Range>; using Ranges = std::vector<Range>;
RangeMask() {} RangeMask(): m_all(0, 0) {}
RangeMask(T _begin, T _end): m_all(_begin, _end) {} RangeMask(T _begin, T _end): m_all(_begin, _end) {}
RangeMask(Range const& _c): m_all(_c) {} RangeMask(Range const& _c): m_all(_c) {}
RangeMask unionedWith(RangeMask const& _m) const { return operator+(_m); }
RangeMask operator+(RangeMask const& _m) const { return RangeMask(*this) += _m; } RangeMask operator+(RangeMask const& _m) const { return RangeMask(*this) += _m; }
RangeMask lowest(T _items) const RangeMask lowest(T _items) const
@ -57,7 +58,9 @@ public:
return ret; return ret;
} }
RangeMask operator~() const RangeMask operator~() const { return inverted(); }
RangeMask inverted() const
{ {
RangeMask ret(m_all); RangeMask ret(m_all);
T last = m_all.first; T last = m_all.first;
@ -72,16 +75,28 @@ public:
return ret; return ret;
} }
RangeMask& operator+=(RangeMask const& _m) RangeMask& invert() { return *this = inverted(); }
template <class S> RangeMask operator-(S const& _m) const { auto ret = *this; return ret -= _m; }
template <class S> RangeMask& operator-=(S const& _m) { return invert().unionWith(_m).invert(); }
RangeMask& operator+=(RangeMask const& _m) { return unionWith(_m); }
RangeMask& unionWith(RangeMask const& _m)
{ {
m_all.first = std::min(_m.m_all.first, m_all.first);
m_all.second = std::max(_m.m_all.second, m_all.second);
for (auto const& i: _m.m_ranges) for (auto const& i: _m.m_ranges)
operator+=(i); unionWith(i);
return *this; return *this;
} }
RangeMask& operator+=(UnsignedRange const& _m) RangeMask& operator+=(Range const& _m) { return unionWith(_m); }
RangeMask& unionWith(Range const& _m)
{ {
for (auto i = _m.first; i < _m.second;) for (auto i = _m.first; i < _m.second;)
{ {
assert(i >= m_all.first);
assert(i < m_all.second);
// for each number, we find the element equal or next lower. this, if any, must contain the value. // for each number, we find the element equal or next lower. this, if any, must contain the value.
auto uit = m_ranges.upper_bound(i); auto uit = m_ranges.upper_bound(i);
auto it = uit == m_ranges.begin() ? m_ranges.end() : std::prev(uit); auto it = uit == m_ranges.begin() ? m_ranges.end() : std::prev(uit);
@ -130,7 +145,8 @@ public:
return *this; return *this;
} }
RangeMask& operator+=(T _i) RangeMask& operator+=(T _m) { return unionWith(_m); }
RangeMask& unionWith(T _i)
{ {
return operator+=(Range(_i, _i + 1)); return operator+=(Range(_i, _i + 1));
} }
@ -150,7 +166,7 @@ public:
bool full() const bool full() const
{ {
return m_ranges.size() == 1 && m_ranges.begin()->first == m_all.first && m_ranges.begin()->second == m_all.second; return m_all.first == m_all.second || (m_ranges.size() == 1 && m_ranges.begin()->first == m_all.first && m_ranges.begin()->second == m_all.second);
} }
void clear() void clear()
@ -158,7 +174,14 @@ public:
m_ranges.clear(); m_ranges.clear();
} }
void reset()
{
m_ranges.clear();
m_all = std::make_pair(0, 0);
}
std::pair<T, T> const& all() const { return m_all; } std::pair<T, T> const& all() const { return m_all; }
void extendAll(T _i) { m_all = std::make_pair(std::min(m_all.first, _i), std::max(m_all.second, _i + 1)); }
class const_iterator class const_iterator
{ {

4
libdevcore/Worker.cpp

@ -38,9 +38,11 @@ void Worker::startWorking()
m_work.reset(new thread([&]() m_work.reset(new thread([&]()
{ {
setThreadName(m_name.c_str()); setThreadName(m_name.c_str());
startedWorking();
while (!m_stop) while (!m_stop)
{ {
this_thread::sleep_for(chrono::milliseconds(30)); if (m_idleWaitMs)
this_thread::sleep_for(chrono::milliseconds(m_idleWaitMs));
doWork(); doWork();
} }
cdebug << "Finishing up worker thread"; cdebug << "Finishing up worker thread";

19
libdevcore/Worker.h

@ -31,7 +31,7 @@ namespace dev
class Worker class Worker
{ {
protected: protected:
Worker(std::string const& _name = "anon"): m_name(_name) {} Worker(std::string const& _name = "anon", unsigned _idleWaitMs = 30): m_name(_name), m_idleWaitMs(_idleWaitMs) {}
/// Move-constructor. /// Move-constructor.
Worker(Worker&& _m) { std::swap(m_name, _m.m_name); } Worker(Worker&& _m) { std::swap(m_name, _m.m_name); }
@ -41,19 +41,34 @@ protected:
virtual ~Worker() { stopWorking(); } virtual ~Worker() { stopWorking(); }
/// Allows changing worker name if work is stopped.
void setName(std::string _n) { if (!isWorking()) m_name = _n; } void setName(std::string _n) { if (!isWorking()) m_name = _n; }
/// Starts worker thread; causes startedWorking() to be called.
void startWorking(); void startWorking();
/// Stop worker thread; causes call to stopWorking().
void stopWorking(); void stopWorking();
/// Returns if worker thread is present.
bool isWorking() const { Guard l(x_work); return !!m_work; } bool isWorking() const { Guard l(x_work); return !!m_work; }
/// Called after thread is started from startWorking().
virtual void startedWorking() {}
/// Called continuously following sleep for m_idleWaitMs.
virtual void doWork() = 0; virtual void doWork() = 0;
/// Called when is to be stopped, just prior to thread being joined.
virtual void doneWorking() {} virtual void doneWorking() {}
private: private:
std::string m_name;
unsigned m_idleWaitMs;
mutable Mutex x_work; ///< Lock for the network existance. mutable Mutex x_work; ///< Lock for the network existance.
std::unique_ptr<std::thread> m_work; ///< The network thread. std::unique_ptr<std::thread> m_work; ///< The network thread.
bool m_stop = false; bool m_stop = false;
std::string m_name;
}; };
} }

10
libdevcore/_libdevcore.cpp

@ -1,10 +0,0 @@
#ifdef _MSC_VER
#include "All.h"
#include "Common.cpp"
#include "CommonData.cpp"
#include "CommonIO.cpp"
#include "FixedHash.cpp"
#include "Guards.cpp"
#include "Log.cpp"
#include "RLP.cpp"
#endif

121
libdevcore/debugbreak.h

@ -0,0 +1,121 @@
/* Copyright (c) 2013, Scott Tsai
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef DEBUG_BREAK_H
#define DEBUG_BREAK_H
#ifdef _MSC_VER
#define debug_break __debugbreak
#else
#include <signal.h>
#include <unistd.h>
#include <sys/syscall.h>
#ifdef __cplusplus
extern "C" {
#endif
enum {
/* gcc optimizers consider code after __builtin_trap() dead.
* Making __builtin_trap() unsuitable for breaking into the debugger */
DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP = 0,
};
#if defined(__i386__) || defined(__x86_64__)
enum { HAVE_TRAP_INSTRUCTION = 1, };
__attribute__((gnu_inline, always_inline))
static void __inline__ trap_instruction(void)
{
__asm__ volatile("int $0x03");
}
#elif defined(__thumb__)
enum { HAVE_TRAP_INSTRUCTION = 1, };
/* FIXME: handle __THUMB_INTERWORK__ */
__attribute__((gnu_inline, always_inline))
static void __inline__ trap_instruction(void)
{
/* See 'arm-linux-tdep.c' in GDB source.
* Both instruction sequences below works. */
#if 1
/* 'eabi_linux_thumb_le_breakpoint' */
__asm__ volatile(".inst 0xde01");
#else
/* 'eabi_linux_thumb2_le_breakpoint' */
__asm__ volatile(".inst.w 0xf7f0a000");
#endif
/* Known problem:
* After a breakpoint hit, can't stepi, step, or continue in GDB.
* 'step' stuck on the same instruction.
*
* Workaround: a new GDB command,
* 'debugbreak-step' is defined in debugbreak-gdb.py
* that does:
* (gdb) set $instruction_len = 2
* (gdb) tbreak *($pc + $instruction_len)
* (gdb) jump *($pc + $instruction_len)
*/
}
#elif defined(__arm__) && !defined(__thumb__)
enum { HAVE_TRAP_INSTRUCTION = 1, };
__attribute__((gnu_inline, always_inline))
static void __inline__ trap_instruction(void)
{
/* See 'arm-linux-tdep.c' in GDB source,
* 'eabi_linux_arm_le_breakpoint' */
__asm__ volatile(".inst 0xe7f001f0");
/* Has same known problem and workaround
* as Thumb mode */
}
#else
enum { HAVE_TRAP_INSTRUCTION = 0, };
#endif
__attribute__((gnu_inline, always_inline))
static void __inline__ debug_break(void)
{
if (HAVE_TRAP_INSTRUCTION) {
trap_instruction();
} else if (DEBUG_BREAK_PREFER_BUILTIN_TRAP_TO_SIGTRAP) {
/* raises SIGILL on Linux x86{,-64}, to continue in gdb:
* (gdb) handle SIGILL stop nopass
* */
__builtin_trap();
} else {
raise(SIGTRAP);
}
}
#ifdef __cplusplus
}
#endif
#endif
#endif

1
libdevcore/vector_ref.h

@ -40,6 +40,7 @@ public:
vector_ref<_T> cropped(size_t _begin, size_t _count = ~size_t(0)) const { if (m_data && _begin + std::max(size_t(0), _count) <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); } vector_ref<_T> cropped(size_t _begin, size_t _count = ~size_t(0)) const { if (m_data && _begin + std::max(size_t(0), _count) <= m_count) return vector_ref<_T>(m_data + _begin, _count == ~size_t(0) ? m_count - _begin : _count); else return vector_ref<_T>(); }
void retarget(_T const* _d, size_t _s) { m_data = _d; m_count = _s; } void retarget(_T const* _d, size_t _s) { m_data = _d; m_count = _s; }
void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); } void retarget(std::vector<_T> const& _t) { m_data = _t.data(); m_count = _t.size(); }
void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); }
_T* begin() { return m_data; } _T* begin() { return m_data; }
_T* end() { return m_data + m_count; } _T* end() { return m_data + m_count; }

60
libdevcrypto/AES.cpp

@ -0,0 +1,60 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/** @file AES.cpp
* @author Alex Leverington <nessence@gmail.com>
* @date 2014
*/
#include "CryptoPP.h"
#include "AES.h"
using namespace std;
using namespace dev;
using namespace dev::crypto;
using namespace dev::crypto::aes;
using namespace CryptoPP;
struct aes::Aes128Ctr
{
Aes128Ctr(h128 _k)
{
mode.SetKeyWithIV(_k.data(), sizeof(h128), Nonce::get().data());
}
CTR_Mode<AES>::Encryption mode;
};
Stream::Stream(StreamType, h128 _ckey):
m_cSecret(_ckey)
{
cryptor = new Aes128Ctr(_ckey);
}
Stream::~Stream()
{
delete cryptor;
}
void Stream::update(bytesRef)
{
}
size_t Stream::streamOut(bytes&)
{
return 0;
}

89
libdevcrypto/AES.h

@ -0,0 +1,89 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/** @file AES.h
* @author Alex Leverington <nessence@gmail.com>
* @date 2014
*
* AES
* todo: use openssl
*/
#pragma once
#include <atomic>
#include "Common.h"
namespace dev
{
namespace crypto
{
namespace aes
{
struct Aes128Ctr;
enum StreamType { Encrypt, Decrypt };
/**
* @brief Encrypted stream
*/
class Stream
{
public:
// streamtype maybe irrelevant w/ctr
Stream(StreamType _t, h128 _ckey);
~Stream();
virtual void update(bytesRef io_bytes);
/// Move ciphertext to _bytes.
virtual size_t streamOut(bytes& o_bytes);
private:
Stream(Stream const&) = delete;
Stream& operator=(Stream const&) = delete;
h128 m_cSecret;
bytes m_text;
Aes128Ctr* cryptor;
};
/**
* @brief Encrypted stream with inband SHA3 mac at specific interval.
*/
class AuthenticatedStream: public Stream
{
public:
AuthenticatedStream(StreamType _t, h128 _ckey, h128 _mackey, unsigned _interval): Stream(_t, _ckey), m_macSecret(_mackey) { m_macInterval = _interval; }
AuthenticatedStream(StreamType _t, Secret const& _s, unsigned _interval): Stream(_t, h128(_s)), m_macSecret(FixedHash<16>((byte const*)_s.data()+16,h128::ConstructFromPointer)) { m_macInterval = _interval; }
/// Adjust mac interval. Next mac will be xored with value.
void adjustInterval(unsigned _interval) { m_macInterval = _interval; }
private:
AuthenticatedStream(AuthenticatedStream const&) = delete;
AuthenticatedStream& operator=(AuthenticatedStream const&) = delete;
std::atomic<unsigned> m_macInterval;
h128 m_macSecret;
};
}
}
}

9
libdevcrypto/All.h

@ -1,9 +0,0 @@
#pragma once
#include "Common.h"
#include "FileSystem.h"
#include "MemoryDB.h"
#include "OverlayDB.h"
#include "SHA3.h"
#include "TrieCommon.h"
#include "TrieDB.h"

59
libdevcrypto/CMakeLists.txt

@ -1,55 +1,32 @@
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0015 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)
# old policy do not use MACOSX_RPATH
cmake_policy(SET CMP0042 OLD)
endif()
set(CMAKE_AUTOMOC OFF)
aux_source_directory(. SRC_LIST) aux_source_directory(. SRC_LIST)
include_directories(${Boost_INCLUDE_DIRS})
include_directories(${CRYPTOPP_INCLUDE_DIRS})
include_directories(${LEVELDB_INCLUDE_DIRS})
include_directories(..)
set(EXECUTABLE devcrypto) set(EXECUTABLE devcrypto)
# set(CMAKE_INSTALL_PREFIX ../lib) file(GLOB HEADERS "*.h")
if(ETH_STATIC) if(ETH_STATIC)
add_library(${EXECUTABLE} STATIC ${SRC_LIST}) add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
else() else()
add_library(${EXECUTABLE} SHARED ${SRC_LIST}) add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
endif() endif()
file(GLOB HEADERS "*.h") target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARIES})
target_link_libraries(${EXECUTABLE} ${LEVELDB_LIBRARIES})
include_directories(..) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LIBRARIES})
target_link_libraries(${EXECUTABLE} devcore) target_link_libraries(${EXECUTABLE} devcore)
target_link_libraries(${EXECUTABLE} secp256k1)
target_link_libraries(${EXECUTABLE} gmp)
target_link_libraries(${EXECUTABLE} ${LEVELDB_LS})
target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS})
if("${TARGET_PLATFORM}" STREQUAL "w64")
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} iphlpapi)
target_link_libraries(${EXECUTABLE} ws2_32)
target_link_libraries(${EXECUTABLE} mswsock)
target_link_libraries(${EXECUTABLE} shlwapi)
elseif (APPLE)
# Latest mavericks boost libraries only come with -mt
target_link_libraries(${EXECUTABLE} boost_system-mt)
target_link_libraries(${EXECUTABLE} boost_filesystem-mt)
target_link_libraries(${EXECUTABLE} boost_thread-mt)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
elseif (UNIX)
find_package(Boost 1.53 REQUIRED COMPONENTS filesystem)
target_link_libraries(${EXECUTABLE} ${Boost_SYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_FILESYSTEM_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_THREAD_LIBRARY})
target_link_libraries(${EXECUTABLE} ${Boost_DATE_TIME_LIBRARY})
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
else ()
target_link_libraries(${EXECUTABLE} boost_system)
target_link_libraries(${EXECUTABLE} boost_filesystem)
target_link_libraries(${EXECUTABLE} boost_thread)
find_package(Threads REQUIRED)
target_link_libraries(${EXECUTABLE} ${CMAKE_THREAD_LIBS_INIT})
endif ()
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib ) install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} ) install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

189
libdevcrypto/Common.cpp

@ -14,60 +14,93 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file CommonEth.cpp /** @file Common.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @author Alex Leverington <nessence@gmail.com>
* @date 2014 * @date 2014
*/ */
#include "Common.h"
#include <random> #include <random>
#include <secp256k1/secp256k1.h> #include <chrono>
#include <mutex>
#include "SHA3.h" #include "SHA3.h"
#include "FileSystem.h"
#include "CryptoPP.h"
#include "Common.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::crypto;
static Secp256k1 s_secp256k1;
bool dev::SignatureStruct::isValid()
{
if (this->v > 1 ||
this->r >= h256("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141") ||
this->s >= h256("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"))
return false;
return true;
}
//#define ETH_ADDRESS_DEBUG 1 Public dev::toPublic(Secret const& _secret)
{
Public p;
s_secp256k1.toPublic(_secret, p);
return std::move(p);
}
Address dev::toAddress(Public const& _public)
{
return s_secp256k1.toAddress(_public);
}
Address dev::toAddress(Secret _private) Address dev::toAddress(Secret const& _secret)
{ {
secp256k1_start(); Public p;
s_secp256k1.toPublic(_secret, p);
byte pubkey[65]; return s_secp256k1.toAddress(p);
int pubkeylen = 65; }
int ok = secp256k1_ecdsa_seckey_verify(_private.data());
if (!ok) void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
return Address(); {
ok = secp256k1_ecdsa_pubkey_create(pubkey, &pubkeylen, _private.data(), 0); bytes io = _plain.toBytes();
assert(pubkeylen == 65); s_secp256k1.encrypt(_k, io);
if (!ok) o_cipher = std::move(io);
return Address(); }
ok = secp256k1_ecdsa_pubkey_verify(pubkey, 65);
if (!ok) bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
return Address(); {
auto ret = right160(dev::eth::sha3(bytesConstRef(&(pubkey[1]), 64))); bytes io = _cipher.toBytes();
#if ETH_ADDRESS_DEBUG s_secp256k1.decrypt(_k, io);
cout << "---- ADDRESS -------------------------------" << endl; if (io.empty())
cout << "SEC: " << _private << endl; return false;
cout << "PUB: " << toHex(bytesConstRef(&(pubkey[1]), 64)) << endl; o_plaintext = std::move(io);
cout << "ADR: " << ret << endl; return true;
#endif }
return ret;
Public dev::recover(Signature const& _sig, h256 const& _message)
{
return s_secp256k1.recover(_sig, _message.ref());
}
Signature dev::sign(Secret const& _k, h256 const& _hash)
{
return s_secp256k1.sign(_k, _hash);
}
bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
{
return s_secp256k1.verify(_p, _s, _hash.ref(), true);
} }
KeyPair KeyPair::create() KeyPair KeyPair::create()
{ {
secp256k1_start(); static mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count());
static std::mt19937_64 s_eng(time(0)); uniform_int_distribution<uint16_t> d(0, 255);
std::uniform_int_distribution<uint16_t> d(0, 255);
for (int i = 0; i < 100; ++i) for (int i = 0; i < 100; ++i)
{ {
h256 sec; KeyPair ret(FixedHash<32>::random(s_eng));
for (unsigned i = 0; i < 32; ++i)
sec[i] = (byte)d(s_eng);
KeyPair ret(sec);
if (ret.address()) if (ret.address())
return ret; return ret;
} }
@ -77,28 +110,64 @@ KeyPair KeyPair::create()
KeyPair::KeyPair(h256 _sec): KeyPair::KeyPair(h256 _sec):
m_secret(_sec) m_secret(_sec)
{ {
int ok = secp256k1_ecdsa_seckey_verify(m_secret.data()); if (s_secp256k1.verifySecret(m_secret, m_public))
if (!ok) m_address = s_secp256k1.toAddress(m_public);
return; }
byte pubkey[65]; KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password)
int pubkeylen = 65; {
ok = secp256k1_ecdsa_pubkey_create(pubkey, &pubkeylen, m_secret.data(), 0); return KeyPair(sha3(aesDecrypt(_seed, _password)));
if (!ok || pubkeylen != 65) }
return;
h256 crypto::kdf(Secret const& _priv, h256 const& _hash)
ok = secp256k1_ecdsa_pubkey_verify(pubkey, 65); {
if (!ok) // H(H(r||k)^h)
return; h256 s;
sha3mac(Nonce::get().ref(), _priv.ref(), s.ref());
m_secret = m_secret; s ^= _hash;
memcpy(m_public.data(), &(pubkey[1]), 64); sha3(s.ref(), s.ref());
m_address = right160(dev::eth::sha3(bytesConstRef(&(pubkey[1]), 64)));
if (!s || !_hash || !_priv)
#if ETH_ADDRESS_DEBUG BOOST_THROW_EXCEPTION(InvalidState());
cout << "---- ADDRESS -------------------------------" << endl; return std::move(s);
cout << "SEC: " << m_secret << endl; }
cout << "PUB: " << m_public << endl;
cout << "ADR: " << m_address << endl; h256 Nonce::get(bool _commit)
#endif {
// todo: atomic efface bit, periodic save, kdf, rr, rng
// todo: encrypt
static h256 s_seed;
static string s_seedFile(getDataDir() + "/seed");
static mutex s_x;
lock_guard<mutex> l(s_x);
if (!s_seed)
{
static Nonce s_nonce;
bytes b = contents(s_seedFile);
if (b.size() == 32)
memcpy(s_seed.data(), b.data(), 32);
else
{
// todo: replace w/entropy from user and system
std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_int_distribution<uint16_t> d(0, 255);
for (unsigned i = 0; i < 32; ++i)
s_seed[i] = (byte)d(s_eng);
}
if (!s_seed)
BOOST_THROW_EXCEPTION(InvalidState());
// prevent seed reuse if process terminates abnormally
writeFile(s_seedFile, bytes());
}
h256 prev(s_seed);
sha3(prev.ref(), s_seed.ref());
if (_commit)
writeFile(s_seedFile, s_seed.asBytes());
return std::move(s_seed);
}
Nonce::~Nonce()
{
Nonce::get(true);
} }

78
libdevcrypto/Common.h

@ -14,8 +14,9 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file CommonEth.h /** @file Common.h
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @author Alex Leverington <nessence@gmail.com>
* @date 2014 * @date 2014
* *
* Ethereum-specific data structures & algorithms. * Ethereum-specific data structures & algorithms.
@ -25,6 +26,7 @@
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h> #include <libdevcore/FixedHash.h>
#include <libdevcore/Exceptions.h>
namespace dev namespace dev
{ {
@ -37,6 +39,25 @@ using Secret = h256;
/// @NOTE This is not endian-specific; it's just a bunch of bytes. /// @NOTE This is not endian-specific; it's just a bunch of bytes.
using Public = h512; using Public = h512;
/// A signature: 65 bytes: r: [0, 32), s: [32, 64), v: 64.
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
using Signature = h520;
struct SignatureStruct
{
SignatureStruct() {}
SignatureStruct(Signature const& _s) { *(h520*)this = _s; }
SignatureStruct(h256 const& _r, h256 const& _s, byte _v): r(_r), s(_s), v(_v) {}
operator Signature() const { return *(h520 const*)this; }
/// @returns true if r,s,v values are valid, otherwise false
bool isValid();
h256 r;
h256 s;
byte v;
};
/// An Ethereum address: 20 bytes. /// An Ethereum address: 20 bytes.
/// @NOTE This is not endian-specific; it's just a bunch of bytes. /// @NOTE This is not endian-specific; it's just a bunch of bytes.
using Address = h160; using Address = h160;
@ -44,9 +65,36 @@ using Address = h160;
/// A vector of Ethereum addresses. /// A vector of Ethereum addresses.
using Addresses = h160s; using Addresses = h160s;
/// Convert a private key into the public key equivalent. /// A set of Ethereum addresses.
/// @returns 0 if it's not a valid private key. using AddressSet = std::set<h160>;
Address toAddress(h256 _private);
/// A vector of secrets.
using Secrets = h256s;
/// Convert a secret key into the public key equivalent.
Public toPublic(Secret const& _secret);
/// Convert a public key to address.
Address toAddress(Public const& _public);
/// Convert a secret key into address of public key equivalent.
/// @returns 0 if it's not a valid secret key.
Address toAddress(Secret const& _secret);
/// Encrypts plain text using Public key.
void encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher);
/// Decrypts cipher using Secret key.
bool decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext);
/// Recovers Public key from signed message hash.
Public recover(Signature const& _sig, h256 const& _hash);
/// Returns siganture of message hash.
Signature sign(Secret const& _k, h256 const& _hash);
/// Verify signature.
bool verify(Public const& _k, Signature const& _s, h256 const& _hash);
/// Simple class that represents a "key pair". /// Simple class that represents a "key pair".
/// All of the data of the class can be regenerated from the secret key (m_secret) alone. /// All of the data of the class can be regenerated from the secret key (m_secret) alone.
@ -63,6 +111,9 @@ public:
/// Create a new, randomly generated object. /// Create a new, randomly generated object.
static KeyPair create(); static KeyPair create();
/// Create from an encrypted seed.
static KeyPair fromEncryptedSeed(bytesConstRef _seed, std::string const& _password);
/// Retrieve the secret key. /// Retrieve the secret key.
Secret const& secret() const { return m_secret; } Secret const& secret() const { return m_secret; }
/// Retrieve the secret key. /// Retrieve the secret key.
@ -83,4 +134,23 @@ private:
Address m_address; Address m_address;
}; };
namespace crypto
{
struct InvalidState: public dev::Exception {};
/// Key derivation
h256 kdf(Secret const& _priv, h256 const& _hash);
/**
* @brief Generator for nonce material
*/
struct Nonce
{
static h256 get(bool _commit = false);
private:
Nonce() {}
~Nonce();
};
}
} }

232
libdevcrypto/CryptoPP.cpp

@ -0,0 +1,232 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
/** @file CryptoPP.cpp
* @author Alex Leverington <nessence@gmail.com>
* @date 2014
*/
#include "CryptoPP.h"
using namespace std;
using namespace dev;
using namespace dev::crypto;
using namespace CryptoPP;
static_assert(dev::Secret::size == 32, "Secret key must be 32 bytes.");
static_assert(dev::Public::size == 64, "Public key must be 64 bytes.");
static_assert(dev::Signature::size == 65, "Signature must be 65 bytes.");
void Secp256k1::encrypt(Public const& _k, bytes& io_cipher)
{
ECIES<ECP>::Encryptor e;
initializeDLScheme(_k, e);
size_t plen = io_cipher.size();
bytes ciphertext;
ciphertext.resize(e.CiphertextLength(plen));
{
lock_guard<mutex> l(x_rng);
e.Encrypt(m_rng, io_cipher.data(), plen, ciphertext.data());
}
memset(io_cipher.data(), 0, io_cipher.size());
io_cipher = std::move(ciphertext);
}
void Secp256k1::decrypt(Secret const& _k, bytes& io_text)
{
CryptoPP::ECIES<CryptoPP::ECP>::Decryptor d;
initializeDLScheme(_k, d);
if (!io_text.size())
{
io_text.resize(1);
io_text[0] = 0;
}
size_t clen = io_text.size();
bytes plain;
plain.resize(d.MaxPlaintextLength(io_text.size()));
DecodingResult r;
{
lock_guard<mutex> l(x_rng);
r = d.Decrypt(m_rng, io_text.data(), clen, plain.data());
}
if (!r.isValidCoding)
{
io_text.clear();
return;
}
io_text.resize(r.messageLength);
io_text = std::move(plain);
}
Signature Secp256k1::sign(Secret const& _k, bytesConstRef _message)
{
return sign(_k, sha3(_message));
}
Signature Secp256k1::sign(Secret const& _key, h256 const& _hash)
{
// assumption made by signing alogrithm
asserts(m_q == m_qs);
Signature sig;
Integer k(kdf(_key, _hash).data(), 32);
if (k == 0)
BOOST_THROW_EXCEPTION(InvalidState());
k = 1 + (k % (m_qs - 1));
ECP::Point rp;
Integer r;
{
lock_guard<mutex> l(x_params);
rp = m_params.ExponentiateBase(k);
r = m_params.ConvertElementToInteger(rp);
}
sig[64] = 0;
// sig[64] = (r >= m_q) ? 2 : 0;
Integer kInv = k.InverseMod(m_q);
Integer z(_hash.asBytes().data(), 32);
Integer s = (kInv * (Integer(_key.asBytes().data(), 32)*r + z)) % m_q;
if (r == 0 || s == 0)
BOOST_THROW_EXCEPTION(InvalidState());
// if (s > m_qs)
// {
// s = m_q - s;
// if (sig[64])
// sig[64] ^= 1;
// }
sig[64] |= rp.y.IsOdd() ? 1 : 0;
r.Encode(sig.data(), 32);
s.Encode(sig.data() + 32, 32);
return sig;
}
bool Secp256k1::verify(Signature const& _signature, bytesConstRef _message)
{
return !!recover(_signature, _message);
}
bool Secp256k1::verify(Public const& _p, Signature const& _sig, bytesConstRef _message, bool _hashed)
{
// todo: verify w/o recovery (if faster)
return _p == _hashed ? recover(_sig, _message) : recover(_sig, sha3(_message).ref());
}
Public Secp256k1::recover(Signature _signature, bytesConstRef _message)
{
Public recovered;
Integer r(_signature.data(), 32);
Integer s(_signature.data()+32, 32);
// cryptopp encodes sign of y as 0x02/0x03 instead of 0/1 or 27/28
byte encodedpoint[33];
encodedpoint[0] = _signature[64]|2;
memcpy(&encodedpoint[1], _signature.data(), 32);
ECP::Element x;
{
lock_guard<mutex> l(x_curve);
m_curve.DecodePoint(x, encodedpoint, 33);
if (!m_curve.VerifyPoint(x))
return recovered;
}
// if (_signature[64] & 2)
// {
// r += m_q;
// lock_guard<mutex> l(x_params);
// if (r >= m_params.GetMaxExponent())
// return recovered;
// }
Integer z(_message.data(), 32);
Integer rn = r.InverseMod(m_q);
Integer u1 = m_q - (rn.Times(z)).Modulo(m_q);
Integer u2 = (rn.Times(s)).Modulo(m_q);
ECP::Point p;
byte recoveredbytes[65];
{
lock_guard<mutex> l(x_curve);
// todo: make generator member
p = m_curve.CascadeMultiply(u2, x, u1, m_params.GetSubgroupGenerator());
m_curve.EncodePoint(recoveredbytes, p, false);
}
memcpy(recovered.data(), &recoveredbytes[1], 64);
return recovered;
}
bool Secp256k1::verifySecret(Secret const& _s, Public& _p)
{
DL_PrivateKey_EC<ECP> k;
k.Initialize(m_params, secretToExponent(_s));
if (!k.Validate(m_rng, 3))
return false;
DL_PublicKey_EC<CryptoPP::ECP> pub;
k.MakePublicKey(pub);
if (!k.Validate(m_rng, 3))
return false;
exportPublicKey(pub, _p);
return true;
}
void Secp256k1::agree(Secret const& _s, Public const& _r, h256& o_s)
{
ECDH<ECP>::Domain d(m_oid);
assert(d.AgreedValueLength() == sizeof(o_s));
byte remote[65] = {0x04};
memcpy(&remote[1], _r.data(), 64);
assert(d.Agree(o_s.data(), _s.data(), remote));
}
void Secp256k1::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& o_p)
{
bytes prefixedKey(_k.GetGroupParameters().GetEncodedElementSize(true));
{
lock_guard<mutex> l(x_params);
m_params.GetCurve().EncodePoint(prefixedKey.data(), _k.GetPublicElement(), false);
assert(Public::size + 1 == _k.GetGroupParameters().GetEncodedElementSize(true));
}
memcpy(o_p.data(), &prefixedKey[1], Public::size);
}
void Secp256k1::exponentToPublic(Integer const& _e, Public& o_p)
{
CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> pk;
{
lock_guard<mutex> l(x_params);
pk.Initialize(m_params, m_params.ExponentiateBase(_e));
}
exportPublicKey(pk, o_p);
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save