diff --git a/.appveyor.yml b/.appveyor.yml index 62c568dd..38629ea7 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -4,8 +4,8 @@ image: Visual Studio 2017 environment: matrix: - - CONFIGURATION: Debug - - CONFIGURATION: Release + - CONFIGURATION: Debug + - CONFIGURATION: Release install: - git submodule update --init --recursive diff --git a/.circleci/clang_tidy.sh b/.circleci/clang_tidy.sh index b97b592d..ae917a5e 100644 --- a/.circleci/clang_tidy.sh +++ b/.circleci/clang_tidy.sh @@ -7,7 +7,7 @@ if [[ -n $(grep "error: " output.txt) ]]; then echo "You must pass the clang tidy checks before submitting a pull request" echo "" grep --color -E '^|warning: |error: ' output.txt - exit -1; + exit 1; else # still output the file to show warnings echo "" diff --git a/.circleci/config.yml b/.circleci/config.yml index 67c56785..b5836792 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ jobs: steps: - checkout - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Install @@ -18,11 +18,16 @@ jobs: steps: - checkout - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Install command: ./.circleci/install_platform_io.sh + - run: + name: Empty Git Submodule Folders + command: | + rm -rf ./src/lib/{ArduinoJson/*,BIP66/*,uECC/*} + rm -rf ./test/lib/googletest/* - run: name: Build command: ./.circleci/script_platform_io.sh @@ -34,16 +39,15 @@ jobs: name: Install dependencies command: | sudo apt-get remove cmake cmake-data - sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test + sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test sudo apt-add-repository -y ppa:george-edison55/cmake-3.x sudo apt-get update sudo apt-get -y install g++-7 gcc-7 lcov cmake sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 60 --slave /usr/bin/g++ g++ /usr/bin/g++-7 sudo update-alternatives --config gcc - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - - run: name: Build command: ./.circleci/script_desktop.sh @@ -63,28 +67,22 @@ jobs: sudo apt-get update sudo apt install python-lldb-5.0 lcov cmake sudo apt install clang-5.0 clang-tidy-5.0 clang-format-5.0 clang-5.0-doc libclang-common-5.0-dev libclang-5.0-dev libclang1-5.0 libllvm5.0 lldb-5.0 llvm-5.0 llvm-5.0-dev - sudo update-alternatives --install /usr/bin/cc cc /usr/bin/clang-5.0 60 sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 50 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-5.0 60 sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 50 - - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - - run: name: Build command: ./.circleci/script_desktop.sh - - run: name: Clang Tidy command: ./.circleci/clang_tidy.sh - - run: name: Clang Format command: ./.circleci/clang_format.sh - build-macos-9-2: macos: xcode: "9.2.0" @@ -95,7 +93,7 @@ jobs: name: Install dependencies command: brew install cmake lcov - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Build @@ -109,12 +107,11 @@ jobs: name: Install dependencies command: brew install cmake lcov - run: - name: Make scripts executable + name: Make scripts executable command: sudo chmod -R +x ./.circleci/*.sh - run: name: Build command: ./.circleci/script_desktop.sh - workflows: version: 2 build: @@ -125,4 +122,3 @@ workflows: - build-linux-clang-5 - build-macos-9-2 - build-macos-9-3 - diff --git a/.circleci/platformio.cpp b/.circleci/platformio.cpp new file mode 100644 index 00000000..5b9fd3a5 --- /dev/null +++ b/.circleci/platformio.cpp @@ -0,0 +1,21 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +// This is a dummy prototype 'setup' & 'loop' for CI testing. +// This isn't intended for project or production use. +// It is only used in the 'pio run' command from root in CI; +// successful completion of which asserts that the ARK Cpp-Crypto library builds on its own. +#if (defined PLATFORMIO && !defined UNIT_TEST) + +#include + +void setup() {} +void loop() {} + +#endif diff --git a/.circleci/script_arduino.sh b/.circleci/script_arduino.sh index 87107574..2431bd3b 100644 --- a/.circleci/script_arduino.sh +++ b/.circleci/script_arduino.sh @@ -7,5 +7,6 @@ mv ~/project/* ~/Arduino/libraries/cpp-crypto arduino-cli lib install "ArduinoJson@6.10.0" arduino-cli lib install "BIP66" +arduino-cli lib install "micro-ecc" arduino-cli compile --output temp.bin -b esp32:esp32:esp32 ~/Arduino/libraries/cpp-crypto/examples/arduino/ESP32/ESP32.ino --debug diff --git a/CHANGELOG.md b/CHANGELOG.md index 58bf0e2e..9f2673a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## Unreleased +## [0.6.0-arduino] - 2019-07-16 + +## [0.6.0] - 2019-07-16 + +### Added + +- added Bridgechain support ([#105]) ### Changed +- changed amount and fee Json serialization to match Core v.2.5 ([#111]) +- improved PlatformIO configuration ([#101]) +- improved formatting and maintainability ([#98]) - improved Slots implementations ([#92]) +### Fixed + +- fixed Transaction Json numeric serialization ([#103]) + ## [0.5.0] - 2019-02-20 ### Changed diff --git a/CMakeLists.txt b/CMakeLists.txt index d116fc67..f63af177 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,20 +7,20 @@ set(CMAKE_CXX_STANDARD 11) set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}) if (MSVC) - add_definitions( - -D_CRT_SECURE_NO_WARNINGS - -D_SCL_SECURE_NO_WARNINGS - -DNOMINMAX - ) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") + add_definitions( + -D_CRT_SECURE_NO_WARNINGS + -D_SCL_SECURE_NO_WARNINGS + -DNOMINMAX + ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") endif() # clone submodules execute_process( - COMMAND git submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + COMMAND git submodule update --init --recursive + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} ) # ------------------------------------------------------------------------------ @@ -28,7 +28,6 @@ execute_process( # ------------------------------------------------------------------------------ if(ENABLE_CLANG_TIDY) - find_program(CLANG_TIDY_BIN clang-tidy-5.0) find_program(RUN_CLANG_TIDY_BIN run-clang-tidy-5.0.py) @@ -36,13 +35,13 @@ if(ENABLE_CLANG_TIDY) message(FATAL_ERROR "unable to locate clang-tidy-5.0") endif() - if(RUN_CLANG_TIDY_BIN STREQUAL "RUN_CLANG_TIDY_BIN-NOTFOUND") - message(FATAL_ERROR "unable to locate run-clang-tidy-5.0.py") - endif() + if(RUN_CLANG_TIDY_BIN STREQUAL "RUN_CLANG_TIDY_BIN-NOTFOUND") + message(FATAL_ERROR "unable to locate run-clang-tidy-5.0.py") + endif() list(APPEND RUN_CLANG_TIDY_BIN_ARGS -clang-tidy-binary ${CLANG_TIDY_BIN} - -header-filter=.* + "\"-header-filter=.*\\b(src|test|examples)\\b\\/(?!lib\/*).*\"" #Only run clang tidy on src, test, examples and skip 3rd party libraries -checks=clan*,cert*,misc*,perf*,cppc*,read*,mode*,-cert-err58-cpp,-misc-noexcept-move-constructor,-cppcoreguidelines-* ) @@ -51,7 +50,6 @@ if(ENABLE_CLANG_TIDY) COMMAND ${RUN_CLANG_TIDY_BIN} ${RUN_CLANG_TIDY_BIN_ARGS} COMMENT "running clang tidy" ) - endif() add_subdirectory(src) diff --git a/docs/cpp.md b/docs/cpp.md index 14ebd569..724c6eec 100644 --- a/docs/cpp.md +++ b/docs/cpp.md @@ -16,6 +16,79 @@ This project is still under development. This page will get more content as the * [macOS >= 10.10](#OS) * [Windows >= 7](#OS) +### ARK Transactions + +#### Devnet + +```cpp +const auto DevnetTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a devnet transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too"); +``` + +#### Mainnet + +```cpp +const Configuration MainnetConfiguration(Networks::Mainnet()); + +const auto MainnetTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a mainnet transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MainnetConfiguration); +``` + +#### BridgeChain Transaction + +```cpp +static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; + +const Configuration MyBridgechainConfiguration(MyBridgechainNetwork); + +const auto MyBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MyBridgechainConfiguration); +``` + + +#### With custom Fees + +```cpp +static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; + +const FeePolicy MyCustomFees = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; + +ßconst Configuration MyBridgechainConfiguration(MyBridgechainNetwork, + MyCustomFees); + +const auto MyBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "", + "this is a top secret passphrase", + "", + MyBridgechainConfiguration); +``` ### Sign diff --git a/examples/arduino/ESP32/ESP32.ino b/examples/arduino/ESP32/ESP32.ino index 2c82de74..8b514ab7 100644 --- a/examples/arduino/ESP32/ESP32.ino +++ b/examples/arduino/ESP32/ESP32.ino @@ -31,13 +31,40 @@ /****************************************/ void checkCrypto() { + + /** + * Create a BridgeChain transaction, tailored for your custom network. + */ + static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" + }; + + const Configuration MyBridgechainConfiguration(MyBridgechainNetwork); + + auto myBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MyBridgechainConfiguration); + + Serial.print("\nBridgechain Transaction: "); + Serial.println(myBridgechainTransaction.toJson().c_str()); + + /**/ + + /********************/ + /** * This is how you can check the default 'Network' "Transaction 'Fees' by type. * In this example, it should return a 'uint64_t' integer of '10000000' as the default 'Fee' for a 'Transaction' of 'Type' '0'. */ - Ark::Crypto::Configuration::Fee fee; - unsigned long typeZeroTransactionFee = fee.get(0); - Serial.print("\n Type 0 default Transaction Fee: "); + Configuration config; + unsigned long typeZeroTransactionFee = config.getFee(0); + Serial.print("\nType 0 default Transaction Fee: "); Serial.println(typeZeroTransactionFee); // The response is a 'uint64_t' integer. /**/ diff --git a/examples/arduino/ESP8266/ESP8266.ino b/examples/arduino/ESP8266/ESP8266.ino index 876a2aaf..5cd91181 100644 --- a/examples/arduino/ESP8266/ESP8266.ino +++ b/examples/arduino/ESP8266/ESP8266.ino @@ -31,13 +31,39 @@ /****************************************/ void checkCrypto() { + /** + * Create a BridgeChain transaction, tailored for your custom network. + */ + static const Network MyBridgechainNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" + }; + + const Configuration MyBridgechainConfiguration(MyBridgechainNetwork); + + auto myBridgechainTransaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + MyBridgechainConfiguration); + + Serial.print("\nBridgechain Transaction: "); + Serial.println(myBridgechainTransaction.toJson().c_str()); + + /**/ + + /********************/ + /** * This is how you can check the default 'Network' "Transaction 'Fees' by type. * In this example, it should return a 'uint64_t' integer of '10000000' as the default 'Fee' for a 'Transaction' of 'Type' '0'. */ - Ark::Crypto::Configuration::Fee fee; - unsigned long typeZeroTransactionFee = fee.get(0); - Serial.print("\n Type 0 default Transaction Fee: "); + Configuration config; + unsigned long typeZeroTransactionFee = config.getFee(0); + Serial.print("\nType 0 default Transaction Fee: "); Serial.println(typeZeroTransactionFee); // The response is a 'uint64_t' integer. /**/ diff --git a/extras/ARDUINO_IDE.sh b/extras/ARDUINO_IDE.sh index 53ddf899..1fdc3a8a 100644 --- a/extras/ARDUINO_IDE.sh +++ b/extras/ARDUINO_IDE.sh @@ -27,7 +27,7 @@ if [ "$1" == "--auto" ]; then fi # Directories -EXTRAS_DIR=`dirname "$0"` +EXTRAS_DIR=$(dirname $0) PROJECT_ROOT=${EXTRAS_DIR}/../ INCLUDE_DIR=${EXTRAS_DIR}/../src/include INCLUDE_CRYPTO_DIR=${INCLUDE_DIR}/cpp-crypto @@ -38,22 +38,20 @@ EXTRAS_BACKUP_DIR=${EXTRAS_DIR}/BACKUP SRC_LIB_DIR=${SRC_DIR}/lib EXTRAS_LIB_DIR=${EXTRAS_BACKUP_DIR}/lib -EXTRAS_IDENTITIES_DIR=${EXTRAS_BACKUP_DIR}/identities +SRC_COMMON_DIR=${SRC_DIR}/common +INCLUDE_COMMON_DIR=${INCLUDE_CRYPTO_DIR}/common -INCLUDE_CONFIGURATION_DIR=${INCLUDE_CRYPTO_DIR}/configuration -SRC_CONFIGURATION_DIR=${SRC_DIR}/configuration +SRC_DEFAULTS_DIR=${SRC_DIR}/defaults +INCLUDE_DEFAULTS_DIR=${INCLUDE_CRYPTO_DIR}/defaults -INCLUDE_ENUMS_DIR=${INCLUDE_CRYPTO_DIR}/enums -SRC_ENUMS_DIR=${SRC_DIR}/enums - -INCLUDE_HELPERS_DIR=${INCLUDE_CRYPTO_DIR}/helpers SRC_HELPERS_DIR=${SRC_DIR}/helpers +INCLUDE_HELPERS_DIR=${INCLUDE_CRYPTO_DIR}/helpers -INCLUDE_ENCODING_DIR=${INCLUDE_HELPERS_DIR}/encoding SRC_ENCODING_DIR=${SRC_HELPERS_DIR}/encoding +INCLUDE_ENCODING_DIR=${INCLUDE_HELPERS_DIR}/encoding -INCLUDE_IDENTITIES_DIR=${INCLUDE_CRYPTO_DIR}/identities SRC_IDENTITIES_DIR=${SRC_DIR}/identities +INCLUDE_IDENTITIES_DIR=${INCLUDE_CRYPTO_DIR}/identities INCLUDE_NETWORKS_DIR=${INCLUDE_CRYPTO_DIR}/networks SRC_NETWORKS_DIR=${SRC_DIR}/networks @@ -100,16 +98,15 @@ if [[ -d ${INCLUDE_DIR} ]]; then echo -e "Moving 'arkCrypto.h' to 'src' directory.\n" mv ${INCLUDE_CRYPTO_DIR}/arkCrypto.h ${SRC_DIR} - echo -e "Moving 'configuration' headers.\n" - mv ${INCLUDE_CONFIGURATION_DIR}/fee.h ${SRC_CONFIGURATION_DIR} - mv ${INCLUDE_CONFIGURATION_DIR}/network.h ${SRC_CONFIGURATION_DIR} - - echo "Creating 'enums' folder πŸ—‚" - mkdir ${SRC_ENUMS_DIR} + echo -e "Moving 'common' headers.\n" + mv ${INCLUDE_COMMON_DIR}/configuration.hpp ${SRC_COMMON_DIR} + mv ${INCLUDE_COMMON_DIR}/fee_policy.hpp ${SRC_COMMON_DIR} + mv ${INCLUDE_COMMON_DIR}/network.hpp ${SRC_COMMON_DIR} - echo -e "Moving 'enums' headers.\n" - mv ${INCLUDE_ENUMS_DIR}/fees.h ${SRC_ENUMS_DIR} - mv ${INCLUDE_ENUMS_DIR}/types.h ${SRC_ENUMS_DIR} + echo -e "Moving 'defaults' headers.\n" + mv ${INCLUDE_DEFAULTS_DIR}/fee_policies.hpp ${SRC_DEFAULTS_DIR} + mv ${INCLUDE_DEFAULTS_DIR}/static_fees.hpp ${SRC_DEFAULTS_DIR} + mv ${INCLUDE_DEFAULTS_DIR}/transaction_types.hpp ${SRC_DEFAULTS_DIR} echo -e "Moving 'helpers' headers.\n" mkdir ${SRC_ENCODING_DIR} @@ -122,10 +119,10 @@ if [[ -d ${INCLUDE_DIR} ]]; then mv ${INCLUDE_IDENTITIES_DIR}/wif.h ${SRC_IDENTITIES_DIR} echo -e "Moving 'networks' headers.\n" - mv ${INCLUDE_NETWORKS_DIR}/abstractnetwork.h ${SRC_NETWORKS_DIR} - mv ${INCLUDE_NETWORKS_DIR}/devnet.h ${SRC_NETWORKS_DIR} - mv ${INCLUDE_NETWORKS_DIR}/mainnet.h ${SRC_NETWORKS_DIR} - mv ${INCLUDE_NETWORKS_DIR}/testnet.h ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/networks.hpp ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/devnet.hpp ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/mainnet.hpp ${SRC_NETWORKS_DIR} + mv ${INCLUDE_NETWORKS_DIR}/testnet.hpp ${SRC_NETWORKS_DIR} echo -e "Moving 'transactions' headers.\n" mv ${INCLUDE_TRANSACTIONS_DIR}/builder.h ${SRC_TRANSACTIONS_DIR} @@ -133,13 +130,14 @@ if [[ -d ${INCLUDE_DIR} ]]; then mv ${INCLUDE_TRANSACTIONS_DIR}/serializer.h ${SRC_TRANSACTIONS_DIR} mv ${INCLUDE_TRANSACTIONS_DIR}/transaction.h ${SRC_TRANSACTIONS_DIR} - echo -e "Backing up, moving, and removing relevant modules from the 'lib' directory.\n" + echo -e "Backing up, moving, and removing dependencies from the 'src/lib' directory.\n" + mkdir ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/ArduinoJson ${EXTRAS_BACKUP_DIR} + mv ${SRC_LIB_DIR}/BIP66 ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/uECC ${EXTRAS_BACKUP_DIR} mv ${SRC_LIB_DIR}/bcl ${SRC_DIR} mv ${SRC_LIB_DIR}/date ${SRC_DIR} mv ${SRC_LIB_DIR}/rfc6979 ${SRC_DIR} - mv ${SRC_LIB_DIR}/stl ${SRC_DIR} echo -e "Moving Docs to the './extras' directory.\n" mv ${PROJECT_ROOT}/docs ${EXTRAS_DIR} @@ -161,8 +159,8 @@ else echo -e "Creating the 'include' directory tree πŸ—‚\n" mkdir ${INCLUDE_DIR} mkdir ${INCLUDE_CRYPTO_DIR} - mkdir ${INCLUDE_CONFIGURATION_DIR} - mkdir ${INCLUDE_ENUMS_DIR} + mkdir ${INCLUDE_COMMON_DIR} + mkdir ${INCLUDE_DEFAULTS_DIR} mkdir ${INCLUDE_HELPERS_DIR} mkdir ${INCLUDE_ENCODING_DIR} mkdir ${INCLUDE_IDENTITIES_DIR} @@ -172,13 +170,15 @@ else echo -e "Moving 'arkCrypto.h' back to the 'include/cpp-crypto/' directory.\n" mv ${SRC_DIR}/arkCrypto.h ${INCLUDE_CRYPTO_DIR} - echo -e "Moving 'configuration' headers.\n" - mv ${SRC_CONFIGURATION_DIR}/fee.h ${INCLUDE_CONFIGURATION_DIR} - mv ${SRC_CONFIGURATION_DIR}/network.h ${INCLUDE_CONFIGURATION_DIR} + echo -e "Moving 'common' headers.\n" + mv ${SRC_COMMON_DIR}/configuration.hpp ${INCLUDE_COMMON_DIR} + mv ${SRC_COMMON_DIR}/fee_policy.hpp ${INCLUDE_COMMON_DIR} + mv ${SRC_COMMON_DIR}/network.hpp ${INCLUDE_COMMON_DIR} - echo -e "Moving 'enums' headers.\n" - mv ${SRC_ENUMS_DIR}/fees.h ${INCLUDE_ENUMS_DIR} - mv ${SRC_ENUMS_DIR}/types.h ${INCLUDE_ENUMS_DIR} + echo -e "Moving 'defaults' headers.\n" + mv ${SRC_DEFAULTS_DIR}/fee_policies.hpp ${INCLUDE_DEFAULTS_DIR} + mv ${SRC_DEFAULTS_DIR}/static_fees.hpp ${INCLUDE_DEFAULTS_DIR} + mv ${SRC_DEFAULTS_DIR}/transaction_types.hpp ${INCLUDE_DEFAULTS_DIR} echo -e "Moving 'helpers/encoding' headers.\n" mv ${SRC_ENCODING_DIR}/hex.h ${INCLUDE_ENCODING_DIR} @@ -191,10 +191,10 @@ else mv ${SRC_IDENTITIES_DIR}/wif.h ${INCLUDE_IDENTITIES_DIR} echo -e "Moving 'networks' headers.\n" - mv ${SRC_NETWORKS_DIR}/abstractnetwork.h ${INCLUDE_NETWORKS_DIR} - mv ${SRC_NETWORKS_DIR}/devnet.h ${INCLUDE_NETWORKS_DIR} - mv ${SRC_NETWORKS_DIR}/mainnet.h ${INCLUDE_NETWORKS_DIR} - mv ${SRC_NETWORKS_DIR}/testnet.h ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/networks.hpp ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/devnet.hpp ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/mainnet.hpp ${INCLUDE_NETWORKS_DIR} + mv ${SRC_NETWORKS_DIR}/testnet.hpp ${INCLUDE_NETWORKS_DIR} echo -e "Moving 'transactions' headers.\n" mv ${SRC_TRANSACTIONS_DIR}/builder.h ${INCLUDE_TRANSACTIONS_DIR} @@ -205,17 +205,16 @@ else echo -e "Restoring the 'lib' directory.\n" mkdir ${SRC_LIB_DIR} mv ${EXTRAS_BACKUP_DIR}/ArduinoJson ${SRC_LIB_DIR} + mv ${EXTRAS_BACKUP_DIR}/BIP66 ${SRC_LIB_DIR} mv ${EXTRAS_BACKUP_DIR}/uECC ${SRC_LIB_DIR} mv ${SRC_DIR}/bcl ${SRC_LIB_DIR} mv ${SRC_DIR}/date ${SRC_LIB_DIR} mv ${SRC_DIR}/rfc6979 ${SRC_LIB_DIR} - mv ${SRC_DIR}/stl ${SRC_LIB_DIR} echo -e "Moving Docs back to the project root directory.\n" mv ${EXTRAS_DIR}/docs ${PROJECT_ROOT} echo -e "Removing old directories πŸ—‘\n" - rm -rf ${SRC_ENUMS_DIR} rm -rf ${EXTRAS_BACKUP_DIR} echo -e "****************************************\n" diff --git a/keywords.txt b/keywords.txt index 98cd5e48..5ef6954f 100644 --- a/keywords.txt +++ b/keywords.txt @@ -6,33 +6,33 @@ # Datatypes (KEYWORD1) ####################################### -Ark KEYWORD1 -Crypto KEYWORD1 -Configuration KEYWORD1 -Enums KEYWORD1 -Identities KEYWORD1 -Networks KEYWORD1 -Transactions KEYWORD1 -Utils KEYWORD1 - -Fee KEYWORD1 -Network KEYWORD1 - -Fees KEYWORD1 -Types KEYWORD1 - -Address KEYWORD1 -PrivateKey KEYWORD1 -PublicKey KEYWORD1 -WIF KEYWORD1 - -Builder KEYWORD1 -Deserializer KEYWORD1 -Serializer KEYWORD1 -Transaction KEYWORD1 - -Message KEYWORD1 -Slot KEYWORD1 +Ark KEYWORD1 +Crypto KEYWORD1 +common KEYWORD1 +defaults KEYWORD1 +Identities KEYWORD1 +managers KEYWORD1 +Transactions KEYWORD1 +Utils KEYWORD1 + +Configuration KEYWORD1 +FeePolicy KEYWORD1 +Network KEYWORD1 + +Address KEYWORD1 +PrivateKey KEYWORD1 +PublicKey KEYWORD1 +WIF KEYWORD1 + +Networks KEYWORD1 + +Builder KEYWORD1 +Deserializer KEYWORD1 +Serializer KEYWORD1 +Transaction KEYWORD1 + +Message KEYWORD1 +Slot KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) @@ -42,6 +42,10 @@ Slot KEYWORD1 # Constants (LITERAL1) ####################################### -Devnet LITERAL1 -Mainnet LITERAL1 -Testnet LITERAL1 +Fees KEYWORD1 +StaticFeePolicy KEYWORD1 +TransactionTypes KEYWORD1 + +Devnet LITERAL1 +Mainnet LITERAL1 +Testnet LITERAL1 diff --git a/library.json b/library.json index c02cabc3..d892dad9 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/ArkEcosystem/Cpp-Crypto.git" }, - "version": "0.5.0", + "version": "0.6.0", "authors": [ { "name": "Ark Ecosystem", @@ -16,13 +16,19 @@ } ], "frameworks": "arduino", - "platforms": "*", + "platforms": [ + "espressif8266", + "espressif32" + ], "dependencies": [ { "name": "micro-ecc" }, { "name": "ArduinoJson" + }, + { + "name": "BIP66" } ], "export": { diff --git a/library.properties b/library.properties index 7821733c..83dd41dc 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Ark-Cpp-Crypto -version=0.5.0 +version=0.6.0 author=Ark Ecosystem maintainer=Ark Ecosystem sentence=A simple Cryptography Implementation in C++ for the ARK Blockchain. diff --git a/platformio.ini b/platformio.ini index 82761003..487f4469 100644 --- a/platformio.ini +++ b/platformio.ini @@ -10,19 +10,19 @@ [platformio] description = "A simple Cryptography Implementation in C++ for the ARK Blockchain." +build_dir = .pio/.pioenvs +libdeps_dir = .pio/.piolibdeps [common] -lib_ldf_mode = off lib_deps = micro-ecc, ArduinoJson@6.10.0, BIP66 build_flags = -I./src/ -I./src/lib -I./src/include/cpp-crypto -src_filter = +<*> -<.git/> - - - - - - +src_filter = +<*> +<../.circleci/platformio.cpp> upload_speed = 921600 [env:esp8266] platform = espressif8266 board = huzzah framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} lib_deps = ${common.lib_deps} build_flags = ${common.build_flags} src_filter = ${common.src_filter} @@ -32,7 +32,6 @@ upload_speed = ${common.upload_speed} platform = espressif32 board = esp32dev framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} lib_deps = ${common.lib_deps} build_flags = ${common.build_flags} src_filter = ${common.src_filter} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0511290d..4ce31358 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,55 +4,60 @@ cmake_minimum_required(VERSION 3.2.2) project(Ark-Cpp-Crypto-lib C CXX) set(BIP66_SRC - ${PROJECT_SOURCE_DIR}/lib/BIP66/src/bip66.cpp + ${PROJECT_SOURCE_DIR}/lib/BIP66/src/bip66.cpp ) set(BCL_SRC - lib/bcl/Base58Check.cpp - lib/bcl/CurvePoint.cpp - lib/bcl/Ecdsa.cpp - lib/bcl/FieldInt.cpp - lib/bcl/Ripemd160.cpp - lib/bcl/Sha256Hash.cpp - lib/bcl/Sha256.cpp - lib/bcl/Sha512.cpp - lib/bcl/Uint256.cpp - lib/bcl/Utils.cpp + lib/bcl/Base58Check.cpp + lib/bcl/CurvePoint.cpp + lib/bcl/Ecdsa.cpp + lib/bcl/FieldInt.cpp + lib/bcl/Ripemd160.cpp + lib/bcl/Sha256Hash.cpp + lib/bcl/Sha256.cpp + lib/bcl/Sha512.cpp + lib/bcl/Uint256.cpp + lib/bcl/Utils.cpp ) set(uECC_SRC - lib/uECC/uECC.c + lib/uECC/uECC.c ) set(COMMON_SRC - configuration/fee.cpp - configuration/network.cpp - helpers/crypto.cpp - identities/address.cpp - identities/privatekey.cpp - identities/publickey.cpp - identities/wif.cpp - networks/abstractnetwork.cpp - transactions/builder.cpp - transactions/deserializer.cpp - transactions/serializer.cpp - transactions/transaction.cpp - utils/message.cpp - utils/slot.cpp + common/configuration.cpp + common/network.cpp + defaults/static_fees.cpp + helpers/crypto.cpp + identities/address.cpp + identities/privatekey.cpp + identities/publickey.cpp + identities/wif.cpp + managers/fee_manager.cpp + managers/network_manager.cpp + networks/devnet.cpp + networks/mainnet.cpp + networks/testnet.cpp + transactions/builder.cpp + transactions/deserializer.cpp + transactions/serializer.cpp + transactions/transaction.cpp + utils/message.cpp + utils/slot.cpp ) -add_library(${PROJECT_NAME} - STATIC - ${BCL_SRC} - ${uECC_SRC} - ${BIP66_SRC} - ${COMMON_SRC} +add_library(${PROJECT_NAME} STATIC + ${BCL_SRC} + ${uECC_SRC} + ${BIP66_SRC} + ${COMMON_SRC} ) set(cpp_crypto_build_include_dirs ${PROJECT_SOURCE_DIR} ${PROJECT_SOURCE_DIR}/include/cpp-crypto ) + include_directories(${cpp_crypto_build_include_dirs}) include_directories(${PROJECT_SOURCE_DIR}/lib/) include_directories(${PROJECT_SOURCE_DIR}/lib/ArduinoJson) @@ -61,10 +66,10 @@ include_directories(${PROJECT_SOURCE_DIR}/lib/rfc6979) include_directories(${PROJECT_SOURCE_DIR}/lib/uECC) include_directories(${PROJECT_SOURCE_DIR}/lib/BIP66/src) -target_include_directories( ${PROJECT_NAME} - PUBLIC ${cpp_crypto_build_include_dirs} +target_include_directories( ${PROJECT_NAME} PUBLIC + ${cpp_crypto_build_include_dirs} ) if (MSVC) - target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) + target_link_libraries(${PROJECT_NAME} PUBLIC crypt32) endif() diff --git a/src/common/configuration.cpp b/src/common/configuration.cpp new file mode 100644 index 00000000..fcd79095 --- /dev/null +++ b/src/common/configuration.cpp @@ -0,0 +1,27 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "common/configuration.hpp" + +namespace Ark { +namespace Crypto { + +bool Configuration::operator==(const Configuration& rhs) const { + return this->getNetwork() == rhs.getNetwork() + && this->getPolicy() == rhs.getPolicy(); +} + +/**/ + +bool Configuration::operator!=(const Configuration& rhs) const { + return this->getNetwork() != rhs.getNetwork() + || this->getPolicy() != rhs.getPolicy();} + +} // namespace Crypto +} // namespace Ark diff --git a/src/common/network.cpp b/src/common/network.cpp new file mode 100644 index 00000000..53664322 --- /dev/null +++ b/src/common/network.cpp @@ -0,0 +1,49 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "common/network.hpp" +#include "networks/devnet.hpp" + +namespace Ark { +namespace Crypto { + +Network::Network() { *this = Networks::Devnet(); } + +/**/ + +std::string Network::nethash() const { return this->nethash_; } +uint8_t Network::slip44() const { return this->slip44_; } +uint8_t Network::wif() const { return this->wif_; } +uint8_t Network::version() const { return this->version_; } +std::string Network::epoch() const { return this->epoch_; } + +/**/ + +bool Network::operator==(const Network& rhs) const { + bool numericsMatch = (this->slip44_ == rhs.slip44_) + && (this->wif_ == rhs.wif_) + && (this->version_ == rhs.version_); + bool stringsMatch = (this->nethash_ == rhs.nethash_) + && (this->epoch_ == rhs.epoch_); + return numericsMatch && stringsMatch; +} + +/**/ + +bool Network::operator!=(const Network& rhs) const { + bool numericsMatch = (this->slip44_ != rhs.slip44_) + || (this->wif_ != rhs.wif_) + || (this->version_ != rhs.version_); + bool stringsMatch = (this->nethash_ != rhs.nethash_) + || (this->epoch_ != rhs.epoch_); + return numericsMatch || stringsMatch; +} + +} // namespace Crypto +} // namespace Ark diff --git a/src/configuration/fee.cpp b/src/configuration/fee.cpp deleted file mode 100644 index 6f6fe63d..00000000 --- a/src/configuration/fee.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#include "configuration/fee.h" - -/** - * @brief Get the transaction fee for the given type. - * - * @param const int type - * @return uint64_t - **/ -uint64_t Ark::Crypto::Configuration::Fee::get(int type) { - return this->fees_[type]; -}; -/**/ - -/** - * @brief Set the transaction fee for the given type. - * - * @param const int type - * @param const uint64_t fee - **/ -void Ark::Crypto::Configuration::Fee::set(int type, uint64_t fee) { - this->fees_[type] = fee; -}; -/**/ diff --git a/src/configuration/network.cpp b/src/configuration/network.cpp deleted file mode 100644 index b3355091..00000000 --- a/src/configuration/network.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#include "configuration/network.h" - -/** - * @brief Get the network used for crypto operations. - * - * @return AbstractNetwork - **/ -Ark::Crypto::Networks::AbstractNetwork Ark::Crypto::Configuration::Network::get() { - return (this->network_.getBase58Prefix(BASE58_ADDRESS_P2PKH) == 0x00) ? (Devnet) : (this->network_); -} -/**/ - -/** - * @brief Set the network used for crypto operations. - * - * @param AbstractNetwork network - **/ -void Ark::Crypto::Configuration::Network::set(const Ark::Crypto::Networks::AbstractNetwork& network) { - this->network_ = network; -}; -/**/ diff --git a/src/defaults/static_fees.cpp b/src/defaults/static_fees.cpp new file mode 100644 index 00000000..eace0c83 --- /dev/null +++ b/src/defaults/static_fees.cpp @@ -0,0 +1,37 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "defaults/static_fees.hpp" + +#include + +#include "common/fee_policy.hpp" + +namespace Ark { +namespace Crypto { +namespace defaults { + +// Default ARK Static Fees +const FeePolicy Fees::StaticFeePolicy() { + return { + 10000000ULL, // Transfer + 500000000ULL, // SecondSignatureRegistration + 2500000000ULL, // DelegateRegistration + 100000000ULL, // Vote + 500000000ULL, // MultiSignatureRegistration + 0ULL, // Ipfs + 0ULL, // TimelockTransfer + 0ULL, // MultiPayment + 2500000000ULL // DelegateResignation + }; +} + +} // namespace defaults +} // namespace Crypto +} // namespace Ark diff --git a/src/helpers/crypto.cpp b/src/helpers/crypto.cpp index 79494fae..9d2d9a85 100644 --- a/src/helpers/crypto.cpp +++ b/src/helpers/crypto.cpp @@ -1,6 +1,6 @@ + #include "helpers/crypto.h" -#include #include "bcl/Ecdsa.hpp" #include "bcl/Sha256.hpp" #include "bcl/Uint256.hpp" @@ -9,34 +9,66 @@ #include "uECC.h" #include "bip66.h" -void cryptoSign(Sha256Hash hash, Ark::Crypto::Identities::PrivateKey privateKey, std::vector& signature) { +void cryptoSign( + Sha256Hash hash, + Ark::Crypto::Identities::PrivateKey privateKey, + std::vector& signature) { + // create r & s-values Uint256 r; Uint256 s; + // create the nonce uint8_t nonce32[32] = {}; - nonce_function_rfc6979(nonce32, hash.value, privateKey.toBytes(), nullptr, nullptr, 0); + nonce_function_rfc6979( + nonce32, + hash.value, + privateKey.toBytes(), + nullptr, nullptr, 0); + + // sign the hash using privateKey-bytes and nonce. + // outputs r & s-values. + Ecdsa::sign( + Uint256(privateKey.toBytes()), + hash, + Uint256(nonce32), + r, s); - auto ret = Ecdsa::sign(Uint256(privateKey.toBytes()), hash, Uint256(nonce32), r, s); - assert(ret); + // create r & s-value uint8_t vector + std::vector rValue(PRIVATEKEY_SIZE); + std::vector sValue(PRIVATEKEY_SIZE); - std::vector rValue(PRIVATEKEY_SIZE), sValue(PRIVATEKEY_SIZE); + // plate big-endian bytes into r & s-value buffers r.getBigEndianBytes(&rValue[0]); s.getBigEndianBytes(&sValue[0]); + // encode r & s-values into a BIP66/DER-encoded signature. BIP66::encode(rValue, sValue, signature); } -bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, std::vector& signature) { - /* Get the Uncompressed PublicKey */ - auto publicKeyBytes = publicKey.toBytes(); // compressed publicKey bytes (uint8_t*) - uint8_t uncompressedPublicKey[64] = {}; // create uncompressed publicKey buffer (uint8_t[64]) - const struct uECC_Curve_t* curve = uECC_secp256k1(); // define the curve-type - uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); // decompress the key +/**/ + +bool cryptoVerify( + Ark::Crypto::Identities::PublicKey publicKey, + Sha256Hash hash, + std::vector& signature) { + // Get the Uncompressed PublicKey + + // compressed publicKey bytes (uint8_t*) + auto publicKeyBytes = publicKey.toBytes(); + + // create uncompressed publicKey buffer (uint8_t[64]) + uint8_t uncompressedPublicKey[64] = {}; + + // define the curve-type + const struct uECC_Curve_t* curve = uECC_secp256k1(); + + // decompress the key + uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); if (uECC_valid_public_key(uncompressedPublicKey, curve) == 0) { return false; }; // validate the uncompressed publicKey - /* Split uncompressed publicKey into (x,y) coordinate buffers */ + // Split uncompressed publicKey into (x,y) coordinate buffers char xBuffer[65] = "\0"; char yBuffer[65] = "\0"; for (int i = 0; i < 32; i++) { @@ -44,19 +76,21 @@ bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, snprintf(&yBuffer[i * 2], 64, "%02x", uncompressedPublicKey[i + 32]); } - /* Create curvepoint of uncompressed publicKey(x,y) */ - FieldInt x(xBuffer); // convert xBuffer to FieldInteger - FieldInt y(yBuffer); // convert yBuffer to FieldInteger + // Create curvepoint of uncompressed publicKey(x,y) + // convert xBuffer & yBuffer to FieldInteger + FieldInt x(xBuffer); + FieldInt y(yBuffer); CurvePoint curvePoint(x, y); - /* Decode signature from DER into r & s buffers */ - std::vector rValue(PRIVATEKEY_SIZE), sValue(PRIVATEKEY_SIZE); - + /// Decode signature from DER into r & s buffers + std::vector rValue(PRIVATEKEY_SIZE); + std::vector sValue(PRIVATEKEY_SIZE); BIP66::decode(signature, rValue, sValue); - Uint256 r256(rValue.data()); // create Uint256/BigNumber from r-value buffer - Uint256 s256(sValue.data()); // create Uint256/BigNumber from s-value buffer + // create Uint256/BigNumber from r & s-value buffers + Uint256 r256(rValue.data()); + Uint256 s256(sValue.data()); - /* Verify */ + // Verify return Ecdsa::verify(curvePoint, hash, r256, s256); } diff --git a/src/helpers/crypto.h b/src/helpers/crypto.h index 204adaa4..a1c9629b 100644 --- a/src/helpers/crypto.h +++ b/src/helpers/crypto.h @@ -17,7 +17,16 @@ #ifndef CRYPTO_H #define CRYPTO_H -void cryptoSign(Sha256Hash hash, Ark::Crypto::Identities::PrivateKey privateKey, std::vector& signature); -bool cryptoVerify(Ark::Crypto::Identities::PublicKey publicKey, Sha256Hash hash, std::vector& signature); +void cryptoSign( + Sha256Hash hash, + Ark::Crypto::Identities::PrivateKey privateKey, + std::vector& signature); + +/**/ + +bool cryptoVerify( + Ark::Crypto::Identities::PublicKey publicKey, + Sha256Hash hash, + std::vector& signature); #endif diff --git a/src/helpers/crypto_helpers.h b/src/helpers/crypto_helpers.h index b34a48ca..2982f712 100644 --- a/src/helpers/crypto_helpers.h +++ b/src/helpers/crypto_helpers.h @@ -15,10 +15,10 @@ #include #include -const auto ADDRESS_LENGTH = 34u; -const auto COMPRESSED_PUBLICKEY_SIZE = 33u; -const auto PRIVATEKEY_SIZE = 32u; -const auto WIF_SIZE = 52u; +const auto ADDRESS_LENGTH = 34U; +const auto COMPRESSED_PUBLICKEY_SIZE = 33U; +const auto PRIVATEKEY_SIZE = 32U; +const auto WIF_SIZE = 52U; #if (defined ARDUINO || defined ESP8266 || defined ESP32) @@ -29,6 +29,13 @@ const auto WIF_SIZE = 52u; #endif +#ifndef USE_IOT + +#define __STDC_FORMAT_MACROS 1 +#include + +#endif + // Write data into dst template inline void pack(std::vector& dst, T& data) { @@ -44,8 +51,12 @@ inline void unpack(T* dst, uint8_t* src, size_t size = -1) { // Join string vector inline std::string join(const std::vector& strings) { - return std::accumulate(strings.begin(), strings.end(), std::string(), - [](const std::string& a, const std::string& b) -> std::string { return a + b; }); + return std::accumulate( + strings.begin(), + strings.end(), + std::string(), + [](const std::string& a, const std::string& b) + -> std::string { return a + b; }); } #endif diff --git a/src/helpers/json.h b/src/helpers/json.h index a4b8c984..d28d8234 100644 --- a/src/helpers/json.h +++ b/src/helpers/json.h @@ -2,12 +2,12 @@ #ifndef JSON_H #define JSON_H -/* ArduinoJson Presets */ +// ArduinoJson Presets #define ARDUINOJSON_USE_LONG_LONG 1 #define ARDUINOJSON_ENABLE_STD_STRING 1 // Enable 'std::string' #define ARDUINOJSON_ENABLE_ARDUINO_STRING 0 // disable 'String' -/* ArduinoJson Header */ +// ArduinoJson Header #include "ArduinoJson.h" #endif diff --git a/src/identities/address.cpp b/src/identities/address.cpp index ce1ff11e..3b048212 100644 --- a/src/identities/address.cpp +++ b/src/identities/address.cpp @@ -1,147 +1,110 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "identities/address.h" -/** - * @brief: constructor - * - * @param: const char *const newAddressStr - **/ -Ark::Crypto::Identities::Address::Address(const char *const newAddressStr) { +#include "identities/privatekey.h" +#include "identities/publickey.h" + +#include "helpers/encoding/hex.h" + +#include "bcl/Base58Check.hpp" + +#include + +Ark::Crypto::Identities::Address::Address( + const char* newAddressStr) { (strlen(newAddressStr) == ADDRESS_LENGTH) - ? void(memmove(this->bytes_, reinterpret_cast(newAddressStr), ADDRESS_LENGTH)) + ? void(memmove( + this->bytes_, + reinterpret_cast(newAddressStr), + ADDRESS_LENGTH)) : void(this->bytes_[COMPRESSED_PUBLICKEY_SIZE] = {'\0'}); } /**/ -Ark::Crypto::Identities::Address::Address(const uint8_t *newAddressBytes) { +Ark::Crypto::Identities::Address::Address( + const uint8_t* newAddressBytes) { memmove(this->bytes_, newAddressBytes, ADDRESS_LENGTH); } + /**/ -/** - * @brief: returns bytes of Address - * - * @return const uint8_t - **/ const uint8_t *Ark::Crypto::Identities::Address::toBytes() { return this->bytes_; } + /**/ -/** - * @brief: returns std::string representation of stored bytes - **/ std::string Ark::Crypto::Identities::Address::toString() const { return std::string(this->bytes_, this->bytes_ + ADDRESS_LENGTH); } + /**/ -/** - * @brief Derive the address from the given passphrase. - * - * @param const char* const passphrase - * @param uint8_t networkVersion - * - * @return Address - **/ -Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPassphrase(const char *const passphrase, - uint8_t networkVersion) { +Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPassphrase( + const char* passphrase, + uint8_t networkVersion) { PublicKey publicKey = PublicKey::fromPassphrase(passphrase); return fromPublicKey(publicKey, networkVersion); } + /**/ -/** - * @brief Derive the address from the given private key. - * - * @param PrivateKey privateKey - * @param uint8_t networkVersion - * - * @return Address - **/ -Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPrivateKey(PrivateKey privateKey, - uint8_t networkVersion) { +Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPrivateKey( + PrivateKey privateKey, + uint8_t networkVersion) { PublicKey publicKey = PublicKey::fromPrivateKey(privateKey); return fromPublicKey(publicKey, networkVersion); } + /**/ -/** - * @brief Derive the address from the given public key. - * - * @param PublicKey publicKey - * @param uint8_t networkVersion - * - * @return Address - **/ -Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPublicKey(PublicKey publicKey, - uint8_t networkVersion) { +Ark::Crypto::Identities::Address Ark::Crypto::Identities::Address::fromPublicKey( + PublicKey publicKey, + uint8_t networkVersion) { std::vector seed(Ripemd160::HASH_LEN); - Ripemd160::getHash(publicKey.toBytes(), COMPRESSED_PUBLICKEY_SIZE, &seed[0]); + Ripemd160::getHash( + publicKey.toBytes(), + COMPRESSED_PUBLICKEY_SIZE, + &seed[0]); std::string s(35, '\0'); Base58Check::pubkeyHashToBase58Check(&seed[0], networkVersion, &s[0]); - return {s.c_str()}; + return { s.c_str() }; } + /**/ -/** - * @brief Validate the given address. - * - * @param Address address - * @param uint8_t networkVersion - * - * @return bool - **/ -bool Ark::Crypto::Identities::Address::validate(Address address, uint8_t networkVersion) { +bool Ark::Crypto::Identities::Address::validate( + Address address, + uint8_t networkVersion) { std::uint8_t pub_key_hash[Ripemd160::HASH_LEN] = {}; uint8_t version = 0; - Base58Check::pubkeyHashFromBase58Check(address.toString().c_str(), pub_key_hash, &version); + Base58Check::pubkeyHashFromBase58Check( + address.toString().c_str(), + pub_key_hash, + &version); return version == networkVersion; } + /**/ -/** - * @brief Validate the given Address string to the network version. - * - * @param const char *const privateKey - * @param uint8_t networkVersion - * - * @return bool - **/ -bool Ark::Crypto::Identities::Address::validate(const char *const addressStr, uint8_t networkVersion) { +bool Ark::Crypto::Identities::Address::validate( + const char* addressStr, + uint8_t networkVersion) { return validate(Address(addressStr), networkVersion); } + /**/ -/** - * @brief Validate the given Address bytes to the network version. - * - * @param const uint8_t *addressBytes - * @param uint8_t networkVersion - * - * @return bool - **/ -bool Ark::Crypto::Identities::Address::validate(const uint8_t *addressBytes, uint8_t networkVersion) { +bool Ark::Crypto::Identities::Address::validate( + const uint8_t* addressBytes, + uint8_t networkVersion) { return validate(Address(addressBytes), networkVersion); } + /**/ -/** - * @brief Reads 21 bytes from source and returns an base58 encoded string - * - * @param uint8_t *source - * - * @return std::string - **/ -std::string Ark::Crypto::Identities::Address::base58encode(const uint8_t *source) { +std::string Ark::Crypto::Identities::Address::base58encode( + const uint8_t* source) { // Magic numbers from Base58Check::pubkeyHashToBase58Check uint8_t temp[21 + 4] = {}; char out[ADDRESS_LENGTH + 1] = {}; @@ -154,19 +117,18 @@ std::string Ark::Crypto::Identities::Address::base58encode(const uint8_t *source return std::string(out); } -/** - * @brief Decodes the base58 encoded address - * - * @param const char* const address - * - * @return std::vector - **/ -std::vector Ark::Crypto::Identities::Address::bytesFromBase58Check(const char *const address) { - std::vector recipientIdBytes; - recipientIdBytes.resize(Ripemd160::HASH_LEN); +/**/ + +std::vector Ark::Crypto::Identities::Address::bytesFromBase58Check( + const char* address) { + std::vector recipientBytes; + recipientBytes.resize(Ripemd160::HASH_LEN); uint8_t version = 0; - Base58Check::pubkeyHashFromBase58Check(address, &recipientIdBytes[0], &version); - recipientIdBytes.insert(recipientIdBytes.begin(), version); + Base58Check::pubkeyHashFromBase58Check( + address, + &recipientBytes[0], + &version); + recipientBytes.insert(recipientBytes.begin(), version); - return recipientIdBytes; + return recipientBytes; } diff --git a/src/identities/privatekey.cpp b/src/identities/privatekey.cpp index 2c49d4c9..35c17435 100644 --- a/src/identities/privatekey.cpp +++ b/src/identities/privatekey.cpp @@ -1,125 +1,101 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "identities/privatekey.h" -/** - * - **/ -Ark::Crypto::Identities::PrivateKey::PrivateKey(const char *const newPrivateKeyStr) { - memmove(this->bytes_, &HexToBytes(newPrivateKeyStr).data()[0], PRIVATEKEY_SIZE); +#include "helpers/encoding/hex.h" + +#include "bcl/Base58Check.hpp" +#include "bcl/Sha256.hpp" +#include "bcl/Sha256Hash.hpp" + +#include +#include +#include + +Ark::Crypto::Identities::PrivateKey::PrivateKey( + const char* newPrivateKeyStr) { + memmove( + this->bytes_, + HexToBytes(newPrivateKeyStr).data(), + PRIVATEKEY_SIZE); } + /**/ -/** - * - **/ -Ark::Crypto::Identities::PrivateKey::PrivateKey(const uint8_t *newPrivateKeyBytes) { +Ark::Crypto::Identities::PrivateKey::PrivateKey( + const uint8_t* newPrivateKeyBytes) { memmove(this->bytes_, newPrivateKeyBytes, PRIVATEKEY_SIZE); } + /**/ -/** - * - **/ const uint8_t *Ark::Crypto::Identities::PrivateKey::toBytes() { return this->bytes_; }; + /**/ -/** - * - **/ std::string Ark::Crypto::Identities::PrivateKey::toString() const { return BytesToHex(this->bytes_, this->bytes_ + PRIVATEKEY_SIZE); } + /**/ -/** - * @brief Derive the private key for the given passphrase. - * - * @param const char* const passphrase - * - * @return std::string - **/ -Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromPassphrase(const char *const passphrase) { +Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromPassphrase( + const char* passphrase) { std::vector privateKey(PRIVATEKEY_SIZE); - auto hash = Sha256::getHash(reinterpret_cast(passphrase), strlen(passphrase)); + auto hash = Sha256::getHash( + reinterpret_cast(passphrase), + strlen(passphrase)); memcpy(&privateKey[0], hash.value, privateKey.size()); - return {BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str()}; + return { + BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str() + }; } + /**/ -/** - * @brief Create a private key instance from a hex string. - * - * @param const char *const privateKey - * - * @return PrivateKey - **/ -Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromHex(const char *const privateKey) { - return {privateKey}; +Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromHex( + const char* privateKey) { + return { privateKey }; } + /**/ -/** - * @brief Derive the private key for the given WIF. - * - * @param const char* wifStr - * @param uint8_t wifByte - * - * @return PrivateKey - **/ -Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromWIFString(const char *wifStr, - uint8_t wifByte) { +Ark::Crypto::Identities::PrivateKey Ark::Crypto::Identities::PrivateKey::fromWIFString( + const char* wifStr, + uint8_t wifByte) { Uint256 bigNum; bool compressed = true; - auto ret = Base58Check::privateKeyFromBase58Check(wifStr, bigNum, &wifByte, &compressed); - assert(ret); + Base58Check::privateKeyFromBase58Check( + wifStr, + bigNum, + &wifByte, + &compressed); std::vector privateKey(PRIVATEKEY_SIZE); bigNum.getBigEndianBytes(&privateKey[0]); - return {BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str()}; + return { + BytesToHex(&privateKey[0], &privateKey[0] + PRIVATEKEY_SIZE).c_str() + }; } + /**/ -/** - * @brief Validate the given private key. - * - * @param PrivateKey privateKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PrivateKey::validate(PrivateKey privateKey) { +bool Ark::Crypto::Identities::PrivateKey::validate( + PrivateKey privateKey) { return PrivateKey::validate(privateKey.toString().c_str()); -}; +} + /**/ -/** - * @brief Validate the given private key. - * - * @param const char *const privateKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PrivateKey::validate(const char *privateKeyStr) { - return ((strlen(privateKeyStr) / 2) == PRIVATEKEY_SIZE); // check length +bool Ark::Crypto::Identities::PrivateKey::validate( + const char* privateKeyStr) { + // check length + return ((strlen(privateKeyStr) / 2) == PRIVATEKEY_SIZE); } + /**/ -/** - * @brief Validate the given private key. - * - * @param const uint8_t *privateKeyBytes - * - * @return bool - **/ -bool Ark::Crypto::Identities::PrivateKey::validate(const uint8_t *privateKeyBytes) { +bool Ark::Crypto::Identities::PrivateKey::validate( + const uint8_t* privateKeyBytes) { return validate(PrivateKey(privateKeyBytes)); } -/**/ diff --git a/src/identities/publickey.cpp b/src/identities/publickey.cpp index 3363f879..c33b7129 100644 --- a/src/identities/publickey.cpp +++ b/src/identities/publickey.cpp @@ -1,134 +1,113 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ + #include "identities/publickey.h" + +#include "helpers/encoding/hex.h" + #include "uECC.h" -/** - * - **/ -Ark::Crypto::Identities::PublicKey::PublicKey(const char *const newPublicKeyStr) { - memmove(this->bytes_, &HexToBytes(newPublicKeyStr).data()[0], COMPRESSED_PUBLICKEY_SIZE); + +#include +#include +#include +#include + +Ark::Crypto::Identities::PublicKey::PublicKey( + const char* newPublicKeyStr) { + memmove( + this->bytes_, + HexToBytes(newPublicKeyStr).data(), + COMPRESSED_PUBLICKEY_SIZE); } + /**/ -/** - * - **/ -Ark::Crypto::Identities::PublicKey::PublicKey(const uint8_t *newPublicKeyBytes) { +Ark::Crypto::Identities::PublicKey::PublicKey( + const uint8_t* newPublicKeyBytes) { memmove(this->bytes_, newPublicKeyBytes, COMPRESSED_PUBLICKEY_SIZE); } + /**/ -/** - * - **/ -const uint8_t *Ark::Crypto::Identities::PublicKey::toBytes() { +const uint8_t* Ark::Crypto::Identities::PublicKey::toBytes() { return this->bytes_; } + /**/ -/** - * - **/ bool Ark::Crypto::Identities::PublicKey::isValid() { return PublicKey::validate(*this); } + /**/ -/** - * - **/ std::string Ark::Crypto::Identities::PublicKey::toString() const { return BytesToHex(this->bytes_, this->bytes_ + COMPRESSED_PUBLICKEY_SIZE); } + /**/ -/** - * @brief Derive the public from the given passphrase. - * - * @param const char *const passphrase - * - * @return std::string - **/ -Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPassphrase(const char *const passphrase) { +Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPassphrase( + const char* passphrase) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); return PublicKey::fromPrivateKey(privateKey); } + /**/ -/** - * - **/ -Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPrivateKey(PrivateKey privateKey) { +Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromPrivateKey( + PrivateKey privateKey) { std::vector publicKey(COMPRESSED_PUBLICKEY_SIZE); const struct uECC_Curve_t *curve = uECC_secp256k1(); uint8_t pub[64] = {}; // TODO: using the current uECC implementation, a private key value of "1" will return a false negative. // It appears to be not supported given the following issue: https://github.com/kmackay/micro-ecc/issues/128 const uint8_t *privkeyBytes = privateKey.toBytes(); - auto ret = uECC_compute_public_key( - &privkeyBytes[0], pub, curve); // Don't check the return inline with the assert. MSVC optimizer does bad things. - assert(ret != 0); - assert(publicKey.size() == COMPRESSED_PUBLICKEY_SIZE); + // Don't check the return inline with the assert. MSVC optimizer does bad things. + uECC_compute_public_key( + &privkeyBytes[0], + pub, + curve); uECC_compress(pub, &publicKey[0], curve); - return {BytesToHex(&publicKey[0], &publicKey[0] + COMPRESSED_PUBLICKEY_SIZE).c_str()}; + return { + BytesToHex(&publicKey[0], &publicKey[0] + COMPRESSED_PUBLICKEY_SIZE).c_str() + }; } + /**/ -/** - * @brief Create a public key instance from a hex string. - * - * @param const char *const publicKey - * - * @return PublicKey - **/ -Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromHex(const char *const publicKey) { - return {publicKey}; -}; +Ark::Crypto::Identities::PublicKey Ark::Crypto::Identities::PublicKey::fromHex( + const char* publicKey) { + return { publicKey }; +} + /**/ -/** - * @brief Validate the given public key. - * - * @param PublicKey publicKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PublicKey::validate(PublicKey publicKey) { - auto publicKeyBytes = publicKey.toBytes(); // compressed publicKey bytes (uint8_t*) - uint8_t uncompressedPublicKey[64] = {}; // create uncompressed publicKey buffer (uint8_t[64]) - const struct uECC_Curve_t *curve = uECC_secp256k1(); // define the curve-type - uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); // decompress the key - return uECC_valid_public_key(uncompressedPublicKey, curve); // validate the uncompressed publicKey +bool Ark::Crypto::Identities::PublicKey::validate( + PublicKey publicKey) { + // compressed publicKey bytes (uint8_t*) + auto publicKeyBytes = publicKey.toBytes(); + // create uncompressed publicKey buffer (uint8_t[64]) + uint8_t uncompressedPublicKey[64] = {}; + // define the curve-type + const struct uECC_Curve_t *curve = uECC_secp256k1(); + + // decompress the key + uECC_decompress(publicKeyBytes, uncompressedPublicKey, curve); + + // validate the uncompressed publicKey + return (uECC_valid_public_key(uncompressedPublicKey, curve) != 0); } + /**/ -/** - * @brief Validate the given public key. - * - * @param const char *const publicKey - * - * @return bool - **/ -bool Ark::Crypto::Identities::PublicKey::validate(const char *publicKeyStr) { +bool Ark::Crypto::Identities::PublicKey::validate( + const char* publicKeyStr) { return validate(PublicKey(publicKeyStr)); } + /**/ -/** - * @brief Validate the given public key. - * - * @param const uint8_t *publicKeyBytes - * - * @return bool - **/ -bool Ark::Crypto::Identities::PublicKey::validate(const uint8_t *publicKeyBytes) { +bool Ark::Crypto::Identities::PublicKey::validate( + const uint8_t* publicKeyBytes) { return validate(PublicKey(publicKeyBytes)); } -/**/ diff --git a/src/identities/wif.cpp b/src/identities/wif.cpp index f1cbc294..14e71e28 100644 --- a/src/identities/wif.cpp +++ b/src/identities/wif.cpp @@ -1,53 +1,63 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "identities/wif.h" -/**/ -Ark::Crypto::Identities::WIF::WIF(const char *const newWIFStr) { - (std::strlen(newWIFStr) == WIF_SIZE) - ? void(std::memmove(this->bytes_, reinterpret_cast(newWIFStr), WIF_SIZE)) +#include "helpers/encoding/hex.h" + +#include "bcl/Base58Check.hpp" +#include "bcl/Uint256.hpp" + +#include +#include +#include +#include + +Ark::Crypto::Identities::WIF::WIF( + const char* newWIFStr) { + (strlen(newWIFStr) == WIF_SIZE) + ? void(memmove( + this->bytes_, + reinterpret_cast(newWIFStr), + WIF_SIZE)) : void(this->bytes_[WIF_SIZE - 1] = {'\0'}); } -/**/ /**/ -Ark::Crypto::Identities::WIF::WIF(const uint8_t *newWIFBytes) { - std::memmove(this->bytes_, newWIFBytes, WIF_SIZE); + +Ark::Crypto::Identities::WIF::WIF( + const uint8_t* newWIFBytes) { + memmove(this->bytes_, newWIFBytes, WIF_SIZE); } -/**/ /**/ + const uint8_t *Ark::Crypto::Identities::WIF::toBytes() { return this->bytes_; }; -/**/ /**/ + std::string Ark::Crypto::Identities::WIF::toString() const { return std::string(this->bytes_, this->bytes_ + WIF_SIZE); } + +/**/ + +bool Ark::Crypto::Identities::WIF::validate(WIF wif) { + const auto wifString = wif.toString(); + return strrchr(wifString.c_str(), '\0') == nullptr; +} + /**/ -/** - * @brief Derive the WIF from the given passphrase. - * - * @param const char *const passphrase - * @param uint8_t wifByte - * - * @return WIF - **/ -Ark::Crypto::Identities::WIF Ark::Crypto::Identities::WIF::fromPassphrase(const char *const passphrase, - uint8_t wifByte) { +Ark::Crypto::Identities::WIF Ark::Crypto::Identities::WIF::fromPassphrase( + const char* passphrase, + uint8_t wifByte) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); std::string wifStr(53, '\0'); - Base58Check::privateKeyToBase58Check(Uint256(privateKey.toString().c_str()), wifByte, true, &wifStr[0]); - return {wifStr.c_str()}; + Base58Check::privateKeyToBase58Check( + Uint256(privateKey.toString().c_str()), + wifByte, + true, + &wifStr[0]); + return { wifStr.c_str() }; } -/**/ diff --git a/src/include/cpp-crypto/arkCrypto.h b/src/include/cpp-crypto/arkCrypto.h index 17f23742..ec069466 100644 --- a/src/include/cpp-crypto/arkCrypto.h +++ b/src/include/cpp-crypto/arkCrypto.h @@ -10,26 +10,22 @@ #ifndef ARKCRYPTO_H #define ARKCRYPTO_H -#define HAS_CRYPTO +#include "common/configuration.hpp" +#include "common/fee_policy.hpp" +#include "common/network.hpp" -#if (defined ARDUINO || defined ESP8266 || defined ESP32) -#define USE_IOT -#endif - -#include "configuration/fee.h" -#include "configuration/network.h" -#include "enums/fees.h" -#include "enums/types.h" +#include "defaults/fee_policies.hpp" +#include "defaults/static_fees.hpp" +#include "defaults/transaction_types.hpp" #include "identities/address.h" #include "identities/privatekey.h" #include "identities/publickey.h" #include "identities/wif.h" -#include "networks/abstractnetwork.h" -#include "networks/devnet.h" -#include "networks/mainnet.h" -#include "networks/testnet.h" +#include "networks/devnet.hpp" +#include "networks/mainnet.hpp" +#include "networks/testnet.hpp" #include "transactions/builder.h" #include "transactions/deserializer.h" @@ -39,10 +35,9 @@ #include "utils/message.h" #include "utils/slot.h" -using namespace Ark::Crypto::Configuration; -using namespace Ark::Crypto::Enums; +using namespace Ark::Crypto; using namespace Ark::Crypto::Identities; -using namespace Ark::Crypto::Networks; using namespace Ark::Crypto::Transactions; +using namespace Ark::Crypto::Utils; #endif diff --git a/src/include/cpp-crypto/common/configuration.hpp b/src/include/cpp-crypto/common/configuration.hpp new file mode 100644 index 00000000..abc7eaf0 --- /dev/null +++ b/src/include/cpp-crypto/common/configuration.hpp @@ -0,0 +1,45 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef COMMON_CONFIGURATION_HPP +#define COMMON_CONFIGURATION_HPP + +#include "common/network.hpp" +#include "managers/network_manager.hpp" +#include "common/fee_policy.hpp" +#include "managers/fee_manager.hpp" + +namespace Ark { +namespace Crypto { +/**/ +class Configuration : public managers::NetworkManager, + public managers::FeeManager { + public: + // Default initialization: using ARK Devnet & StaticFees + Configuration() = default; + ~Configuration() = default; + + // Network initialization: Custom Network & StaticFees + explicit Configuration(const Network& network) : NetworkManager(network) {} + + // FeePolicy initialization: ARK Devnet & Custom Fees + explicit Configuration(const FeePolicy& policy) : FeeManager(policy) {} + + // Network & Fee initialization: Custom Network & Custom Fees + Configuration(const Network& network, const FeePolicy& policy) + : NetworkManager(network), FeeManager(policy) {} + + bool operator==(const Configuration& rhs) const; + bool operator!=(const Configuration& rhs) const; +}; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/common/fee_policy.hpp b/src/include/cpp-crypto/common/fee_policy.hpp new file mode 100644 index 00000000..bede2c6a --- /dev/null +++ b/src/include/cpp-crypto/common/fee_policy.hpp @@ -0,0 +1,24 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef COMMON_TRANSACTION_FEE_POLICY_HPP +#define COMMON_TRANSACTION_FEE_POLICY_HPP + +#include +#include + +namespace Ark { +namespace Crypto { +/**/ +typedef std::vector FeePolicy; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/common/network.hpp b/src/include/cpp-crypto/common/network.hpp new file mode 100644 index 00000000..d93a19bd --- /dev/null +++ b/src/include/cpp-crypto/common/network.hpp @@ -0,0 +1,56 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef COMMON_NETWORK_H +#define COMMON_NETWORK_H + +#include +#include + +namespace Ark { +namespace Crypto { +/**/ +// Abstract Network class +// +// Default initialization is ARK Devnet +class Network final { + public: + Network(); + Network(std::string nethash, + uint8_t slip44, + uint8_t wif, + uint8_t version, + std::string epoch) + : nethash_(nethash), + slip44_(slip44), + wif_(wif), + version_(version), + epoch_(epoch) {} + + std::string nethash() const; + uint8_t slip44() const; + uint8_t wif() const; + uint8_t version() const; + std::string epoch() const; + + bool operator==(const Network& rhs) const; + bool operator!=(const Network& rhs) const; + + private: + std::string nethash_; + uint8_t slip44_; + uint8_t wif_; + uint8_t version_; + std::string epoch_; +}; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/configuration/fee.h b/src/include/cpp-crypto/configuration/fee.h deleted file mode 100644 index 986c5634..00000000 --- a/src/include/cpp-crypto/configuration/fee.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef FEE_H -#define FEE_H - -#include "enums/fees.h" -#include "enums/types.h" -using namespace Ark::Crypto::Enums; - -#include - -namespace Ark { -namespace Crypto { -namespace Configuration { -/** - * This is the fee configuration class. - * - * @author Simon Downey - **/ -class Fee { - private: - /** - * @brief The default transaction fees array. - **/ - uint64_t fees_[9] = {Fees::TRANSFER, - Fees::SECOND_SIGNATURE_REGISTRATION, - Fees::DELEGATE_REGISTRATION, - Fees::VOTE, - Fees::MULTI_SIGNATURE_REGISTRATION, - Fees::IPFS, - Fees::TIMELOCK_TRANSFER, - Fees::MULTI_PAYMENT, - Fees::DELEGATE_RESIGNATION}; - /**/ - public: - Fee() = default; - uint64_t get(int type); - void set(int type, uint64_t fee); -}; -/**/ - -}; // namespace Configuration -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/configuration/network.h b/src/include/cpp-crypto/configuration/network.h deleted file mode 100644 index a6bb4d4e..00000000 --- a/src/include/cpp-crypto/configuration/network.h +++ /dev/null @@ -1,44 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef NETWORK_H -#define NETWORK_H - -#include "networks/abstractnetwork.h" -#include "networks/devnet.h" -#include "networks/mainnet.h" -#include "networks/testnet.h" - -#include - -namespace Ark { -namespace Crypto { -namespace Configuration { - -using namespace Ark::Crypto::Networks; - -/** - * @brief This is the network configuration class. - * - * @author Simon Downey - **/ -class Network { - private: - AbstractNetwork network_; - - public: - AbstractNetwork get(); - void set(const AbstractNetwork& network); -}; -/**/ -}; // namespace Configuration -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/defaults/fee_policies.hpp b/src/include/cpp-crypto/defaults/fee_policies.hpp new file mode 100644 index 00000000..390f3474 --- /dev/null +++ b/src/include/cpp-crypto/defaults/fee_policies.hpp @@ -0,0 +1,30 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef DEFAULTS_TRANSACTIONS_FEE_POLICIES_HPP +#define DEFAULTS_TRANSACTIONS_FEE_POLICIES_HPP + +#include + +#include "common/fee_policy.hpp" + +namespace Ark { +namespace Crypto { +namespace defaults { +/**/ +class Fees { + public: + static const FeePolicy StaticFeePolicy(); +}; +/**/ +} // namespace defaults +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/defaults/static_fees.hpp b/src/include/cpp-crypto/defaults/static_fees.hpp new file mode 100644 index 00000000..ccddd95c --- /dev/null +++ b/src/include/cpp-crypto/defaults/static_fees.hpp @@ -0,0 +1,29 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef DEFAULTS_TRANSACTIONS_STATIC_FEES_HPP +#define DEFAULTS_TRANSACTIONS_STATIC_FEES_HPP + +#include "defaults/fee_policies.hpp" + +// const FeePolicy Fees::StaticFeePolicy() { +// return { +// 10000000ULL, // Transfer +// 500000000ULL, // SecondSignatureRegistration +// 2500000000ULL, // DelegateRegistration +// 100000000ULL, // Vote +// 500000000ULL, // MultiSignatureRegistration +// 0ULL, // Ipfs +// 0ULL, // TimelockTransfer +// 0ULL, // MultiPayment +// 2500000000ULL // DelegateResignation +// }; +// } + +#endif diff --git a/src/include/cpp-crypto/defaults/transaction_types.hpp b/src/include/cpp-crypto/defaults/transaction_types.hpp new file mode 100644 index 00000000..09cf5056 --- /dev/null +++ b/src/include/cpp-crypto/defaults/transaction_types.hpp @@ -0,0 +1,35 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef DEFAULTS_TRANSACTIONS_TYPES_HPP +#define DEFAULTS_TRANSACTIONS_TYPES_HPP + +#include + +namespace Ark { +namespace Crypto { +namespace defaults { +/**/ +enum TransactionTypes : uint8_t { + Transfer = 0, + SecondSignatureRegistration = 1, + DelegateRegistration = 2, + Vote = 3, + MultiSignatureRegistration = 4, + Ipfs = 5, + TimelockTransfer = 6, + MultiPayment = 7, + DelegateResignation = 8 +}; +/**/ +} // namespace defaults +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/enums/fees.h b/src/include/cpp-crypto/enums/fees.h deleted file mode 100644 index 9aa58e22..00000000 --- a/src/include/cpp-crypto/enums/fees.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef FEES_H -#define FEES_H - -#include - -namespace Ark { -namespace Crypto { -namespace Enums { -/** - * This is the transaction fees class. - * - * @author Simon Downey - **/ -struct Fees { - public: - static const uint64_t TRANSFER = 10000000; - static const uint64_t SECOND_SIGNATURE_REGISTRATION = 500000000; - static const uint64_t DELEGATE_REGISTRATION = 2500000000; - static const uint64_t VOTE = 100000000; - static const uint64_t MULTI_SIGNATURE_REGISTRATION = 500000000; - static const uint64_t IPFS = 0; - static const uint64_t TIMELOCK_TRANSFER = 0; - static const uint64_t MULTI_PAYMENT = 0; - static const uint64_t DELEGATE_RESIGNATION = 0; -}; -/**/ -}; // namespace Enums -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/enums/types.h b/src/include/cpp-crypto/enums/types.h deleted file mode 100644 index b7e6a088..00000000 --- a/src/include/cpp-crypto/enums/types.h +++ /dev/null @@ -1,37 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef TYPES_H -#define TYPES_H - -namespace Ark { -namespace Crypto { -namespace Enums { -/** - * This is the transaction types class. - * - * @author Simon Downey - **/ -enum Types : int { - TRANSFER = 0, - SECOND_SIGNATURE_REGISTRATION = 1, - DELEGATE_REGISTRATION = 2, - VOTE = 3, - MULTI_SIGNATURE_REGISTRATION = 4, - IPFS = 5, - TIMELOCK_TRANSFER = 6, - MULTI_PAYMENT = 7, - DELEGATE_RESIGNATION = 8 -}; -/**/ -}; // namespace Enums -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/helpers/encoding/hex.h b/src/include/cpp-crypto/helpers/encoding/hex.h index bc14ad19..88954764 100644 --- a/src/include/cpp-crypto/helpers/encoding/hex.h +++ b/src/include/cpp-crypto/helpers/encoding/hex.h @@ -17,49 +17,58 @@ * Hex Helpers **/ template -inline std::string BytesToHex(const T itbegin, const T itend, bool fSpaces = false) { +inline std::string BytesToHex( + const T itbegin, + const T itend) { + static const char hexmap[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' + }; + std::string rv; - static const char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; rv.reserve((itend - itbegin) * 3); for (T it = itbegin; it < itend; ++it) { const auto val = static_cast(*it); - if (fSpaces && it != itbegin) { - rv.push_back(' '); - } rv.push_back(hexmap[val >> 4]); rv.push_back(hexmap[val & 15]); } return rv; -} +}; /**/ template -inline std::string BytesToHex(const T& vch, bool fSpaces = false) { - return BytesToHex(vch.begin(), vch.end(), fSpaces); -} +inline std::string BytesToHex(const T& vch) { + return BytesToHex(vch.begin(), vch.end()); +}; -/********/ +/****/ const int8_t p_util_hexdigit[256] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, - 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, + -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; /**/ inline int8_t HexDigit(char c) { return p_util_hexdigit[static_cast(c)]; -} +}; /**/ @@ -67,23 +76,17 @@ inline std::vector HexToBytes(const char* psz) { // convert hex dump to vector std::vector vch; for (;;) { - while (isspace(*psz) != 0) { - psz++; - } + while (isspace(*psz) != 0) { psz++; }; auto c = HexDigit(*psz++); - if (c == static_cast(-1)) { - break; - } + if (c == static_cast(-1)) { break; }; int8_t n = (c << 4); c = HexDigit(*psz++); - if (c == static_cast(-1)) { - break; - } + if (c == static_cast(-1)) { break; }; n |= c; vch.push_back(n); - } + }; return vch; -} +}; /**/ diff --git a/src/include/cpp-crypto/identities/address.h b/src/include/cpp-crypto/identities/address.h index 7e71087d..48cb3cdb 100644 --- a/src/include/cpp-crypto/identities/address.h +++ b/src/include/cpp-crypto/identities/address.h @@ -10,42 +10,39 @@ #ifndef ADDRESS_H #define ADDRESS_H -#include -#include "helpers/encoding/hex.h" #include "helpers/crypto_helpers.h" + #include "identities/privatekey.h" #include "identities/publickey.h" +#include +#include + namespace Ark { namespace Crypto { namespace Identities { - -/** - * This is the address class. - * - * @author Simon Downey - **/ +/**/ class Address { - protected: - uint8_t bytes_[ADDRESS_LENGTH]; +private: + uint8_t bytes_[ADDRESS_LENGTH] {}; - public: - Address() : bytes_(){}; - Address(const char *const newAddressStr); - Address(const uint8_t *newAddressBytes); +public: + Address() : bytes_() {}; + Address(const char* newAddressStr); + Address(const uint8_t* newAddressBytes); const uint8_t *toBytes(); std::string toString() const; - static Address fromPassphrase(const char *const passphrase, uint8_t networkVersion); + static Address fromPassphrase(const char* passphrase, uint8_t networkVersion); static Address fromPrivateKey(PrivateKey privateKey, uint8_t networkVersion); static Address fromPublicKey(PublicKey publicKey, uint8_t networkVersion); static bool validate(Address address, uint8_t networkVersion); - static bool validate(const char *const addressStr, uint8_t networkVersion); - static bool validate(const uint8_t *addressBytes, uint8_t networkVersion); - static std::string base58encode(const uint8_t *source); - static std::vector bytesFromBase58Check(const char *const address); + static bool validate(const char* addressStr, uint8_t networkVersion); + static bool validate(const uint8_t* addressBytes, uint8_t networkVersion); + static std::string base58encode(const uint8_t* source); + static std::vector bytesFromBase58Check(const char* address); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/identities/privatekey.h b/src/include/cpp-crypto/identities/privatekey.h index f69da3c7..e442fb1d 100644 --- a/src/include/cpp-crypto/identities/privatekey.h +++ b/src/include/cpp-crypto/identities/privatekey.h @@ -10,42 +10,34 @@ #ifndef PRIVATEKEY_H #define PRIVATEKEY_H -#include -#include -#include "bcl/Base58Check.hpp" -#include "bcl/Sha256.hpp" -#include "bcl/Sha256Hash.hpp" -#include "helpers/encoding/hex.h" #include "helpers/crypto_helpers.h" +#include +#include + namespace Ark { namespace Crypto { namespace Identities { - -/** - * This is the private key class. - * - * @author Simon Downey - **/ +/**/ class PrivateKey { - protected: - uint8_t bytes_[PRIVATEKEY_SIZE]; +private: + uint8_t bytes_[PRIVATEKEY_SIZE] {}; - public: - PrivateKey() : bytes_(){}; - PrivateKey(const char *const newPrivateKeyStr); - PrivateKey(const uint8_t *newPrivateKeyBytes); +public: + PrivateKey() : bytes_() {}; + PrivateKey(const char* newPrivateKeyStr); + PrivateKey(const uint8_t* newPrivateKeyBytes); const uint8_t *toBytes(); std::string toString() const; - static PrivateKey fromPassphrase(const char *const passphrase); - static PrivateKey fromHex(const char *const privateKey); - static PrivateKey fromWIFString(const char *wifStr, uint8_t wifByte); + static PrivateKey fromPassphrase(const char* passphrase); + static PrivateKey fromHex(const char* privateKey); + static PrivateKey fromWIFString(const char* wifStr, uint8_t wifByte); static bool validate(PrivateKey privateKey); - static bool validate(const char *privateKeyStr); - static bool validate(const uint8_t *privateKeyBytes); + static bool validate(const char* privateKeyStr); + static bool validate(const uint8_t* privateKeyBytes); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/identities/publickey.h b/src/include/cpp-crypto/identities/publickey.h index 5dd35642..03cc4d2c 100644 --- a/src/include/cpp-crypto/identities/publickey.h +++ b/src/include/cpp-crypto/identities/publickey.h @@ -10,40 +10,39 @@ #ifndef PUBLICKEY_H #define PUBLICKEY_H -#include -#include "helpers/encoding/hex.h" -#include "helpers/crypto_helpers.h" #include "identities/privatekey.h" +#include "identities/publickey.h" + +#include "helpers/crypto_helpers.h" + +#include +#include namespace Ark { namespace Crypto { namespace Identities { -/** - * This is the public key class. - * - * @author Simon Downey - **/ +/**/ class PublicKey { - protected: - uint8_t bytes_[COMPRESSED_PUBLICKEY_SIZE]; +private: + uint8_t bytes_[COMPRESSED_PUBLICKEY_SIZE] {}; - public: - PublicKey() : bytes_(){}; - PublicKey(const char *const newPublicKeyStr); - PublicKey(const uint8_t *newPublicKeyBytes); +public: + PublicKey() : bytes_() {}; + PublicKey(const char* newPublicKeyStr); + PublicKey(const uint8_t* newPublicKeyBytes); const uint8_t *toBytes(); bool isValid(); std::string toString() const; - static PublicKey fromPassphrase(const char *const passphrase); + static PublicKey fromPassphrase(const char* passphrase); static PublicKey fromPrivateKey(PrivateKey privateKey); - static PublicKey fromHex(const char *const publicKey); + static PublicKey fromHex(const char* publicKey); static bool validate(PublicKey publicKey); - static bool validate(const char *publicKeyStr); - static bool validate(const uint8_t *publicKeyBytes); + static bool validate(const char* publicKeyStr); + static bool validate(const uint8_t* publicKeyBytes); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/identities/wif.h b/src/include/cpp-crypto/identities/wif.h index 096eac64..8d00d9ae 100644 --- a/src/include/cpp-crypto/identities/wif.h +++ b/src/include/cpp-crypto/identities/wif.h @@ -10,32 +10,30 @@ #ifndef WIF_H #define WIF_H -#include -#include "helpers/encoding/hex.h" #include "identities/privatekey.h" +#include +#include + namespace Ark { namespace Crypto { namespace Identities { - -/** - * This is the wif class. - * - * @author Simon Downey - **/ +/**/ class WIF { - protected: - uint8_t bytes_[WIF_SIZE]; +private: + uint8_t bytes_[WIF_SIZE] {}; - public: - WIF() : bytes_(){}; - WIF(const char *const newWIFStr); - WIF(const uint8_t *newWIFBytes); +public: + WIF() : bytes_() {}; + WIF(const char* newWIFStr); + WIF(const uint8_t* newWIFBytes); const uint8_t *toBytes(); std::string toString() const; - static WIF fromPassphrase(const char *const passphrase, uint8_t wifByte); + static WIF fromPassphrase(const char* passphrase, uint8_t wifByte); + + static bool validate(WIF wif); }; /**/ }; // namespace Identities diff --git a/src/include/cpp-crypto/networks/abstractnetwork.h b/src/include/cpp-crypto/networks/abstractnetwork.h deleted file mode 100644 index 9d49d0ef..00000000 --- a/src/include/cpp-crypto/networks/abstractnetwork.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef ABSTRACT_NETWORK_H -#define ABSTRACT_NETWORK_H - -#include -#include -#include - -namespace Ark { -namespace Crypto { -namespace Networks { - -/** - * @brief Base58 Prefix Type - **/ -enum Base58PrefixType : int { BASE58_ADDRESS_P2PKH = 0, BASE58_ADDRESS_P2SH, BASE58_WIF }; -/**/ - -/** - * @brief Base58 Prefix Container - **/ -struct base58_t { - uint8_t ADDRESS_P2PKH; - uint8_t ADDRESS_P2SH; - uint8_t WIF; -}; -/**/ - -/** - * @brief BIP32 Prefix Type - **/ -enum BIP32PrefixType : int { BIP32_PREFIX_XPUB = 0, BIP32_PREFIX_XPRV }; -/**/ -/** - * @brief BIP32 Prefix Container - **/ -struct bip32_t { - long PREFIX_XPUB; - long PREFIX_XPRV; -}; -/**/ - -/** - * @brief This is the abstract network class. - * - * @author Simon Downey - **/ -class AbstractNetwork { - protected: - base58_t base58_; - bip32_t bip32_; - char epoch_[34]; - bool isLocked_; - - public: - AbstractNetwork() = default; - - /** - * @brief Abstract Network Parameter Instantiation interface - * - * @param base58_t base58 - * @param bip32_t bip32 - * @param char epoch[34] - * @param bool isEditable // default false - **/ - AbstractNetwork(base58_t base58, bip32_t bip32, const char* epoch, bool locked = true) - : base58_(base58), bip32_(bip32), epoch_(), isLocked_(locked) { - std::strncpy(this->epoch_, epoch, 34); - }; - /**/ - - virtual ~AbstractNetwork() = default; - - uint8_t getBase58Prefix(Base58PrefixType prefix) const; - void setBase58Prefix(Base58PrefixType prefix, uint8_t newByte); - - long getBIP32Prefix(BIP32PrefixType prefix) const; - void setBIP32Prefix(BIP32PrefixType prefix, long newByte); - - bool isLocked() const; - - const char* epoch() const; - uint8_t version() const; -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/devnet.h b/src/include/cpp-crypto/networks/devnet.h deleted file mode 100644 index 3e48f276..00000000 --- a/src/include/cpp-crypto/networks/devnet.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef DEVNET_H -#define DEVNET_H - -#include "networks/abstractnetwork.h" - -namespace Ark { -namespace Crypto { -namespace Networks { -/** - * This is the devnet network class. - * - * @author Simon Downey - **/ -const AbstractNetwork Devnet = { - { - 0x1E, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xaa // BASE58_WIF - }, - { - 46090600, // BIP32_PREFIX_XPUB - 46089520 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/devnet.hpp b/src/include/cpp-crypto/networks/devnet.hpp new file mode 100644 index 00000000..57100d50 --- /dev/null +++ b/src/include/cpp-crypto/networks/devnet.hpp @@ -0,0 +1,23 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_DEVNET_HPP +#define NETWORKS_DEVNET_HPP + +#include "networks/networks.hpp" + +// const Network Devnet { +// "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", // nethash +// 1, // slip44 +// 0xaa, // wif +// 0x1E, // version +// "2017-03-21T13:00:00.000Z" // epoch +// }; + +#endif diff --git a/src/include/cpp-crypto/networks/mainnet.h b/src/include/cpp-crypto/networks/mainnet.h deleted file mode 100644 index 00a6d189..00000000 --- a/src/include/cpp-crypto/networks/mainnet.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef MAINNET_H -#define MAINNET_H - -#include "networks/abstractnetwork.h" - -namespace Ark { -namespace Crypto { -namespace Networks { -/** - * @brief This is the mainnet network class. - * - * @author Simon Downey - **/ -const AbstractNetwork Mainnet = { - { - 0x17, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xaa // BASE58_WIF - }, - { - 46090600, // BIP32_PREFIX_XPUB - 46089520 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/mainnet.hpp b/src/include/cpp-crypto/networks/mainnet.hpp new file mode 100644 index 00000000..624c728c --- /dev/null +++ b/src/include/cpp-crypto/networks/mainnet.hpp @@ -0,0 +1,23 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_MAINNET_HPP +#define NETWORKS_MAINNET_HPP + +#include "networks/networks.hpp" + +// const Network Mainnet { +// "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988", // nethash +// 111, // slip44 +// 0xaa, // wif +// 0x17, // version +// "2017-03-21T13:00:00.000Z" // epoch +// }; + +#endif diff --git a/src/include/cpp-crypto/networks/networks.hpp b/src/include/cpp-crypto/networks/networks.hpp new file mode 100644 index 00000000..8385ec1e --- /dev/null +++ b/src/include/cpp-crypto/networks/networks.hpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_HPP +#define NETWORKS_HPP + +#include "common/network.hpp" + +namespace Ark { +namespace Crypto { +/**/ +class Networks { + public: + static const Network Devnet(); + static const Network Mainnet(); + static const Network Testnet(); +}; +/**/ +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/include/cpp-crypto/networks/testnet.h b/src/include/cpp-crypto/networks/testnet.h deleted file mode 100644 index 97689c78..00000000 --- a/src/include/cpp-crypto/networks/testnet.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#ifndef TESTNET_H -#define TESTNET_H - -#include "networks/abstractnetwork.h" - -namespace Ark { -namespace Crypto { -namespace Networks { -/** - * @brief This is the testnet network class. - * - * @author Simon Downey - **/ -const AbstractNetwork Testnet = { - { - 0x17, // BASE58_ADDRESS_P2PKH - 0x00, // BASE58_ADDRESS_P2SH - 0xba // BASE58_WIF - }, - { - 70617039, // BIP32_PREFIX_XPUB - 70615956 // BIP32_PREFIX_XPRV - }, - "2017-03-21T13:00:00.000Z" // Epoch -}; -/**/ -}; // namespace Networks -}; // namespace Crypto -}; // namespace Ark - -#endif diff --git a/src/include/cpp-crypto/networks/testnet.hpp b/src/include/cpp-crypto/networks/testnet.hpp new file mode 100644 index 00000000..a83feb93 --- /dev/null +++ b/src/include/cpp-crypto/networks/testnet.hpp @@ -0,0 +1,23 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef NETWORKS_TESTNET_HPP +#define NETWORKS_TESTNET_HPP + +#include "networks/networks.hpp" + +// const Network Testnet { +// "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", // nethash +// 1, // slip44 +// 0xba, // wif +// 0x17, // version +// "2017-03-21T13:00:00.000Z" // epoch +// }; + +#endif diff --git a/src/include/cpp-crypto/transactions/builder.h b/src/include/cpp-crypto/transactions/builder.h index bf69dde0..5542d190 100644 --- a/src/include/cpp-crypto/transactions/builder.h +++ b/src/include/cpp-crypto/transactions/builder.h @@ -10,14 +10,19 @@ #ifndef BUILDER_H #define BUILDER_H +#include +#include +#include + #include "transactions/transaction.h" +#include "common/configuration.hpp" namespace Ark { namespace Crypto { namespace Transactions { - +/**/ class Builder { - public: +public: /** * Builder::buildTransfer() * @@ -25,26 +30,52 @@ class Builder { * If amount is not > 0, Builder will return an empty Transaction object and * validation will fail. **/ - static Transaction buildTransfer(std::string recipientId, uint64_t amount, std::string vendorField, - std::string passphrase, std::string secondPassphrase = ""); + static Transaction buildTransfer( + std::string recipient, + uint64_t amount, + std::string vendorField, + std::string passphrase, + std::string secondPassphrase = "", + const Configuration& configuration = {}); /**/ - static Transaction buildSecondSignatureRegistration(std::string passphrase, std::string secondPassphrase = ""); - static Transaction buildDelegateRegistration(std::string username, std::string passphrase, - std::string secondPassphrase = ""); - static Transaction buildVote(std::vector votes, std::string passphrase, - std::string secondPassphrase = ""); - static Transaction buildMultiSignatureRegistration(uint8_t min, uint8_t lifetime, std::vector keysgroup, - std::string passphrase, std::string secondPassphrase = ""); + static Transaction buildSecondSignatureRegistration( + std::string passphrase, + std::string secondPassphrase = "", + const Configuration& configuration = {}); + + static Transaction buildDelegateRegistration( + std::string username, + std::string passphrase, + std::string secondPassphrase = "", + const Configuration& configuration = {}); - private: + static Transaction buildVote( + std::vector votes, + std::string passphrase, + std::string secondPassphrase = "", + const Configuration& configuration = {}); + + static Transaction buildMultiSignatureRegistration( + uint8_t min, + uint8_t lifetime, + std::vector& keysgroup, + std::string passphrase, + std::string secondPassphrase = "", + const Configuration& configuration = {}); + +private: Builder(); - static Transaction sign(Transaction transaction, std::string passphrase, std::string secondPassphrase = ""); + static Transaction sign( + Transaction transaction, + std::string passphrase, + std::string secondPassphrase = "", + const Configuration& configuration = {}); Builder sign(const std::string& passphrase); - private: +private: void serializeVendorField(std::vector& bytes); void serializeType(std::vector& bytes); void serializeTransfer(std::vector& bytes); @@ -56,9 +87,9 @@ class Builder { Transaction _transaction; }; - -} // namespace Transactions -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Transactions +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/src/include/cpp-crypto/transactions/deserializer.h b/src/include/cpp-crypto/transactions/deserializer.h index 869b2f54..ccaf217d 100644 --- a/src/include/cpp-crypto/transactions/deserializer.h +++ b/src/include/cpp-crypto/transactions/deserializer.h @@ -10,22 +10,22 @@ #ifndef DESERIALIZER_H #define DESERIALIZER_H -#include "helpers/encoding/hex.h" -#include "helpers/crypto_helpers.h" -#include "identities/privatekey.h" -#include "identities/publickey.h" #include "transactions/transaction.h" +#include +#include +#include + namespace Ark { namespace Crypto { namespace Transactions { - +/**/ class Deserializer { - public: +public: Deserializer(const std::string& serialized); Transaction deserialize(); - private: +private: void deserializeHeader(Transaction& transaction); void deserializeType(Transaction& transaction); void deserializeTransfer(Transaction& transaction); @@ -44,9 +44,9 @@ class Deserializer { std::vector _binary; uint32_t _assetOffset; }; - -} // namespace Transactions -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Transactions +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/src/include/cpp-crypto/transactions/serializer.h b/src/include/cpp-crypto/transactions/serializer.h index e70c4282..b33994d5 100644 --- a/src/include/cpp-crypto/transactions/serializer.h +++ b/src/include/cpp-crypto/transactions/serializer.h @@ -12,16 +12,20 @@ #include "transactions/transaction.h" +#include +#include +#include + namespace Ark { namespace Crypto { namespace Transactions { - +/**/ class Serializer { - public: - Serializer(const Transaction& transaction); +public: + Serializer(Transaction transaction); std::string serialize(); - private: +private: void serializeVendorField(std::vector& bytes); void serializeType(std::vector& bytes); void serializeTransfer(std::vector& bytes); @@ -33,7 +37,7 @@ class Serializer { Transaction _transaction; }; - +/**/ } // namespace Transactions } // namespace Crypto } // namespace Ark diff --git a/src/include/cpp-crypto/transactions/transaction.h b/src/include/cpp-crypto/transactions/transaction.h index 1f1ef9b0..a7353435 100644 --- a/src/include/cpp-crypto/transactions/transaction.h +++ b/src/include/cpp-crypto/transactions/transaction.h @@ -10,8 +10,6 @@ #ifndef TRANSACTION_H #define TRANSACTION_H -#include "helpers/encoding/hex.h" -#include "helpers/crypto_helpers.h" #include "identities/privatekey.h" #include "identities/publickey.h" @@ -22,7 +20,7 @@ namespace Ark { namespace Crypto { namespace Transactions { - +/**/ struct TransactionAsset { struct { std::string publicKey; @@ -40,10 +38,10 @@ struct TransactionAsset { std::vector keysgroup; } multiSignature; }; - +/**/ class Transaction { public: - Transaction(); + Transaction() = default; std::string getId() const; @@ -65,7 +63,7 @@ class Transaction { uint32_t timelock_type = 0; std::vector signatures = {}; std::string id = ""; - std::string recipientId = ""; + std::string recipient = ""; std::string senderPublicKey = ""; std::string signature = ""; std::string secondSignature = ""; @@ -79,11 +77,14 @@ class Transaction { uint64_t timelock = 0; private: - bool internalVerify(std::string publicKey, std::vector bytes, std::string signature) const; + bool internalVerify( + std::string publicKey, + std::vector bytes, + std::string signature) const; }; - -} // namespace Transactions -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Transactions +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/src/managers/fee_manager.cpp b/src/managers/fee_manager.cpp new file mode 100644 index 00000000..8332014f --- /dev/null +++ b/src/managers/fee_manager.cpp @@ -0,0 +1,67 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "managers/fee_manager.hpp" + +#include + +namespace Ark { +namespace Crypto { +namespace managers { + +namespace { + static const uint64_t AMOUNT_ZERO = 0ULL; +} // namespace + +/**/ + +uint64_t FeeManager::getFee(uint8_t type) const { + std::size_t slot = type + 1; + return slot <= feePolicy_.size() + ? this->feePolicy_[type] + : AMOUNT_ZERO; +} + +/**/ + +void FeeManager::setFee(uint8_t type, uint64_t amount) { + std::size_t slot = type + 1; + if (slot > this->feePolicy_.size()) { + this->feePolicy_.resize(slot); + }; + this->feePolicy_[type] = amount; +} + +/**/ + +FeePolicy FeeManager::getPolicy() const { + return this->feePolicy_; +} + +/**/ + +void FeeManager::setPolicy(const FeePolicy& policy) { + this->feePolicy_ = policy; +} + +/**/ + +bool FeeManager::operator==(const FeeManager& rhs) const { + return this->getPolicy() == rhs.getPolicy(); +} + +/**/ + +bool FeeManager::operator!=(const FeeManager& rhs) const { + return this->getPolicy() != rhs.getPolicy(); +} + +} // namespace managers +} // namespace Crypto +} // namespace Ark diff --git a/src/managers/fee_manager.hpp b/src/managers/fee_manager.hpp new file mode 100644 index 00000000..05362937 --- /dev/null +++ b/src/managers/fee_manager.hpp @@ -0,0 +1,46 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef MANAGERS_FEE_MANAGER_HPP +#define MANAGERS_FEE_MANAGER_HPP + +#include "common/fee_policy.hpp" +#include "defaults/fee_policies.hpp" + +namespace Ark { +namespace Crypto { +namespace managers { +/**/ +class FeeManager { + private: + FeePolicy feePolicy_ = defaults::Fees::StaticFeePolicy(); + + public: + // Default initialization: using ARK StaticFees + FeeManager() = default; + virtual ~FeeManager() = default; + + // FeePolicy initialization: Custom FeePolicy + FeeManager(const FeePolicy& policy) : feePolicy_(policy) {} + + uint64_t getFee(uint8_t type) const; + void setFee(uint8_t type, uint64_t amount); + + FeePolicy getPolicy() const; + void setPolicy(const FeePolicy& policy); + + bool operator==(const FeeManager& rhs) const; + bool operator!=(const FeeManager& rhs) const; +}; +/**/ +} // namespace managers +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/managers/network_manager.cpp b/src/managers/network_manager.cpp new file mode 100644 index 00000000..723d91ed --- /dev/null +++ b/src/managers/network_manager.cpp @@ -0,0 +1,42 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "managers/network_manager.hpp" + +#include "common/network.hpp" + +namespace Ark { +namespace Crypto { +namespace managers { + +Network NetworkManager::getNetwork() const { + return this->network_; +} + +/**/ + +void NetworkManager::setNetwork(const Network& network) { + this->network_ = network; +} + +/**/ + +bool NetworkManager::operator==(const NetworkManager& rhs) const { + return this->getNetwork() == rhs.getNetwork(); +} + +/**/ + +bool NetworkManager::operator!=(const NetworkManager& rhs) const { + return this->getNetwork() != rhs.getNetwork(); +} + +} // namespace managers +} // namespace Crypto +} // namespace Ark diff --git a/src/managers/network_manager.hpp b/src/managers/network_manager.hpp new file mode 100644 index 00000000..ee5d2a5d --- /dev/null +++ b/src/managers/network_manager.hpp @@ -0,0 +1,43 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#ifndef MANAGERS_NETWORK_MANAGER_HPP +#define MANAGERS_NETWORK_MANAGER_HPP + +#include "common/network.hpp" +#include "networks/devnet.hpp" + +namespace Ark { +namespace Crypto { +namespace managers { +/**/ +class NetworkManager { + private: + Network network_ = Networks::Devnet(); + + public: + // Default initialization: using ARK Devnet + NetworkManager() = default; + virtual ~NetworkManager() = default; + + // Network initialization: Custom Network + NetworkManager(const Network& network) : network_(network) {} + + Network getNetwork() const; + void setNetwork(const Network& network); + + bool operator==(const NetworkManager& rhs) const; + bool operator!=(const NetworkManager& rhs) const; +}; +/**/ +} // namespace managers +} // namespace Crypto +} // namespace Ark + +#endif diff --git a/src/networks/abstractnetwork.cpp b/src/networks/abstractnetwork.cpp deleted file mode 100644 index d5499245..00000000 --- a/src/networks/abstractnetwork.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ - -#include "networks/abstractnetwork.h" - -/** - * @brief get the networks Base58 prefix byte given a prefix name - * - * @param Base58PrefixType prefix - * @return uint8_t - **/ -uint8_t Ark::Crypto::Networks::AbstractNetwork::getBase58Prefix(Base58PrefixType prefix) const { - switch (prefix) { - case 0: - return this->base58_.ADDRESS_P2PKH; - case 1: - return this->base58_.ADDRESS_P2SH; - case 2: - return this->base58_.WIF; - default: - return 0; - } -} -/**/ - -/** - * @brief sets the networks Base58 prefix given a prefix name and byte - * - * @param Base58PrefixType prefix - * @param uint8_t newByte - **/ -void Ark::Crypto::Networks::AbstractNetwork::setBase58Prefix(Base58PrefixType prefix, uint8_t newByte) { - if (!isLocked_) { - switch (prefix) { - case 0: - this->base58_.ADDRESS_P2PKH = newByte; - case 1: - this->base58_.ADDRESS_P2SH = newByte; - case 2: - this->base58_.WIF = newByte; - }; - } -} -/**/ - -/** - * @brief get the networks BIP32 prefix byte given a prefix name - * - * @param Base58PrefixType prefix - * @return long - **/ -long Ark::Crypto::Networks::AbstractNetwork::getBIP32Prefix(BIP32PrefixType prefix) const { - return (prefix == 0) ? this->bip32_.PREFIX_XPUB : this->bip32_.PREFIX_XPRV; -} -/**/ - -/** - * @brief sets the networks BIP32 prefix given a prefix name and byte - * - * @param BIP32PrefixType prefix - * @param long newByte - **/ -void Ark::Crypto::Networks::AbstractNetwork::setBIP32Prefix(BIP32PrefixType prefix, long newByte) { - if (!isLocked_) { - switch (prefix) { - case 0: - this->bip32_.PREFIX_XPUB = newByte; - break; - case 1: - this->bip32_.PREFIX_XPRV = newByte; - break; - }; - } -} -/**/ - -/** - * Get the network epoch. - * - * @return const char* - **/ -bool Ark::Crypto::Networks::AbstractNetwork::isLocked() const { - return this->isLocked_; -} -/**/ - -/** - * Get the network epoch. - * - * @return const char* - **/ -const char* Ark::Crypto::Networks::AbstractNetwork::epoch() const { - return this->epoch_; -} -/**/ - -/** - * Get the network version as number. - * - * @return int - **/ -uint8_t Ark::Crypto::Networks::AbstractNetwork::version() const { - return uint8_t(base58_.ADDRESS_P2PKH); -} -/**/ diff --git a/src/networks/devnet.cpp b/src/networks/devnet.cpp new file mode 100644 index 00000000..39e8e6df --- /dev/null +++ b/src/networks/devnet.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "networks/devnet.hpp" + +namespace Ark { +namespace Crypto { +/**/ +// Devnet +// Default ARK Development Network +const Network Networks::Devnet() { // NOLINT + return Network( + "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", // nethash + 1, // slip44 + 0xaa, // wif + 0x1e, // version + "2017-03-21T13:00:00.000Z" // epoch + ); +} +/**/ +} // namespace Crypto +} // namespace Ark diff --git a/src/networks/mainnet.cpp b/src/networks/mainnet.cpp new file mode 100644 index 00000000..ef3229e3 --- /dev/null +++ b/src/networks/mainnet.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "networks/mainnet.hpp" + +namespace Ark { +namespace Crypto { +/**/ +// Mainnet +// ARK Public Network +const Network Networks::Mainnet() { // NOLINT + return Network( + "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988", // nethash + 111, // slip44 + 0xaa, // wif + 0x17, // version + "2017-03-21T13:00:00.000Z" // epoch + ); +} +/**/ +} // namespace Crypto +} // namespace Ark diff --git a/src/networks/testnet.cpp b/src/networks/testnet.cpp new file mode 100644 index 00000000..1d2f99b1 --- /dev/null +++ b/src/networks/testnet.cpp @@ -0,0 +1,28 @@ +/** + * This file is part of Ark Cpp Crypto. + * + * (c) Ark Ecosystem + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + **/ + +#include "networks/testnet.hpp" + +namespace Ark { +namespace Crypto { +/**/ +// Testnet +// ARK Test Network +const Network Networks::Testnet() { // NOLINT + return Network( + "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", // nethash + 1, // slip44 + 0xba, // wif + 0x17, // version + "2017-03-21T13:00:00.000Z" // epoch + ); +} +/**/ +} // namespace Crypto +} // namespace Ark diff --git a/src/transactions/builder.cpp b/src/transactions/builder.cpp index f6775358..c0ef3748 100644 --- a/src/transactions/builder.cpp +++ b/src/transactions/builder.cpp @@ -1,86 +1,148 @@ + #include "transactions/builder.h" -#include "configuration/fee.h" -#include "configuration/network.h" -#include "enums/types.h" -#include "helpers/crypto_helpers.h" + +#include +#include +#include +#include + +#include "common/configuration.hpp" +#include "defaults/transaction_types.hpp" #include "identities/address.h" #include "utils/slot.h" +#include "helpers/crypto_helpers.h" namespace Ark { namespace Crypto { namespace Transactions { -Transaction Builder::buildTransfer(std::string recipientId, uint64_t amount, std::string vendorField, - std::string passphrase, std::string secondPassphrase) { +Transaction Builder::buildTransfer( + std::string recipient, + uint64_t amount, + std::string vendorField, + std::string passphrase, + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - if (amount < 1ull) { return transaction; }; + if (amount < 1ULL) { return transaction; } - transaction.type = Enums::Types::TRANSFER; - transaction.fee = Configuration::Fee().get(Enums::Types::TRANSFER); - transaction.recipientId = std::move(recipientId); - transaction.amount = std::move(amount); + transaction.type = defaults::TransactionTypes::Transfer; + transaction.fee = configuration.getFee(defaults::TransactionTypes::Transfer); + transaction.recipient = std::move(recipient); + transaction.amount = amount; transaction.vendorField = std::move(vendorField); - return sign(transaction, std::move(passphrase), std::move(secondPassphrase)); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildSecondSignatureRegistration(std::string passphrase, std::string secondPassphrase) { +/**/ + +Transaction Builder::buildSecondSignatureRegistration( + std::string passphrase, + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::SECOND_SIGNATURE_REGISTRATION; - transaction.fee = Configuration::Fee().get(Enums::Types::SECOND_SIGNATURE_REGISTRATION); + transaction.type = defaults::TransactionTypes::SecondSignatureRegistration; + transaction.fee = configuration.getFee( + defaults::TransactionTypes::SecondSignatureRegistration); - const auto publicKey = Identities::PublicKey::fromPassphrase(secondPassphrase.c_str()); + const auto publicKey = Identities::PublicKey::fromPassphrase( + secondPassphrase.c_str()); transaction.asset.signature.publicKey = publicKey.toString(); - return sign(transaction, std::move(passphrase), secondPassphrase); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildDelegateRegistration(std::string username, std::string passphrase, - std::string secondPassphrase) { +/**/ + +Transaction Builder::buildDelegateRegistration( + std::string username, + std::string passphrase, + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::DELEGATE_REGISTRATION; - transaction.fee = Configuration::Fee().get(Enums::Types::DELEGATE_REGISTRATION); + transaction.type = defaults::TransactionTypes::DelegateRegistration; + transaction.fee = configuration.getFee( + defaults::TransactionTypes::DelegateRegistration); transaction.asset.delegate.username = std::move(username); - return sign(transaction, std::move(passphrase), std::move(secondPassphrase)); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildVote(std::vector votes, std::string passphrase, std::string secondPassphrase) { +/**/ + +Transaction Builder::buildVote( + std::vector votes, + std::string passphrase, + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::VOTE; - transaction.fee = Configuration::Fee().get(Enums::Types::VOTE); + transaction.type = defaults::TransactionTypes::Vote; + transaction.fee = configuration.getFee(defaults::TransactionTypes::Vote); transaction.asset.votes = std::move(votes); - const auto recipient = - Identities::Address::fromPassphrase(passphrase.c_str(), Configuration::Network().get().version()); - transaction.recipientId = recipient.toString(); + const auto recipient = Identities::Address::fromPassphrase( + passphrase.c_str(), + configuration.getNetwork().version()); + transaction.recipient = recipient.toString(); - return sign(transaction, passphrase, std::move(secondPassphrase)); + return sign(transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::buildMultiSignatureRegistration(uint8_t min, uint8_t lifetime, std::vector keysgroup, - std::string passphrase, std::string secondPassphrase) { +/**/ + +Transaction Builder::buildMultiSignatureRegistration( + uint8_t min, + uint8_t lifetime, + std::vector& keysgroup, + std::string passphrase, + std::string secondPassphrase, + const Configuration& configuration) { Transaction transaction; - transaction.type = Enums::Types::MULTI_SIGNATURE_REGISTRATION; - transaction.fee = (keysgroup.size() + 1) * Configuration::Fee().get(Enums::Types::MULTI_SIGNATURE_REGISTRATION); + transaction.type = defaults::TransactionTypes::MultiSignatureRegistration; + transaction.fee = ( + keysgroup.size() + 1) + * configuration.getFee(defaults::TransactionTypes::MultiSignatureRegistration); transaction.asset.multiSignature.min = min; transaction.asset.multiSignature.lifetime = lifetime; transaction.asset.multiSignature.keysgroup = keysgroup; - const auto recipient = - Identities::Address::fromPassphrase(passphrase.c_str(), Configuration::Network().get().version()); - transaction.recipientId = recipient.toString(); + const auto recipient = Identities::Address::fromPassphrase( + passphrase.c_str(), + configuration.getNetwork().version()); + transaction.recipient = recipient.toString(); - return sign(transaction, passphrase, std::move(secondPassphrase)); + return sign( + transaction, + std::move(passphrase), + std::move(secondPassphrase)); } -Transaction Builder::sign(Transaction transaction, std::string passphrase, std::string secondPassphrase) { - transaction.timestamp = static_cast(Utils::Slot::time(Configuration::Network().get())); +/**/ + +Transaction Builder::sign( + Transaction transaction, + std::string passphrase, + std::string secondPassphrase, + const Configuration& configuration) { + transaction.timestamp = static_cast( + Utils::Slot::time(configuration.getNetwork())); transaction.sign(passphrase.c_str()); if (secondPassphrase.length() > 0) { transaction.secondSign(secondPassphrase.c_str()); - } + }; transaction.id = transaction.getId(); diff --git a/src/transactions/deserializer.cpp b/src/transactions/deserializer.cpp index 6a05c17d..aab2dff8 100644 --- a/src/transactions/deserializer.cpp +++ b/src/transactions/deserializer.cpp @@ -1,19 +1,31 @@ + #include "transactions/deserializer.h" -#include "bcl/Sha256.hpp" -#include "enums/types.h" -#include "helpers/crypto.h" -#include "identities/address.h" #include +#include #include #include +#include +#include + +#include "defaults/transaction_types.hpp" +#include "identities/address.h" +#include "identities/privatekey.h" +#include "identities/publickey.h" +#include "helpers/crypto.h" +#include "helpers/crypto_helpers.h" +#include "helpers/encoding/hex.h" + +#include "bcl/Sha256.hpp" namespace Ark { namespace Crypto { namespace Transactions { Deserializer::Deserializer(const std::string& serialized) - : _serialized(serialized), _binary(HexToBytes(serialized.c_str())), _assetOffset(0) {} + : _serialized(serialized), + _binary(HexToBytes(serialized.c_str())), + _assetOffset(0) {} Transaction Deserializer::deserialize() { Transaction transaction; @@ -24,20 +36,24 @@ Transaction Deserializer::deserialize() { if (transaction.version == 1) { handleVersionOne(transaction); - } + }; return transaction; } +/**/ + void Deserializer::deserializeHeader(Transaction& transaction) { - unpack(&transaction.header, &this->_binary[0]); // 1 Byte - unpack(&transaction.version, &this->_binary[1]); // 1 Byte - unpack(&transaction.network, &this->_binary[2]); // 1 Byte - unpack(&transaction.type, &this->_binary[3]); // 1 Byte - unpack(&transaction.timestamp, &this->_binary[4]); // 4 Byte + unpack(&transaction.header, &this->_binary[0]); // 1 Byte + unpack(&transaction.version, &this->_binary[1]); // 1 Byte + unpack(&transaction.network, &this->_binary[2]); // 1 Byte + unpack(&transaction.type, &this->_binary[3]); // 1 Byte + unpack(&transaction.timestamp, &this->_binary[4]); // 4 Byte // 33 Byte - transaction.senderPublicKey = BytesToHex(this->_binary.begin() + 8, this->_binary.begin() + 33 + 8); + transaction.senderPublicKey = BytesToHex( + this->_binary.begin() + 8, + this->_binary.begin() + 33 + 8); unpack(&transaction.fee, &this->_binary[41]); // 8 Byte @@ -45,89 +61,103 @@ void Deserializer::deserializeHeader(Transaction& transaction) { uint8_t vendorFieldLength = 0; unpack(&vendorFieldLength, &this->_binary[49]); // 1 Byte if (vendorFieldLength > 0) { - transaction.vendorFieldHex = this->_serialized.substr(vendorFieldOffset, vendorFieldLength * 2); - } + transaction.vendorFieldHex = this->_serialized.substr( + vendorFieldOffset, + vendorFieldLength * 2); + }; _assetOffset = vendorFieldOffset + vendorFieldLength * 2; } -void Deserializer::deserializeType(Transaction& transaction) { +/**/ + +void Deserializer::deserializeType( + Transaction& transaction) { switch (transaction.type) { - case Enums::Types::TRANSFER: { + case defaults::TransactionTypes::Transfer: { deserializeTransfer(transaction); break; - } - case Enums::Types::SECOND_SIGNATURE_REGISTRATION: { + }; + case defaults::TransactionTypes::SecondSignatureRegistration: { deserializeSecondSignatureRegistration(transaction); break; - } - case Enums::Types::DELEGATE_REGISTRATION: { + }; + case defaults::TransactionTypes::DelegateRegistration: { deserializeDelegateRegistration(transaction); break; - } - case Enums::Types::VOTE: { + }; + case defaults::TransactionTypes::Vote: { deserializeVote(transaction); break; - } - case Enums::Types::MULTI_SIGNATURE_REGISTRATION: { + }; + case defaults::TransactionTypes::MultiSignatureRegistration: { deserializeMultiSignatureRegistration(transaction); break; - } - case Enums::Types::IPFS: { - break; - } - case Enums::Types::TIMELOCK_TRANSFER: { - break; - } - case Enums::Types::MULTI_PAYMENT: { - break; - } - case Enums::Types::DELEGATE_RESIGNATION: { - break; - } - } + }; + case defaults::TransactionTypes::Ipfs: { break; }; + case defaults::TransactionTypes::TimelockTransfer: { break; }; + case defaults::TransactionTypes::MultiPayment: { break; }; + case defaults::TransactionTypes::DelegateResignation: { break; }; + }; } -void Deserializer::deserializeTransfer(Transaction& transaction) { +/**/ + +void Deserializer::deserializeTransfer( + Transaction& transaction) { unpack(&transaction.amount, &this->_binary[_assetOffset / 2]); unpack(&transaction.expiration, &this->_binary[_assetOffset / 2 + 8]); - transaction.recipientId = Identities::Address::base58encode(&this->_binary[(_assetOffset / 2) + 12]); + transaction.recipient = Identities::Address::base58encode( + &this->_binary[(_assetOffset / 2) + 12]); _assetOffset += (8 + 4 + 21) * 2; -} +}; -void Deserializer::deserializeSecondSignatureRegistration(Transaction& transaction) { - transaction.asset.signature.publicKey = this->_serialized.substr(_assetOffset, 66); +void Deserializer::deserializeSecondSignatureRegistration( + Transaction& transaction) { + transaction.asset.signature.publicKey = this->_serialized.substr( + _assetOffset, + 66); _assetOffset += 66; -} +}; -void Deserializer::deserializeDelegateRegistration(Transaction& transaction) { +void Deserializer::deserializeDelegateRegistration( + Transaction& transaction) { uint8_t usernameLength = 0; unpack(&usernameLength, &this->_binary[_assetOffset / 2]); usernameLength &= 0xff; - std::string username = this->_serialized.substr((_assetOffset / 2 + 1) * 2, usernameLength * 2); - std::vector bytes = HexToBytes(username.c_str()); - transaction.asset.delegate.username = std::string(bytes.begin(), bytes.end()); + std::string username = this->_serialized.substr( + (_assetOffset / 2 + 1) * 2, usernameLength * 2); + std::vector bytes = HexToBytes(username.c_str()); + transaction.asset.delegate.username = std::string( + bytes.begin(), + bytes.end()); _assetOffset += (usernameLength + 1) * 2; -} +}; -void Deserializer::deserializeVote(Transaction& transaction) { +void Deserializer::deserializeVote( + Transaction& transaction) { uint8_t voteLength = 0; unpack(&voteLength, &this->_binary[_assetOffset / 2]); voteLength &= 0xff; for (uint8_t i = 0; i < voteLength; i++) { - std::string vote = this->_serialized.substr(_assetOffset + 2 + i * 2 * 32, 68); + std::string vote = this->_serialized.substr( + _assetOffset + 2 + i * 2 * 32, + 68); vote = (vote[1] == '1' ? "+" : "-") + vote.substr(2); transaction.asset.votes.push_back(vote); - } + }; _assetOffset += 2 + voteLength * 34 * 2; } -void Deserializer::deserializeMultiSignatureRegistration(Transaction& transaction) { +/**/ + +void Deserializer::deserializeMultiSignatureRegistration( + Transaction& transaction) { uint8_t min = 0; unpack(&min, &this->_binary[_assetOffset / 2]); min &= 0xff; @@ -144,85 +174,114 @@ void Deserializer::deserializeMultiSignatureRegistration(Transaction& transactio transaction.asset.multiSignature.lifetime = lifetime; for (uint8_t i = 0; i < count; i++) { - std::string key = this->_serialized.substr(_assetOffset + 6 + i * 66, 66); + std::string key = this->_serialized.substr( + _assetOffset + 6 + i * 66, + 66); transaction.asset.multiSignature.keysgroup.push_back(key); - } + }; _assetOffset += 6 + count * 66; } +/**/ + static uint8_t parseSignatureLength(const std::string& hex) { - assert(hex.length() <= 2); + if (hex.length() > 2) { return 0; }; unsigned int length; sscanf(hex.c_str(), "%x", &length); return static_cast(length + 2); } -void Deserializer::deserializeSignatures(Transaction& transaction) { +/**/ + +void Deserializer::deserializeSignatures( + Transaction& transaction) { std::string signature = this->_serialized.substr(_assetOffset); size_t multiSignatureOffset = 0; if (!signature.empty()) { size_t signatureLength = parseSignatureLength(signature.substr(2, 2)); - transaction.signature = this->_serialized.substr(_assetOffset, signatureLength * 2); + transaction.signature = this->_serialized.substr( + _assetOffset, + signatureLength * 2); multiSignatureOffset += signatureLength * 2; - transaction.secondSignature = this->_serialized.substr((_assetOffset + signatureLength * 2)); + transaction.secondSignature = this->_serialized.substr( + (_assetOffset + signatureLength * 2)); if (!transaction.secondSignature.empty()) { if (transaction.secondSignature.substr(0, 2) == "ff") { transaction.secondSignature = ""; } else { - size_t secondSignatureLength = parseSignatureLength(transaction.secondSignature.substr(2, 2)); - transaction.secondSignature = transaction.secondSignature.substr(0, secondSignatureLength * 2); + size_t secondSignatureLength = parseSignatureLength( + transaction.secondSignature.substr(2, 2)); + transaction.secondSignature = transaction.secondSignature.substr( + 0, + secondSignatureLength * 2); multiSignatureOffset += secondSignatureLength * 2; - } - } + }; + }; - std::string signatures = this->_serialized.substr(_assetOffset + multiSignatureOffset); + std::string signatures = this->_serialized.substr( + _assetOffset + multiSignatureOffset); if (!signatures.empty() && signatures.substr(0, 2) == "ff") { signatures = signatures.substr(2); while (!signatures.empty()) { - size_t multiSignatureLength = parseSignatureLength(signatures.substr(2, 2)); + size_t multiSignatureLength = parseSignatureLength( + signatures.substr(2, 2)); if (multiSignatureLength > 0) { - transaction.signatures.push_back(signatures.substr(0, multiSignatureLength * 2)); - } + transaction.signatures.push_back( + signatures.substr(0, + multiSignatureLength * 2)); + }; signatures = signatures.substr(multiSignatureLength * 2); - } - } - } + }; + }; + }; } -void Deserializer::handleVersionOne(Transaction& transaction) { - transaction.signSignature = transaction.secondSignature; +/**/ - if (transaction.type == Enums::Types::VOTE) { - const auto publicKey = Identities::PublicKey::fromHex(transaction.senderPublicKey.c_str()); - const auto address = Identities::Address::fromPublicKey(publicKey, transaction.network); - transaction.recipientId = address.toString(); - } +void Deserializer::handleVersionOne( + Transaction& transaction) { + transaction.signSignature = transaction.secondSignature; - if (transaction.type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { - std::for_each(transaction.asset.multiSignature.keysgroup.begin(), transaction.asset.multiSignature.keysgroup.end(), - [](std::string& key) { key.insert(0, "+"); }); - } + if (transaction.type == defaults::TransactionTypes::Vote) { + const auto publicKey = Identities::PublicKey::fromHex( + transaction.senderPublicKey.c_str()); + const auto address = Identities::Address::fromPublicKey( + publicKey, + transaction.network); + transaction.recipient = address.toString(); + }; + + if (transaction.type == defaults::TransactionTypes::MultiSignatureRegistration) { + std::for_each( + transaction.asset.multiSignature.keysgroup.begin(), + transaction.asset.multiSignature.keysgroup.end(), + [](std::string& key) { key.insert(0, "+"); } + ); + }; if (!transaction.vendorFieldHex.empty()) { const auto bytes = HexToBytes(transaction.vendorFieldHex.c_str()); transaction.vendorField = std::string(bytes.begin(), bytes.end()); - } + }; if (transaction.id.empty()) { transaction.id = transaction.getId(); - } - - if (transaction.type == Enums::Types::SECOND_SIGNATURE_REGISTRATION || - transaction.type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { - const auto publicKey = Identities::PublicKey::fromHex(transaction.senderPublicKey.c_str()); - const auto address = Identities::Address::fromPublicKey(publicKey, transaction.network); - transaction.recipientId = address.toString(); - } + }; + + if (transaction.type == defaults::TransactionTypes::SecondSignatureRegistration + || transaction.type == defaults::TransactionTypes::MultiSignatureRegistration) { + const auto publicKey = Identities::PublicKey::fromHex( + transaction.senderPublicKey.c_str()); + const auto address = Identities::Address::fromPublicKey( + publicKey, + transaction.network); + transaction.recipient = address.toString(); + }; } } // namespace Transactions diff --git a/src/transactions/serializer.cpp b/src/transactions/serializer.cpp index e3e4b519..04c97c3e 100644 --- a/src/transactions/serializer.cpp +++ b/src/transactions/serializer.cpp @@ -1,27 +1,45 @@ + #include "transactions/serializer.h" -#include "configuration/network.h" -#include "enums/types.h" -#include "helpers/crypto_helpers.h" + +#include +#include +#include + +#include "common/configuration.hpp" +#include "defaults/transaction_types.hpp" #include "identities/address.h" +#include "helpers/crypto_helpers.h" +#include "helpers/encoding/hex.h" namespace Ark { namespace Crypto { namespace Transactions { // TODO: remove class ? -Serializer::Serializer(const Transaction& transaction) : _transaction(transaction) {} +Serializer::Serializer(Transaction transaction) + : _transaction(std::move(transaction)) {} std::string Serializer::serialize() { std::vector bytes; bytes.push_back(0xff); - bytes.push_back(_transaction.version > 0 ? _transaction.version : 0x01); - bytes.push_back(_transaction.network > 0 ? _transaction.network : Configuration::Network().get().version()); + bytes.push_back( + _transaction.version > 0 + ? _transaction.version + : 0x01); + bytes.push_back( + _transaction.network > 0 + ? _transaction.network + : Configuration().getNetwork().version()); bytes.push_back(_transaction.type); pack(bytes, _transaction.timestamp); - std::vector senderPublicKeyBytes = HexToBytes(_transaction.senderPublicKey.c_str()); - bytes.insert(bytes.end(), senderPublicKeyBytes.begin(), senderPublicKeyBytes.end()); + std::vector senderPublicKeyBytes = HexToBytes( + _transaction.senderPublicKey.c_str()); + bytes.insert( + bytes.end(), + senderPublicKeyBytes.begin(), + senderPublicKeyBytes.end()); pack(bytes, _transaction.fee); @@ -32,129 +50,186 @@ std::string Serializer::serialize() { return BytesToHex(bytes); } -void Serializer::serializeVendorField(std::vector& bytes) { +/**/ + +void Serializer::serializeVendorField( + std::vector& bytes) { if (_transaction.vendorField.length() > 0) { - auto vendorFieldLength = static_cast(_transaction.vendorField.length()); + auto vendorFieldLength = static_cast( + _transaction.vendorField.length()); bytes.push_back(vendorFieldLength); - bytes.insert(bytes.end(), std::begin(_transaction.vendorField), std::end(_transaction.vendorField)); - + bytes.insert( + bytes.end(), + std::begin(_transaction.vendorField), + std::end(_transaction.vendorField)); } else if (_transaction.vendorFieldHex.length() > 0) { - auto vendorFieldHexLength = static_cast(_transaction.vendorFieldHex.length() / 2); + auto vendorFieldHexLength = static_cast( + _transaction.vendorFieldHex.length() / 2); bytes.push_back(vendorFieldHexLength); - bytes.insert(bytes.end(), std::begin(_transaction.vendorFieldHex), std::end(_transaction.vendorFieldHex)); + bytes.insert( + bytes.end(), + std::begin(_transaction.vendorFieldHex), + std::end(_transaction.vendorFieldHex)); } else { bytes.push_back(0x00); - } + }; } -void Serializer::serializeType(std::vector& bytes) { +/**/ + +void Serializer::serializeType( + std::vector& bytes) { switch (_transaction.type) { - case Enums::Types::TRANSFER: { + case defaults::TransactionTypes::Transfer: { serializeTransfer(bytes); break; - } - case Enums::Types::SECOND_SIGNATURE_REGISTRATION: { + }; + case defaults::TransactionTypes::SecondSignatureRegistration: { serializeSecondSignatureRegistration(bytes); break; - } - case Enums::Types::DELEGATE_REGISTRATION: { + }; + case defaults::TransactionTypes::DelegateRegistration: { serializeDelegateRegistration(bytes); break; - } - case Enums::Types::VOTE: { + }; + case defaults::TransactionTypes::Vote: { serializeVote(bytes); break; - } - case Enums::Types::MULTI_SIGNATURE_REGISTRATION: { + }; + case defaults::TransactionTypes::MultiSignatureRegistration: { serializeMultiSignatureRegistration(bytes); break; - } - case Enums::Types::IPFS: { - break; - } - case Enums::Types::TIMELOCK_TRANSFER: { - break; - } - case Enums::Types::MULTI_PAYMENT: { - break; - } - case Enums::Types::DELEGATE_RESIGNATION: { - break; - } - } + }; + case defaults::TransactionTypes::Ipfs: { break; }; + case defaults::TransactionTypes::TimelockTransfer: { break; }; + case defaults::TransactionTypes::MultiPayment: { break; }; + case defaults::TransactionTypes::DelegateResignation: { break; }; + }; } -void Serializer::serializeTransfer(std::vector& bytes) { +/**/ + +void Serializer::serializeTransfer( + std::vector& bytes) { pack(bytes, _transaction.amount); pack(bytes, _transaction.expiration); - std::vector recipientIdBytes = Identities::Address::bytesFromBase58Check(_transaction.recipientId.c_str()); - bytes.insert(bytes.end(), recipientIdBytes.begin(), recipientIdBytes.end()); + std::vector recipientBytes = Identities::Address::bytesFromBase58Check( + _transaction.recipient.c_str()); + bytes.insert( + bytes.end(), + recipientBytes.begin(), + recipientBytes.end()); } -void Serializer::serializeSecondSignatureRegistration(std::vector& bytes) { - std::vector publicKeyBytes = HexToBytes(_transaction.asset.signature.publicKey.c_str()); - bytes.insert(bytes.end(), publicKeyBytes.begin(), publicKeyBytes.end()); +/**/ + +void Serializer::serializeSecondSignatureRegistration( + std::vector& bytes) { + std::vector publicKeyBytes = HexToBytes( + _transaction.asset.signature.publicKey.c_str()); + bytes.insert( + bytes.end(), + publicKeyBytes.begin(), + publicKeyBytes.end()); } -void Serializer::serializeDelegateRegistration(std::vector& bytes) { +/**/ + +void Serializer::serializeDelegateRegistration( + std::vector& bytes) { const auto username = _transaction.asset.delegate.username; bytes.push_back(static_cast(username.size())); - bytes.insert(bytes.end(), username.begin(), username.end()); + bytes.insert( + bytes.end(), + username.begin(), + username.end()); } -void Serializer::serializeVote(std::vector& bytes) { +/**/ + +void Serializer::serializeVote( + std::vector& bytes) { std::string votes; for (const auto& vote : _transaction.asset.votes) { votes += (vote[0] == '+' ? "01" : "00") + vote.substr(1); - } + }; std::vector voteBytes = HexToBytes(votes.c_str()); - bytes.push_back(static_cast(_transaction.asset.votes.size())); - bytes.insert(bytes.end(), voteBytes.begin(), voteBytes.end()); + bytes.push_back(static_cast( + _transaction.asset.votes.size())); + bytes.insert( + bytes.end(), + voteBytes.begin(), + voteBytes.end()); } -void Serializer::serializeMultiSignatureRegistration(std::vector& bytes) { +/**/ + +void Serializer::serializeMultiSignatureRegistration( + std::vector& bytes) { std::string keysgroup; if (_transaction.version == 1) { for (const auto& kg : _transaction.asset.multiSignature.keysgroup) { keysgroup += kg.substr(1); - } + }; } else { keysgroup = join(_transaction.asset.multiSignature.keysgroup); - } + }; bytes.push_back(_transaction.asset.multiSignature.min); - bytes.push_back(static_cast(_transaction.asset.multiSignature.keysgroup.size())); + bytes.push_back(static_cast( + _transaction.asset.multiSignature.keysgroup.size())); bytes.push_back(_transaction.asset.multiSignature.lifetime); std::vector keysgroupBytes = HexToBytes(keysgroup.c_str()); - bytes.insert(bytes.end(), keysgroupBytes.begin(), keysgroupBytes.end()); + bytes.insert( + bytes.end(), + keysgroupBytes.begin(), + keysgroupBytes.end()); } -void Serializer::serializeSignatures(std::vector& bytes) { +/**/ + +void Serializer::serializeSignatures( + std::vector& bytes) { if (_transaction.signature.length() > 0) { - std::vector signatureBytes = HexToBytes(_transaction.signature.c_str()); - bytes.insert(bytes.end(), signatureBytes.begin(), signatureBytes.end()); - } + std::vector signatureBytes = HexToBytes( + _transaction.signature.c_str()); + bytes.insert( + bytes.end(), + signatureBytes.begin(), + signatureBytes.end()); + }; if (_transaction.secondSignature.length() > 0) { - std::vector secondSignatureBytes = HexToBytes(_transaction.secondSignature.c_str()); - bytes.insert(bytes.end(), secondSignatureBytes.begin(), secondSignatureBytes.end()); + std::vector secondSignatureBytes = HexToBytes( + _transaction.secondSignature.c_str()); + bytes.insert( + bytes.end(), + secondSignatureBytes.begin(), + secondSignatureBytes.end()); } else if (_transaction.signSignature.length() > 0) { - std::vector signSignatureBytes = HexToBytes(_transaction.signSignature.c_str()); - bytes.insert(bytes.end(), signSignatureBytes.begin(), signSignatureBytes.end()); - } + std::vector signSignatureBytes = HexToBytes( + _transaction.signSignature.c_str()); + bytes.insert( + bytes.end(), + signSignatureBytes.begin(), + signSignatureBytes.end()); + }; if (!_transaction.signatures.empty()) { bytes.push_back(0xff); std::string joined = join(_transaction.signatures); for (const auto& signature : _transaction.signatures) { std::vector signatureBytes = HexToBytes(signature.c_str()); - bytes.insert(bytes.end(), std::begin(signatureBytes), std::end(signatureBytes)); - } - } + bytes.insert( + bytes.end(), + std::begin(signatureBytes), + std::end(signatureBytes)); + }; + }; } } // namespace Transactions diff --git a/src/transactions/transaction.cpp b/src/transactions/transaction.cpp index 5c8fe64e..3399b3c7 100644 --- a/src/transactions/transaction.cpp +++ b/src/transactions/transaction.cpp @@ -1,28 +1,37 @@ + #include "transactions/transaction.h" -#include "bcl/Sha256.hpp" -#include "enums/types.h" + +#include +#include +#include +#include + +#include "defaults/transaction_types.hpp" +#include "identities/address.h" +#include "identities/privatekey.h" #include "helpers/crypto.h" #include "helpers/crypto_helpers.h" +#include "helpers/encoding/hex.h" #include "helpers/json.h" -#include "identities/address.h" -#include "identities/privatekey.h" -#include +#include "bcl/Sha256.hpp" using namespace Ark::Crypto::Identities; -Ark::Crypto::Transactions::Transaction::Transaction() {} - std::string Ark::Crypto::Transactions::Transaction::getId() const { auto bytes = this->toBytes(false, false); const auto shaHash = Sha256::getHash(&bytes[0], bytes.size()); - memcpy(&bytes[0], shaHash.value, shaHash.HASH_LEN); - return BytesToHex(&bytes[0], &bytes[0] + shaHash.HASH_LEN); + memcpy(&bytes[0], shaHash.value, Sha256Hash::HASH_LEN); + return BytesToHex(&bytes[0], &bytes[0] + Sha256Hash::HASH_LEN); } -std::string Ark::Crypto::Transactions::Transaction::sign(const char* passphrase) { +/**/ + +std::string Ark::Crypto::Transactions::Transaction::sign( + const char* passphrase) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); - this->senderPublicKey = Identities::PublicKey::fromPrivateKey(privateKey).toString(); + this->senderPublicKey = Identities::PublicKey::fromPrivateKey( + privateKey).toString(); const auto bytes = this->toBytes(); const auto hash = Sha256::getHash(&bytes[0], bytes.size()); @@ -34,7 +43,10 @@ std::string Ark::Crypto::Transactions::Transaction::sign(const char* passphrase) return this->signature; } -std::string Ark::Crypto::Transactions::Transaction::secondSign(const char* passphrase) { +/**/ + +std::string Ark::Crypto::Transactions::Transaction::secondSign( + const char* passphrase) { PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); const auto bytes = this->toBytes(false); const auto hash = Sha256::getHash(&bytes[0], bytes.size()); @@ -46,14 +58,28 @@ std::string Ark::Crypto::Transactions::Transaction::secondSign(const char* passp return this->secondSignature; } +/**/ + bool Ark::Crypto::Transactions::Transaction::verify() const { - return this->internalVerify(this->senderPublicKey, this->toBytes(), this->signature); + return this->internalVerify( + this->senderPublicKey, + this->toBytes(), + this->signature); } -bool Ark::Crypto::Transactions::Transaction::secondVerify(const char* secondPublicKey) const { - return this->internalVerify(secondPublicKey, this->toBytes(false), this->secondSignature); +/**/ + +bool Ark::Crypto::Transactions::Transaction::secondVerify( + const char* secondPublicKey) const { + std::string secondPublicKeyString = secondPublicKey; + return this->internalVerify( + secondPublicKeyString, + this->toBytes(false), + this->secondSignature); } +/**/ + bool Ark::Crypto::Transactions::Transaction::internalVerify( std::string publicKey, std::vector bytes, @@ -63,120 +89,172 @@ bool Ark::Crypto::Transactions::Transaction::internalVerify( const auto hash = Sha256::getHash(&bytes[0], bytes.size()); const auto key = Identities::PublicKey::fromHex(publicKey.c_str()); auto signatureBytes = HexToBytes(signature.c_str()); + return cryptoVerify(key, hash, signatureBytes); } +/**/ + std::vector Ark::Crypto::Transactions::Transaction::toBytes( bool skipSignature, bool skipSecondSignature) const { std::vector bytes; - if (this->type == 0 && amount < 1ull) { return bytes; }; + if (this->type == 0 && amount < 1ULL) { return bytes; }; pack(bytes, this->type); pack(bytes, this->timestamp); - const auto senderKeyBytes = HexToBytes(this->senderPublicKey.c_str()); - bytes.insert(std::end(bytes), std::begin(senderKeyBytes), std::end(senderKeyBytes)); - - const auto skipRecipientId = type - == Enums::Types::SECOND_SIGNATURE_REGISTRATION - || type == Enums::Types::MULTI_SIGNATURE_REGISTRATION; - - if (!this->recipientId.empty() && !skipRecipientId) { - std::vector recipientIdBytes = Address::bytesFromBase58Check(this->recipientId.c_str()); - bytes.insert(std::end(bytes), std::begin(recipientIdBytes), std::end(recipientIdBytes)); + const auto senderKeyBytes = HexToBytes( + this->senderPublicKey.c_str()); + bytes.insert( + std::end(bytes), + std::begin(senderKeyBytes), + std::end(senderKeyBytes)); + + const auto skiprecipient = + type == defaults::TransactionTypes::SecondSignatureRegistration + || type ==defaults::TransactionTypes::MultiSignatureRegistration; + + if (!this->recipient.empty() && !skiprecipient) { + std::vector recipientBytes = Address::bytesFromBase58Check( + this->recipient.c_str()); + bytes.insert( + std::end(bytes), + std::begin(recipientBytes), + std::end(recipientBytes)); } else { std::vector filler(21, 0); - bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); - } + bytes.insert( + std::end(bytes), + std::begin(filler), + std::end(filler)); + }; if (!this->vendorField.empty() && vendorField.length() <= 255) { - bytes.insert(std::end(bytes), std::begin(this->vendorField), std::end(this->vendorField)); - + bytes.insert( + std::end(bytes), + std::begin(this->vendorField), + std::end(this->vendorField)); size_t diff = 64 - vendorField.length(); if (diff > 0) { std::vector filler(diff, 0); - bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); - } + bytes.insert( + std::end(bytes), + std::begin(filler), + std::end(filler)); + }; } else { std::vector filler(64, 0); - bytes.insert(std::end(bytes), std::begin(filler), std::end(filler)); - } + bytes.insert( + std::end(bytes), + std::begin(filler), + std::end(filler)); + }; pack(bytes, this->amount); pack(bytes, this->fee); - if (type == Enums::Types::SECOND_SIGNATURE_REGISTRATION) { - const auto publicKeyBytes = HexToBytes(this->asset.signature.publicKey.c_str()); - bytes.insert(std::end(bytes), std::begin(publicKeyBytes), std::end(publicKeyBytes)); - - } else if (type == Enums::Types::DELEGATE_REGISTRATION) { - bytes.insert(std::end(bytes), std::begin(this->asset.delegate.username), std::end(this->asset.delegate.username)); - - } else if (type == Enums::Types::VOTE) { + if (type == defaults::TransactionTypes::SecondSignatureRegistration) { + // SECOND_SIGNATURE_REGISTRATION + const auto publicKeyBytes = HexToBytes( + this->asset.signature.publicKey.c_str()); + bytes.insert( + std::end(bytes), + std::begin(publicKeyBytes), + std::end(publicKeyBytes)); + } else if (type == defaults::TransactionTypes::DelegateRegistration) { + // DELEGATE_REGISTRATION + bytes.insert( + std::end(bytes), + std::begin(this->asset.delegate.username), + std::end(this->asset.delegate.username)); + } else if (type == defaults::TransactionTypes::Vote) { + // VOTE const auto joined = join(this->asset.votes); - bytes.insert(std::end(bytes), std::begin(joined), std::end(joined)); - - } else if (type == Enums::Types::MULTI_SIGNATURE_REGISTRATION) { + bytes.insert( + std::end(bytes), + std::begin(joined), + std::end(joined)); + } else if (type == defaults::TransactionTypes::MultiSignatureRegistration) { + // MULTI_SIGNATURE_REGISTRATION pack(bytes, this->asset.multiSignature.min); pack(bytes, this->asset.multiSignature.lifetime); const auto joined = join(this->asset.multiSignature.keysgroup); - bytes.insert(std::end(bytes), std::begin(joined), std::end(joined)); - } + bytes.insert( + std::end(bytes), + std::begin(joined), + std::end(joined)); + }; if (!skipSignature && !this->signature.empty()) { const auto signatureBytes = HexToBytes(this->signature.c_str()); - bytes.insert(std::end(bytes), std::begin(signatureBytes), std::end(signatureBytes)); - } + bytes.insert( + std::end(bytes), + std::begin(signatureBytes), + std::end(signatureBytes)); + }; if (!skipSecondSignature && !this->secondSignature.empty()) { - const auto secondSignatureBytes = HexToBytes(this->secondSignature.c_str()); - bytes.insert(std::end(bytes), std::begin(secondSignatureBytes), std::end(secondSignatureBytes)); - } + const auto secondSignatureBytes = HexToBytes( + this->secondSignature.c_str()); + bytes.insert( + std::end(bytes), + std::begin(secondSignatureBytes), + std::end(secondSignatureBytes)); + }; return bytes; } +/**/ + std::map Ark::Crypto::Transactions::Transaction::toArray() { // buffers for variable and non-string type-values. - char amount[24], - assetName[16], - assetValue[512], - fee[24], - network[8], - signatures[512], - timestamp[36], - type[8], - version[8]; + char amount[24]; + char assetName[16]; + char assetValue[512]; + char fee[24]; + char network[8]; + char signatures[512]; + char timestamp[36]; + char type[8]; + char version[8]; // Amount - sprintf(amount, "%llu", this->amount); + snprintf(amount, sizeof(amount), "%" PRIu64, this->amount); // Asset - if (this->type == 0) { // Transfer - //do nothing - } else if (this->type == 1) { // Second Signature Registration - - strcpy(assetName, "publicKey"); - strcpy(assetValue, this->asset.signature.publicKey.c_str()); - - } else if (this->type == 2) { // Delegate Registration - - strcpy(assetName, "username"); - strcpy(assetValue, this->asset.delegate.username.c_str()); - - } else if (this->type == 3) { // Vote - - strcpy(assetName, "votes"); - strcpy(assetValue, ""); + if (this->type == 0) { + // Transfer + // do nothing + } else if (this->type == 1) { + // Second Signature Registration + strncpy(assetName, "publicKey", sizeof(assetName)); + strncpy( + assetValue, + this->asset.signature.publicKey.c_str(), + this->asset.signature.publicKey.length() + 1); + } else if (this->type == 2) { + // Delegate Registration + strncpy(assetName, "username", sizeof(assetName)); + strncpy( + assetValue, + this->asset.delegate.username.c_str(), + this->asset.delegate.username.length() + 1); + } else if (this->type == 3) { + // Vote + strncpy(assetName, "votes", sizeof(assetName)); + strncpy(assetValue, "", 1); for (unsigned int i = 0; i < this->asset.votes.size(); ++i) { - strcat(assetValue, this->asset.votes[i].c_str()); - + strncat( + assetValue, + this->asset.votes[i].c_str(), + this->asset.votes[i].length() + 1); if (i < this->asset.votes.size() - 1) { - strcat(assetValue, ","); - } - } + strncat(assetValue, ",", 1); + }; + }; // } else if (this->type == 4) { // Multisignature Registration // // TODO @@ -191,29 +269,31 @@ std::map Ark::Crypto::Transactions::Transaction::toArr }; // Fee - // fee << this->fee; - sprintf(fee, "%llu", this->fee); + snprintf(fee, sizeof(fee), "%" PRIu64, this->fee); // Signatures strcpy(signatures, ""); for (unsigned int i = 0; i < this->signatures.size(); ++i) { - strcat(signatures, this->signatures[i].c_str()); + strncat( + signatures, + this->signatures[i].c_str(), + this->signatures[i].length() + 1); if (i < this->signatures.size() - 1) { - strcpy(signatures, ","); - } - } + strncpy(signatures, ",", 1); + }; + }; // Network - sprintf(network, "%d", this->network); + snprintf(network, sizeof(network), "%d", this->network); // Timestamp - sprintf(timestamp, "%d", this->timestamp); + snprintf(timestamp, sizeof(timestamp), "%d", this->timestamp); // Type - sprintf(type, "%d", this->type); + snprintf(type, sizeof(type), "%u", this->type); // Version - sprintf(version, "%d", this->version); + snprintf(version, sizeof(version), "%d", this->version); return { { "amount", amount }, @@ -221,7 +301,7 @@ std::map Ark::Crypto::Transactions::Transaction::toArr { "fee", fee }, { "id", this->id }, { "network", network }, - { "recipientId", this->recipientId }, + { "recipient", this->recipient }, { "secondSignature", this->secondSignature }, { "senderPublicKey", this->senderPublicKey }, { "signature", this->signature }, @@ -234,6 +314,8 @@ std::map Ark::Crypto::Transactions::Transaction::toArr }; } +/**/ + std::string Ark::Crypto::Transactions::Transaction::toJson() { std::map txArray = this->toArray(); @@ -241,35 +323,35 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { DynamicJsonDocument doc(docCapacity); // Amount + // >= Core v.2.5 'amount' json is string-type doc["amount"] = txArray["amount"]; // Asset - if (this->type == 0) { // Transfer + if (this->type == 0) { + // Transfer //do nothing - } else if (this->type == 1) { // Second Signature Registration - + } else if (this->type == 1) { + // Second Signature Registration JsonObject tAsset = doc.createNestedObject("asset"); JsonObject signature = tAsset.createNestedObject("signature"); signature["publicKey"] = txArray["publicKey"]; - - } else if (this->type == 2) { // Delegate Registration - + } else if (this->type == 2) { + // Delegate Registration JsonObject dAsset = doc.createNestedObject("asset"); JsonObject delegate = dAsset.createNestedObject("delegate"); delegate["username"] = txArray["username"]; - - }else if (this->type == 3) { // Vote - + } else if (this->type == 3) { + // Vote JsonObject vAsset = doc.createNestedObject("asset"); JsonArray votes = vAsset.createNestedArray("votes"); - std::string::size_type lastPos = txArray["votes"].find_first_not_of(",", 0); - std::string::size_type pos = txArray["votes"].find_first_of(",", lastPos); + std::string::size_type lastPos = txArray["votes"].find_first_not_of(',', 0); + std::string::size_type pos = txArray["votes"].find_first_of(',', lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { votes.add(txArray["votes"].substr(lastPos, pos - lastPos)); - lastPos = txArray["votes"].find_first_not_of(",", pos); - pos = txArray["votes"].find_first_of(",", lastPos); - } + lastPos = txArray["votes"].find_first_not_of(',', pos); + pos = txArray["votes"].find_first_of(',', lastPos); + }; // } else if (this->type == 4) { // Multisignature Registration // // TODO @@ -284,6 +366,7 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { }; // Fee + // >= Core v.2.5 'fee' json is string-type doc["fee"] = txArray["fee"]; // Id @@ -291,16 +374,16 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { // Network if (txArray["network"] != "0") { - doc["network"] = txArray["network"]; - } + doc["network"] = atoi(txArray["network"].c_str()); + }; - // RecipientId - doc["recipientId"] = txArray["recipientId"]; + // recipient + doc["recipient"] = txArray["recipient"]; // SecondSignature if (std::strlen(txArray["secondSignature"].c_str()) > 0) { doc["secondSignature"] = txArray["secondSignature"]; - } + }; // SenderPublicKey doc["senderPublicKey"] = txArray["senderPublicKey"]; @@ -309,37 +392,37 @@ std::string Ark::Crypto::Transactions::Transaction::toJson() { doc["signature"] = txArray["signature"]; // Signatures - if (this->signatures.size() > 0) { + if (!this->signatures.empty()) { JsonArray signatures = doc.createNestedArray("signatures"); - std::string::size_type lastPos = txArray["signatures"].find_first_not_of(",", 0); - std::string::size_type pos = txArray["signatures"].find_first_of(",", lastPos); + std::string::size_type lastPos = txArray["signatures"].find_first_not_of(',', 0); + std::string::size_type pos = txArray["signatures"].find_first_of(',', lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { signatures.add(txArray["signatures"].substr(lastPos, pos - lastPos)); - lastPos = txArray["signatures"].find_first_not_of(",", pos); - pos = txArray["signatures"].find_first_of(",", lastPos); - } - } + lastPos = txArray["signatures"].find_first_not_of(',', pos); + pos = txArray["signatures"].find_first_of(',', lastPos); + }; + }; // SignSignature if (std::strlen(txArray["signSignature"].c_str()) > 0) { doc["signSignature"] = txArray["signSignature"]; - } + }; // Timestamp - doc["timestamp"] = txArray["timestamp"]; + doc["timestamp"] = strtoul(txArray["timestamp"].c_str(), nullptr, 10); // Type - doc["type"] = txArray["type"]; + doc["type"] = atoi(txArray["type"].c_str()); // VendorField if (std::strlen(txArray["vendorField"].c_str()) > 0) { doc["vendorField"] = txArray["vendorField"]; - } + }; // Version if (txArray["version"] != "0") { - doc["version"] = txArray["version"]; - } + doc["version"] = atoi(txArray["version"].c_str()); + }; char jsonChar[docCapacity]; serializeJson(doc, jsonChar, docCapacity); diff --git a/src/utils/message.cpp b/src/utils/message.cpp index 916fc0d4..c5a8feaf 100644 --- a/src/utils/message.cpp +++ b/src/utils/message.cpp @@ -1,43 +1,21 @@ -/** - * This file is part of Ark Cpp Crypto. - * - * (c) Ark Ecosystem - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - **/ #include "utils/message.h" #include "helpers/json.h" -/** - * @brief Create a message object for checking its validity. - * - * @param std::string msg - * @param PublicKey pubKey - * @param std::vector sig - **/ Ark::Crypto::Utils::Message::Message( std::string msg, PublicKey pubKey, std::vector sig) - : message(msg), + : message(std::move(msg)), publicKey(pubKey), - signature(sig){}; + signature(std::move(sig)) {}; + /**/ -/** - * @brief Sign a message using the given passphrase. - * - * @param string message - * @param string passphrase - * - * @return bool - **/ bool Ark::Crypto::Utils::Message::sign( std::string newMessage, const char *const passphrase) { - this->message = newMessage; + this->message = std::move(newMessage); /* Get the PrivateKey */ auto privateKey = PrivateKey::fromPassphrase(passphrase); @@ -46,7 +24,8 @@ bool Ark::Crypto::Utils::Message::sign( this->publicKey = PublicKey::fromPrivateKey(privateKey); /* Get the Hash */ - const auto unsignedMessage = reinterpret_cast(message.c_str()); + const auto unsignedMessage = reinterpret_cast( + message.c_str()); const auto hash = Sha256::getHash(unsignedMessage, this->message.length()); /* Sign it */ @@ -54,27 +33,20 @@ bool Ark::Crypto::Utils::Message::sign( return this->verify(); }; + /**/ -/** - * @brief Verify the message contents. - * - * @return bool - **/ bool Ark::Crypto::Utils::Message::verify() { // cast message to unsigned char* - const auto unsignedMessage = reinterpret_cast(this->message.c_str()); + const auto unsignedMessage = reinterpret_cast( + this->message.c_str()); const auto hash = Sha256::getHash(unsignedMessage, this->message.length()); return cryptoVerify(this->publicKey, hash, this->signature); }; + /**/ -/** - * @brief Convert the message to its array representation using an array of pairs - * - * @return std::map - **/ std::map Ark::Crypto::Utils::Message::toArray() { return { { "publickey", this->publicKey.toString() }, @@ -82,13 +54,9 @@ std::map Ark::Crypto::Utils::Message::toArray() { { "message", this->message } }; } + /**/ -/** - * @brief Convert the message to its JSON representation. - * - * @return std::string - **/ std::string Ark::Crypto::Utils::Message::toJson() { std::map messageArray = this->toArray(); @@ -110,4 +78,3 @@ std::string Ark::Crypto::Utils::Message::toJson() { return jsonStr; } -/**/ diff --git a/src/utils/message.h b/src/utils/message.h index f159c549..53d9eba4 100644 --- a/src/utils/message.h +++ b/src/utils/message.h @@ -24,8 +24,6 @@ #include "rfc6979/rfc6979.h" -#include -#include #include #include #include @@ -35,12 +33,7 @@ using namespace Ark::Crypto::Identities; namespace Ark { namespace Crypto { namespace Utils { - -/** - * This is the message class. - * - * @author Simon Downey - **/ +/**/ class Message { public: std::string message; @@ -57,7 +50,6 @@ class Message { std::string toJson(); }; /**/ - }; // namespace Utils }; // namespace Crypto }; // namespace Ark diff --git a/src/utils/slot.cpp b/src/utils/slot.cpp index e8244b02..165f757c 100644 --- a/src/utils/slot.cpp +++ b/src/utils/slot.cpp @@ -1,7 +1,10 @@ -#include "helpers/crypto_helpers.h" #include "utils/slot.h" +#include "common/network.hpp" + +#include "helpers/crypto_helpers.h" + #ifndef USE_IOT // OS Builds #include @@ -10,16 +13,13 @@ #undef round #include "date/date.h" - uint64_t Ark::Crypto::Utils::Slot::epoch(Crypto::Networks::AbstractNetwork network) { + uint64_t Ark::Crypto::Utils::Slot::epoch( + const Ark::Crypto::Network& network) { // https://stackoverflow.com/questions/33421450/c-c-time-zone-correct-time-conversion-to-seconds-since-epoch/33438989#33438989 std::istringstream in(network.epoch()); std::chrono::system_clock::time_point tp; in >> date::parse("%FT%TZ", tp); - if (in.fail()) { - in.clear(); - in.str(network.epoch()); - in >> date::parse("%FT%T%z", tp); - }; + // cast milliseconds as uint64_t in seconds(/ 1000) return static_cast( std::chrono::duration_cast( @@ -36,7 +36,8 @@ #endif -uint64_t Ark::Crypto::Utils::Slot::time(Crypto::Networks::AbstractNetwork network) { +uint64_t Ark::Crypto::Utils::Slot::time( + const Ark::Crypto::Network& network) { const auto time = now() - epoch(network); return (time > 0) ? time : 0; } @@ -47,7 +48,8 @@ uint64_t Ark::Crypto::Utils::Slot::time(Crypto::Networks::AbstractNetwork networ #include /* strtol */ #include - uint64_t Ark::Crypto::Utils::Slot::epoch(Crypto::Networks::AbstractNetwork network) { + uint64_t Ark::Crypto::Utils::Slot::epoch( + const Ark::Crypto::Network& network) { constexpr const size_t expectedLength = sizeof("2017-03-21T13:00:00.000Z") - 1; if (expectedLength != 24) { return 0; } // Unexpected ISO 8601 date/time length @@ -73,10 +75,10 @@ uint64_t Ark::Crypto::Utils::Slot::time(Crypto::Networks::AbstractNetwork networ // 'time(0) will collide with Slot::time // so we create the call outside the Slot namespace. - uint64_t NOW() { return time(0); } + static uint64_t Now() { return time(0); } uint64_t Ark::Crypto::Utils::Slot::now() { - return NOW(); + return Now(); } #endif diff --git a/src/utils/slot.h b/src/utils/slot.h index 93650f19..96865884 100644 --- a/src/utils/slot.h +++ b/src/utils/slot.h @@ -10,23 +10,25 @@ #ifndef ARK_UTILITIES_SLOTS_H #define ARK_UTILITIES_SLOTS_H -#include "configuration/network.h" +#include + +#include "common/network.hpp" namespace Ark { namespace Crypto { namespace Utils { - +/**/ class Slot { public: - static uint64_t epoch(Crypto::Networks::AbstractNetwork network); - static uint64_t time(Crypto::Networks::AbstractNetwork network); + static uint64_t epoch(const Network& network); + static uint64_t time(const Network& network); private: static uint64_t now(); }; - -} // namespace Utils -} // namespace Crypto -} // namespace Ark +/**/ +}; // namespace Utils +}; // namespace Crypto +}; // namespace Ark #endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b79d8dc9..668d43ba 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,8 +2,6 @@ cmake_minimum_required(VERSION 3.2.2) project(Ark-Cpp-Crypto-tests C CXX) -set(BUILD_GMOCK OFF FORCE) - add_subdirectory(lib/googletest) include(CTest) @@ -19,24 +17,29 @@ include_directories(${PROJECT_SOURCE_DIR}/../src/lib/ArduinoJson) include_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) set (TEST_SRC - ${PROJECT_SOURCE_DIR}/configuration/fee.cpp - ${PROJECT_SOURCE_DIR}/configuration/network.cpp - ${PROJECT_SOURCE_DIR}/enums/fees.cpp - ${PROJECT_SOURCE_DIR}/enums/types.cpp - ${PROJECT_SOURCE_DIR}/identities/address.cpp - ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp - ${PROJECT_SOURCE_DIR}/identities/publickey.cpp - ${PROJECT_SOURCE_DIR}/identities/wif.cpp - ${PROJECT_SOURCE_DIR}/networks/abstractnetwork.cpp - ${PROJECT_SOURCE_DIR}/networks/devnet.cpp - ${PROJECT_SOURCE_DIR}/networks/mainnet.cpp - ${PROJECT_SOURCE_DIR}/networks/testnet.cpp - ${PROJECT_SOURCE_DIR}/transactions/builder.cpp - ${PROJECT_SOURCE_DIR}/transactions/deserializer.cpp - ${PROJECT_SOURCE_DIR}/transactions/serializer.cpp - ${PROJECT_SOURCE_DIR}/transactions/transaction.cpp - ${PROJECT_SOURCE_DIR}/utils/message.cpp - ${PROJECT_SOURCE_DIR}/utils/slot.cpp + ${PROJECT_SOURCE_DIR}/common/configuration.cpp + ${PROJECT_SOURCE_DIR}/common/fee_policy.cpp + ${PROJECT_SOURCE_DIR}/common/network.cpp + ${PROJECT_SOURCE_DIR}/defaults/static_fees.cpp + ${PROJECT_SOURCE_DIR}/defaults/transaction_types.cpp + ${PROJECT_SOURCE_DIR}/helpers/crypto_helpers.cpp + ${PROJECT_SOURCE_DIR}/helpers/crypto.cpp + ${PROJECT_SOURCE_DIR}/helpers/encoding/hex.cpp + ${PROJECT_SOURCE_DIR}/identities/address.cpp + ${PROJECT_SOURCE_DIR}/identities/privatekey.cpp + ${PROJECT_SOURCE_DIR}/identities/publickey.cpp + ${PROJECT_SOURCE_DIR}/identities/wif.cpp + ${PROJECT_SOURCE_DIR}/managers/fee_manager.cpp + ${PROJECT_SOURCE_DIR}/managers/network_manager.cpp + ${PROJECT_SOURCE_DIR}/networks/devnet.cpp + ${PROJECT_SOURCE_DIR}/networks/mainnet.cpp + ${PROJECT_SOURCE_DIR}/networks/testnet.cpp + ${PROJECT_SOURCE_DIR}/transactions/builder.cpp + ${PROJECT_SOURCE_DIR}/transactions/deserializer.cpp + ${PROJECT_SOURCE_DIR}/transactions/serializer.cpp + ${PROJECT_SOURCE_DIR}/transactions/transaction.cpp + ${PROJECT_SOURCE_DIR}/utils/message.cpp + ${PROJECT_SOURCE_DIR}/utils/slot.cpp ) find_library(Ark-Cpp-Crypto-tests PUBLIC) @@ -54,4 +57,4 @@ if (CMAKE_BUILD_TYPE STREQUAL "Coverage") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage") - endif() #CMAKE_BUILD_TYPE STREQUAL "Coverage" +endif() #CMAKE_BUILD_TYPE STREQUAL "Coverage" diff --git a/test/common/configuration.cpp b/test/common/configuration.cpp new file mode 100644 index 00000000..f0ea4e6d --- /dev/null +++ b/test/common/configuration.cpp @@ -0,0 +1,134 @@ + +#include "gtest/gtest.h" + +#include + +#include + +namespace { +static const Network kDefaultNetwork = Networks::Devnet(); +static const Network kCustomNetwork = { // random parameters + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; +/**/ +static const FeePolicy kDefaultFeePolicy = defaults::Fees::StaticFeePolicy(); +static const FeePolicy kCustomFeePolicy = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; +static const uint64_t kTestAmount = 1000000000ULL; +/**/ +static const Configuration kDefaultConfiguration = Configuration(); +static const Configuration kCustomFeeConfiguration(kCustomFeePolicy); +static const Configuration kCustomNetworkConfiguration(kCustomNetwork); +static const Configuration kCustomConfiguration(kCustomNetwork, + kCustomFeePolicy); +} //namespace + +/**/ + +//* +TEST(common, configuration_constructor_default) { + Configuration config; + bool isMatching = kDefaultConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_constructor_network) { + Configuration config(kCustomNetwork); + bool isMatching = kCustomNetworkConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_constructor_fee) { + Configuration config(kCustomFeePolicy); + bool isMatching = kCustomFeeConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_constructor_with_network_and_fee) { + Configuration config(kCustomNetwork, kCustomFeePolicy); + bool isMatching = kCustomConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_network_get) { + Configuration config; + auto network = config.getNetwork(); + bool isMatching = kDefaultNetwork == network; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_network_set) { + Configuration config; + config.setNetwork(kCustomNetwork); + auto network = config.getNetwork(); + bool isMatching = kCustomNetwork == network; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_fee_get) { + Configuration config; + auto transferType = defaults::TransactionTypes::Transfer; + auto defaultTransferFee = kDefaultFeePolicy[transferType]; + auto transferFee = config.getFee(transferType); + ASSERT_EQ(defaultTransferFee, transferFee); +} + +/**/ + +TEST(common, configuration_fee_set) { + Configuration config; + auto transferType = defaults::TransactionTypes::Transfer; + config.setFee(transferType, kTestAmount); + uint64_t newFee = config.getFee(transferType); + ASSERT_EQ(kTestAmount, newFee); +} + +/**/ + + +TEST(common, configuration_fees_get_policy) { + Configuration config; + bool isMatching = kDefaultFeePolicy == config.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_fees_policy_set) { + Configuration config; + config.setPolicy(kCustomFeePolicy); + bool isMatching = kCustomFeePolicy == config.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_comparison_equals) { + Configuration config; + bool isMatching = kDefaultConfiguration == config; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(common, configuration_comparison_not_equal) { + Configuration config(kCustomNetwork); + bool notMatching = kCustomConfiguration != config; + ASSERT_TRUE(notMatching); +} diff --git a/test/common/fee_policy.cpp b/test/common/fee_policy.cpp new file mode 100644 index 00000000..2c59bc05 --- /dev/null +++ b/test/common/fee_policy.cpp @@ -0,0 +1,20 @@ + +#include "gtest/gtest.h" + +#include + +namespace { +static const FeePolicy kCustomFeePolicy = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; +} //namespace + +/**/ + +TEST(common, fee_policy_custom) { + const FeePolicy feePolicy(kCustomFeePolicy); + for (auto i = 0; i < kCustomFeePolicy.size(); ++i) { + ASSERT_EQ(kCustomFeePolicy[i], feePolicy[i]); + }; +} diff --git a/test/common/network.cpp b/test/common/network.cpp new file mode 100644 index 00000000..003cf425 --- /dev/null +++ b/test/common/network.cpp @@ -0,0 +1,67 @@ + +#include "gtest/gtest.h" + +#include + +namespace { // NOLINT +static const Network kDevnetNetwork = Networks::Devnet(); +/**/ +static const std::string kCustomNethash = "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df"; +static const uint8_t kCustomSlip44 = 1; +static const uint8_t kCustomWif = 0x53; +static const uint8_t kCustomVersion = 0xaa; +static const std::string kCustomEpoch = "2019-04-12T13:00:00.000Z"; +/**/ +static const Network kCustomNetwork { + kCustomNethash, + kCustomSlip44, kCustomWif, kCustomVersion, + kCustomEpoch +}; +} // namespace + +/**/ + +TEST(common, network_constructor_default) { + Network network; + bool networksMatch = kDevnetNetwork == network; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_constructor_list) { + Network customNetwork = { kCustomNethash, + kCustomSlip44, + kCustomWif, + kCustomVersion, + kCustomEpoch }; + bool networksMatch = kCustomNetwork == customNetwork; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_comparison_equals) { + Network customNetwork(kDevnetNetwork); + bool networksMatch = kDevnetNetwork == customNetwork; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_comparison_not_equal) { + Network customNetwork(kCustomNetwork); + bool networksMatch = kDevnetNetwork != customNetwork; + ASSERT_TRUE(networksMatch); +} + +/**/ + +TEST(common, network_get_parameters) { + Network network(kDevnetNetwork); + ASSERT_STREQ(kDevnetNetwork.nethash().c_str(), network.nethash().c_str()); + ASSERT_EQ(kDevnetNetwork.slip44(), network.slip44()); + ASSERT_EQ(kDevnetNetwork.wif(), network.wif()); + ASSERT_EQ(kDevnetNetwork.version(), network.version()); + ASSERT_STREQ(kDevnetNetwork.epoch().c_str(), network.epoch().c_str()); +} diff --git a/test/configuration/fee.cpp b/test/configuration/fee.cpp deleted file mode 100644 index 99c5d1eb..00000000 --- a/test/configuration/fee.cpp +++ /dev/null @@ -1,39 +0,0 @@ - -#include "arkCrypto.h" -#include "gtest/gtest.h" - -TEST(configuration, fee_get) { - Ark::Crypto::Configuration::Fee fee; - ASSERT_TRUE(10000000 == fee.get(0)); - ASSERT_TRUE(500000000 == fee.get(1)); - ASSERT_TRUE(2500000000 == fee.get(2)); - ASSERT_TRUE(100000000 == fee.get(3)); - ASSERT_TRUE(500000000 == fee.get(4)); - ASSERT_TRUE(0 == fee.get(5)); - ASSERT_TRUE(0 == fee.get(6)); - ASSERT_TRUE(0 == fee.get(7)); - ASSERT_TRUE(0 == fee.get(8)); -} - -TEST(configuration, fee_set) { - Ark::Crypto::Configuration::Fee fee; - fee.set(0, 20000000ul); - fee.set(1, 1000000000ul); - fee.set(2, 4000000000ul); - fee.set(3, 200000000ul); - fee.set(4, 1000000000ul); - fee.set(5, 1ul); - fee.set(6, 1ul); - fee.set(7, 1ul); - fee.set(8, 1ul); - - ASSERT_TRUE(20000000 == fee.get(0)); - ASSERT_TRUE(1000000000 == fee.get(1)); - ASSERT_TRUE(4000000000 == fee.get(2)); - ASSERT_TRUE(200000000 == fee.get(3)); - ASSERT_TRUE(1000000000 == fee.get(4)); - ASSERT_TRUE(1 == fee.get(5)); - ASSERT_TRUE(1 == fee.get(6)); - ASSERT_TRUE(1 == fee.get(7)); - ASSERT_TRUE(1 == fee.get(8)); -} diff --git a/test/configuration/network.cpp b/test/configuration/network.cpp deleted file mode 100644 index 41aa3763..00000000 --- a/test/configuration/network.cpp +++ /dev/null @@ -1,29 +0,0 @@ - -#include "arkCrypto.h" -#include "gtest/gtest.h" - -TEST(configuration, network_get) { - auto network = Network().get(); // defaults to devnet - ASSERT_EQ(0x1E, network.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, network.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xaa, network.getBase58Prefix(BASE58_WIF)); - ASSERT_EQ(46090600, network.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(46089520, network.getBIP32Prefix(BIP32_PREFIX_XPRV)); - ASSERT_STREQ("2017-03-21T13:00:00.000Z", network.epoch()); - ASSERT_EQ(true, network.isLocked()); - ASSERT_EQ(30, network.version()); -} - -TEST(configuration, network_set) { - Network network; - network.set(Testnet); - auto testnet = network.get(); - ASSERT_EQ(0x17, testnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, testnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xba, testnet.getBase58Prefix(BASE58_WIF)); - ASSERT_EQ(70617039, testnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(70615956, testnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); - ASSERT_STREQ("2017-03-21T13:00:00.000Z", testnet.epoch()); - ASSERT_EQ(true, testnet.isLocked()); - ASSERT_EQ(23, testnet.version()); -} diff --git a/test/defaults/static_fees.cpp b/test/defaults/static_fees.cpp new file mode 100644 index 00000000..6951bf3c --- /dev/null +++ b/test/defaults/static_fees.cpp @@ -0,0 +1,40 @@ + +#include "gtest/gtest.h" + +#include + +#include + +namespace { +static const uint64_t kTransfer = 10000000ULL; +static const uint64_t kSecondSignatureRegistration = 500000000ULL; +static const uint64_t kDelegateRegistration = 2500000000ULL; +static const uint64_t kVote = 100000000ULL; +static const uint64_t kMultiSignatureRegistration = 500000000ULL; +static const uint64_t kIpfs = 0ULL; +static const uint64_t kTimelockTransfer = 0ULL; +static const uint64_t kMultiPayment = 0ULL; +static const uint64_t kDelegateResignation = 2500000000ULL; +static const uint8_t kTransferType = 0; +static const uint8_t kSecondSignatureRegistrationType = 1; +static const uint8_t kDelegateRegistrationType = 2; +static const uint8_t kVoteType = 3; +static const uint8_t kMultiSignatureRegistrationType = 4; +static const uint8_t kIpfsType = 5; +static const uint8_t kTimelockTransferType = 6; +static const uint8_t kMultiPaymentType = 7; +static const uint8_t kDelegateResignationType = 8; +} //namespace + +TEST(defaults, fees_static) { // NOLINT + const auto feePolicy = defaults::Fees::StaticFeePolicy(); + ASSERT_EQ(kTransfer, feePolicy[kTransferType]); + ASSERT_EQ(kSecondSignatureRegistration, feePolicy[kSecondSignatureRegistrationType]); + ASSERT_EQ(kDelegateRegistration, feePolicy[kDelegateRegistrationType]); + ASSERT_EQ(kVote, feePolicy[kVoteType]); + ASSERT_EQ(kMultiSignatureRegistration, feePolicy[kMultiSignatureRegistrationType]); + ASSERT_EQ(kIpfs, feePolicy[kIpfsType]); + ASSERT_EQ(kTimelockTransfer, feePolicy[kTimelockTransferType]); + ASSERT_EQ(kMultiPayment, feePolicy[kMultiPaymentType]); + ASSERT_EQ(kDelegateResignation, feePolicy[kDelegateResignationType]); +} diff --git a/test/defaults/transaction_types.cpp b/test/defaults/transaction_types.cpp new file mode 100644 index 00000000..3afab7c8 --- /dev/null +++ b/test/defaults/transaction_types.cpp @@ -0,0 +1,30 @@ + +#include "gtest/gtest.h" + +#include + +namespace { +static const uint8_t kTransferType = 0; +static const uint8_t kSecondSignatureRegistrationType = 1; +static const uint8_t kDelegateRegistrationType = 2; +static const uint8_t kVoteType = 3; +static const uint8_t kMultiSignatureRegistrationType = 4; +static const uint8_t kIpfsType = 5; +static const uint8_t kTimelockTransferType = 6; +static const uint8_t kMultiPaymentType = 7; +static const uint8_t kDelegateResignationType = 8; +} //namespace + +/**/ + +TEST(defaults, transaction_types) { // NOLINT + ASSERT_EQ(kTransferType, defaults::TransactionTypes::Transfer); + ASSERT_EQ(kSecondSignatureRegistrationType, defaults::TransactionTypes::SecondSignatureRegistration); + ASSERT_EQ(kDelegateRegistrationType, defaults::TransactionTypes::DelegateRegistration); + ASSERT_EQ(kVoteType, defaults::TransactionTypes::Vote); + ASSERT_EQ(kMultiSignatureRegistrationType, defaults::TransactionTypes::MultiSignatureRegistration); + ASSERT_EQ(kIpfsType, defaults::TransactionTypes::Ipfs); + ASSERT_EQ(kTimelockTransferType, defaults::TransactionTypes::TimelockTransfer); + ASSERT_EQ(kMultiPaymentType, defaults::TransactionTypes::MultiPayment); + ASSERT_EQ(kDelegateResignationType, defaults::TransactionTypes::DelegateResignation); +} diff --git a/test/enums/fees.cpp b/test/enums/fees.cpp deleted file mode 100644 index d1aedb5b..00000000 --- a/test/enums/fees.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "gtest/gtest.h" - -#include "enums/fees.h" - -TEST(enums, fees) { - Ark::Crypto::Enums::Fees fees; - - auto feeZERO = fees.TRANSFER; - ASSERT_TRUE(10000000 == feeZERO); - - auto feeONE = fees.SECOND_SIGNATURE_REGISTRATION; - ASSERT_TRUE(500000000 == feeONE); - - auto feeTWO = fees.DELEGATE_REGISTRATION; - ASSERT_TRUE(2500000000 == feeTWO); - - auto feeTHREE = fees.VOTE; - ASSERT_TRUE(100000000 == feeTHREE); - - auto feeFOUR = fees.MULTI_SIGNATURE_REGISTRATION; - ASSERT_TRUE(500000000 == feeFOUR); - - auto feeFIVE = fees.IPFS; - ASSERT_TRUE(0 == feeFIVE); - - auto feeSIX = fees.TIMELOCK_TRANSFER; - ASSERT_TRUE(0 == feeSIX); - - auto feeSEVEN = fees.MULTI_PAYMENT; - ASSERT_TRUE(0 == feeSEVEN); - - auto feeEIGHT = fees.DELEGATE_RESIGNATION; - ASSERT_TRUE(0 == feeEIGHT); -} diff --git a/test/enums/types.cpp b/test/enums/types.cpp deleted file mode 100644 index 4d482025..00000000 --- a/test/enums/types.cpp +++ /dev/null @@ -1,15 +0,0 @@ -#include "gtest/gtest.h" - -#include "enums/types.h" - -TEST(enums, types) { - ASSERT_EQ(0, Ark::Crypto::Enums::Types::TRANSFER); - ASSERT_EQ(1, Ark::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION); - ASSERT_EQ(2, Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION); - ASSERT_EQ(3, Ark::Crypto::Enums::Types::VOTE); - ASSERT_EQ(4, Ark::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION); - ASSERT_EQ(5, Ark::Crypto::Enums::Types::IPFS); - ASSERT_EQ(6, Ark::Crypto::Enums::Types::TIMELOCK_TRANSFER); - ASSERT_EQ(7, Ark::Crypto::Enums::Types::MULTI_PAYMENT); - ASSERT_EQ(8, Ark::Crypto::Enums::Types::DELEGATE_RESIGNATION); -} diff --git a/test/helpers/crypto.cpp b/test/helpers/crypto.cpp new file mode 100644 index 00000000..2acea58f --- /dev/null +++ b/test/helpers/crypto.cpp @@ -0,0 +1,108 @@ + +#include "gtest/gtest.h" + +#include "identities/privatekey.h" +#include "identities/publickey.h" + +#include "bcl/Sha256.hpp" +#include "bcl/Uint256.hpp" + +#include "helpers/crypto.h" + +namespace { // NOLINT + std::vector MessageHashTestBytes = { + 165, 145, 166, 212, 11, 244, 32, 64, + 74, 1, 23, 51, 207, 183, 177, 144, + 214, 44, 101, 191, 11, 205, 163, 43, + 87, 178, 119, 217, 173, 159, 20, 110 + }; + + std::vector PrivateKeyTestBytes = { + 216, 131, 156, 36, 50, 191, 208, 166, + 126, 241, 10, 128, 75, 169, 145, 234, + 187, 161, 159, 21, 74, 61, 112, 121, + 23, 104, 29, 69, 130, 42, 87, 18 + }; + + std::vector PublicKeyTestBytes = { + 3, + 65, 81, 163, 236, 70, 181, 103, 10, + 104, 43, 10, 99, 57, 79, 134, 53, + 135, 209, 188, 151, 72, 59, 27, 108, + 112, 235, 88, 231, 240, 174, 209, 146 + }; + std::vector InvalidPublicKeyTestBytes = { + 3, + 66, 81, 163, 236, 70, 181, 103, 10, + 104, 43, 10, 99, 57, 79, 134, 53, + 135, 209, 188, 151, 72, 59, 27, 108, + 112, 235, 88, 231, 240, 174, 209, 146 + }; + + std::vector RValueTestBytes = { + 15, 180, 173, 221, 209, 241, 214, 82, + 181, 68, 234, 106, 182, 40, 40, 160, + 166, 91, 113, 46, 212, 71, 226, 83, + 141, 176, 202, 235, 250, 104, 146, 158 + }; + + std::vector SValueTestBytes = { + 94, 203, 46, 28, 99, 178, 152, 121, + 194, 236, 241, 37, 93, 181, 6, 214, + 113, 200, 179, 250, 96, 23, 246, 124, + 253, 27, 240, 126, 110, 221, 28, 200 + }; + + std::vector SignatureTestBytes = { + 48, 68, 2, 32, 15, 180, 173, 221, 209, 241, + 214, 82, 181, 68, 234, 106, 182, 40, 40, 160, + 166, 91, 113, 46, 212, 71, 226, 83, 141, 176, + 202, 235, 250, 104, 146, 158, 2, 32, 94, 203, + 46, 28, 99, 178, 152, 121, 194, 236, 241, 37, + 93, 181, 6, 214, 113, 200, 179, 250, 96, 23, + 246, 124, 253, 27, 240, 126, 110, 221, 28, 200 + }; +}; + +/**/ + +TEST(helpers, crypto_sign) { + Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); + Ark::Crypto::Identities::PrivateKey privateKey(&PrivateKeyTestBytes[0]); + std::vector signature; + cryptoSign( + hash, + privateKey, + signature); + + for (auto i = 0; i < signature.size(); ++i) { + ASSERT_EQ(signature[i], SignatureTestBytes[i]); + }; +} + +/**/ + +TEST(helpers, crypto_verify_valid) { + Ark::Crypto::Identities::PublicKey publicKey(&PublicKeyTestBytes[0]); + Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); + + bool isValid = cryptoVerify( + publicKey, + hash, + SignatureTestBytes); + ASSERT_TRUE(isValid); +} + +/**/ + +TEST(helpers, crypto_verify_invalid) { + Ark::Crypto::Identities::PublicKey publicKey(&InvalidPublicKeyTestBytes[0]); +// Ark::Crypto::Identities::PublicKey publicKey(&InvalidPublicKeyTestBytes[0]); + Sha256Hash hash(&MessageHashTestBytes[0], MessageHashTestBytes.size()); + + bool isValid = cryptoVerify( + publicKey, + hash, + SignatureTestBytes); + ASSERT_FALSE(isValid); +} diff --git a/test/helpers/crypto_helpers.cpp b/test/helpers/crypto_helpers.cpp new file mode 100644 index 00000000..e3bc51ec --- /dev/null +++ b/test/helpers/crypto_helpers.cpp @@ -0,0 +1,30 @@ + +#include "gtest/gtest.h" + +#include "helpers/crypto_helpers.h" + +#include +#include + +TEST(helpers, pack_unpack) { + std::vector packBuffer; + uint8_t packValue = 23; + pack(packBuffer, packValue); + + uint8_t unpackValue; + unpack(&unpackValue, &packBuffer[0]); + ASSERT_EQ(packValue, unpackValue); +} + +/**/ + +TEST(helpers, join) { + const auto strBuffer = "123"; + std::vector vstr(3); + vstr[0] = strBuffer[0]; + vstr[1] = strBuffer[1]; + vstr[2]= strBuffer[2]; + + std::string joined = join(vstr); + ASSERT_STREQ(joined.c_str(), strBuffer); +} diff --git a/test/helpers/encoding/hex.cpp b/test/helpers/encoding/hex.cpp new file mode 100644 index 00000000..5c0cb8f7 --- /dev/null +++ b/test/helpers/encoding/hex.cpp @@ -0,0 +1,41 @@ + +#include "gtest/gtest.h" + +#include "helpers/encoding/hex.h" + +namespace { // NOLINT + std::vector SignatureTestBytes = { + 48, 68, 2, 32, 15, 180, 173, 221, 209, 241, + 214, 82, 181, 68, 234, 106, 182, 40, 40, 160, + 166, 91, 113, 46, 212, 71, 226, 83, 141, 176, + 202, 235, 250, 104, 146, 158, 2, 32, 94, 203, + 46, 28, 99, 178, 152, 121, 194, 236, 241, 37, + 93, 181, 6, 214, 113, 200, 179, 250, 96, 23, + 246, 124, 253, 27, 240, 126, 110, 221, 28, 200 + }; + const auto SignatureTestString = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; + const auto SignatureTestStringSpaces = "30 44 02 20 0f b4 ad dd d1 f1 d6 52 b5 44 ea 6a b6 28 28 a0 a6 5b 71 2e d4 47 e2 53 8d b0 ca eb fa 68 92 9e 02 20 5e cb 2e 1c 63 b2 98 79 c2 ec f1 25 5d b5 06 d6 71 c8 b3 fa 60 17 f6 7c fd 1b f0 7e 6e dd 1c c8"; +} + +TEST(helpers, hex_bytes_to_hex) { + const auto result = BytesToHex(&SignatureTestBytes[0], &SignatureTestBytes[0] + SignatureTestBytes.size()); + ASSERT_STREQ(result.c_str(), SignatureTestString); +} + +/**/ + +TEST(helpers, hex_hex_to_bytes) { + const auto result = HexToBytes(SignatureTestString); + for (auto i = 0; i < result.size(); ++i) { + ASSERT_TRUE(result[i] == SignatureTestBytes[i]); + }; +} + +/**/ + +TEST(helpers, hex_hex_to_bytes_spaces) { + const auto result = HexToBytes(SignatureTestStringSpaces); + for (auto i = 0; i < result.size(); ++i) { + ASSERT_TRUE(result[i] == SignatureTestBytes[i]); + }; +} diff --git a/test/identities/address.cpp b/test/identities/address.cpp index 9b0e85e6..ebbfaad3 100644 --- a/test/identities/address.cpp +++ b/test/identities/address.cpp @@ -4,39 +4,104 @@ #include "identities/address.h" #include "identities/privatekey.h" #include "identities/publickey.h" + +#include + using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t networkVersion = 0x1E; + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t NetworkVersion = 0x1E; + const auto AddressString = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; + const uint8_t TestAddressBytes[34] = { + 68, 54, 49, 109, 102, 83, 103, 103, + 122, 98, 118, 81, 103, 84, 85, 101, + 54, 74, 104, 89, 75, 72, 50, 100, + 111, 72, 97, 113, 74, 51, 68, 121, 105, 98 + }; } // namespace +/**/ + +TEST(identities, address_from_bytes) { + Address address(TestAddressBytes); + ASSERT_STREQ(address.toString().c_str(), AddressString); +} + +/**/ + +TEST(identities, address_to_bytes) { + Address address(AddressString); + const auto addressBytes = address.toBytes(); + for (auto i = 0; i < 34; ++i) { + ASSERT_EQ(addressBytes[i], TestAddressBytes[i]); + }; +} + +/**/ + TEST(identities, address_from_passphrase) { - Address address = Address::fromPassphrase(passphrase, networkVersion); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + Address address = Address::fromPassphrase(Passphrase, NetworkVersion); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + TEST(identities, address_from_privatekey) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - Address address = Address::fromPrivateKey(privateKey, networkVersion); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + const auto privateKeyString = "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"; + PrivateKey privateKey(privateKeyString); + Address address = Address::fromPrivateKey(privateKey, NetworkVersion); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + TEST(identities, address_from_publickey) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - Address address = Address::fromPublicKey(publicKey, networkVersion); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + const auto publicKeyString = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; + PublicKey publicKey(publicKeyString); + Address address = Address::fromPublicKey(publicKey, NetworkVersion); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + TEST(identities, address_from_string) { - Address address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", address.toString().c_str()); + Address address(AddressString); + ASSERT_STREQ(AddressString, address.toString().c_str()); } +/**/ + +TEST(identities, address_validate_address) { + Address address(AddressString); + ASSERT_TRUE(Address::validate(address, NetworkVersion)); +} + +/**/ + TEST(identities, address_validate) { - Address address("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"); - ASSERT_TRUE(Address::validate(address, networkVersion)); + Address address(AddressString); + ASSERT_TRUE(Address::validate(address, NetworkVersion)); +} + +/**/ + +TEST(identities, address_validate_string) { + ASSERT_TRUE(Address::validate(AddressString, NetworkVersion)); +} + +/**/ + +TEST(identities, address_validate_bytes) { + ASSERT_TRUE(Address::validate(TestAddressBytes, NetworkVersion)); +} + +/**/ + +TEST(identities, address_invalid) { + const auto invalidAddressStr = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyi"; + Address address(invalidAddressStr); + ASSERT_FALSE(Address::validate(address, NetworkVersion)); } diff --git a/test/identities/privatekey.cpp b/test/identities/privatekey.cpp index 9243a34a..b7594c29 100644 --- a/test/identities/privatekey.cpp +++ b/test/identities/privatekey.cpp @@ -5,68 +5,67 @@ using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t testPrivateKeyBytes[32] = { + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t TestPrivateKeyBytes[32] = { 216, 131, 156, 36, 50, 191, 208, 166, 126, 241, 10, 128, 75, 169, 145, 234, 187, 161, 159, 21, 74, 61, 112, 121, - 23, 104, 29, 69, 130, 42, 87, 18 -}; -const uint8_t wifByte = 0xaa; - + 23, 104, 29, 69, 130, 42, 87, 18 + }; + const uint8_t WIFByte = 0xaa; + const auto PrivateKeyString = "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"; } // namespace TEST(identities, privatekey_construct_bytes) { - PrivateKey privateKey(testPrivateKeyBytes); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey(TestPrivateKeyBytes); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_construct_string) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey(PrivateKeyString); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_hex) { - PrivateKey privateKey = PrivateKey::fromHex("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey = PrivateKey::fromHex(PrivateKeyString); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_passphrase) { - PrivateKey privateKey = PrivateKey::fromPassphrase(passphrase); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey = PrivateKey::fromPassphrase(Passphrase); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_string) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey(PrivateKeyString); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_from_wif_string) { const char* wifStr = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"; - PrivateKey privateKey = PrivateKey::fromWIFString(wifStr, wifByte); - ASSERT_STREQ("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", privateKey.toString().c_str()); + PrivateKey privateKey = PrivateKey::fromWIFString(wifStr, WIFByte); + ASSERT_STREQ(PrivateKeyString, privateKey.toString().c_str()); } TEST(identities, privatekey_get_bytes) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); + PrivateKey privateKey(PrivateKeyString); const auto privateKeyBytes = privateKey.toBytes(); for (unsigned int i = 0; i < PRIVATEKEY_SIZE; i++) { - ASSERT_EQ(privateKeyBytes[i], testPrivateKeyBytes[i]); + ASSERT_EQ(privateKeyBytes[i], TestPrivateKeyBytes[i]); }; } TEST(identities, privatekey_validate) { - PrivateKey privateKey("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712"); + PrivateKey privateKey(PrivateKeyString); ASSERT_TRUE(PrivateKey::validate(privateKey)); } TEST(identities, privatekey_validate_bytes) { - ASSERT_TRUE(PrivateKey::validate(testPrivateKeyBytes)); + ASSERT_TRUE(PrivateKey::validate(TestPrivateKeyBytes)); } TEST(identities, privatekey_validate_string) { - ASSERT_TRUE(PrivateKey::validate("d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712")); + ASSERT_TRUE(PrivateKey::validate(PrivateKeyString)); } diff --git a/test/identities/publickey.cpp b/test/identities/publickey.cpp index 5e9cfdc8..098833f3 100644 --- a/test/identities/publickey.cpp +++ b/test/identities/publickey.cpp @@ -5,57 +5,73 @@ using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t testPublicKeyBytes[33] = { - 3, - 65, 81, 163, 236, 70, 181, 103, 10, - 104, 43, 10, 99, 57, 79, 134, 53, - 135, 209, 188, 151, 72, 59, 27, 108, - 112, 235, 88, 231, 240, 174, 209, 146 -}; - + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t TestPublicKeyBytes[33] = { + 3, + 65, 81, 163, 236, 70, 181, 103, 10, + 104, 43, 10, 99, 57, 79, 134, 53, + 135, 209, 188, 151, 72, 59, 27, 108, + 112, 235, 88, 231, 240, 174, 209, 146 + }; + const auto PublicKeyString = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; } // namespace +/**/ + TEST(identities, publickey_from_bytes) { - PublicKey publicKey(testPublicKeyBytes); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey(TestPublicKeyBytes); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_from_hex) { - PublicKey publicKey = PublicKey::fromHex("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey = PublicKey::fromHex(PublicKeyString); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_from_passphrase) { - PublicKey publicKey = PublicKey::fromPassphrase(passphrase); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey = PublicKey::fromPassphrase(Passphrase); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_from_string) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", publicKey.toString().c_str()); + PublicKey publicKey(PublicKeyString); + ASSERT_STREQ(PublicKeyString, publicKey.toString().c_str()); } +/**/ + TEST(identities, publickey_get_bytes) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); + PublicKey publicKey(PublicKeyString); const auto publicKeyBytes = publicKey.toBytes(); for (unsigned int i = 0; i < COMPRESSED_PUBLICKEY_SIZE; i++) { - ASSERT_EQ(publicKeyBytes[i], testPublicKeyBytes[i]); + ASSERT_EQ(publicKeyBytes[i], TestPublicKeyBytes[i]); }; } +/**/ + TEST(identities, publickey_validate) { - PublicKey publicKey("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"); + PublicKey publicKey(PublicKeyString); ASSERT_TRUE(PublicKey::validate(publicKey)); + ASSERT_TRUE(publicKey.isValid()); } +/**/ + TEST(identities, publickey_validate_bytes) { - ASSERT_TRUE(PublicKey::validate(testPublicKeyBytes)); + ASSERT_TRUE(PublicKey::validate(TestPublicKeyBytes)); } +/**/ + TEST(identities, publickey_validate_string) { - ASSERT_TRUE(PublicKey::validate("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192")); + ASSERT_TRUE(PublicKey::validate(PublicKeyString)); } diff --git a/test/identities/wif.cpp b/test/identities/wif.cpp index 275acf2a..84678de5 100644 --- a/test/identities/wif.cpp +++ b/test/identities/wif.cpp @@ -5,39 +5,54 @@ using namespace Ark::Crypto::Identities; namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json -const auto passphrase = "this is a top secret passphrase"; -const uint8_t testWIFBytes[52] = { + // ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/identities/fixture.json + const auto Passphrase = "this is a top secret passphrase"; + const uint8_t TestWIFBytes[52] = { 83, 71, 113, 52, 120, 76, 103, 90, 75, 67, 71, 120, 115, 55, 98, 106, 109, 119, 110, 66, 114, 87, 99, 84, 52, 67, 49, 65, 68, 70, 69, 101, 114, 109, 106, 56, 52, 54, 75, 67, 57, 55, 70, 83, 118, 49, 87, 70, 68, 49, 100, 65 -}; -const uint8_t wifByte = 0xaa; - + }; + const uint8_t WIFByte = 0xaa; + const auto AddressString = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"; } // namespace +/**/ + TEST(identities, wif_from_bytes) { - WIF wif(testWIFBytes); - ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); + WIF wif(TestWIFBytes); + ASSERT_STREQ(AddressString, wif.toString().c_str()); } +/**/ + TEST(identities, wif_from_passphrase) { - WIF wif = WIF::fromPassphrase(passphrase, wifByte); - ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); + WIF wif = WIF::fromPassphrase(Passphrase, WIFByte); + ASSERT_STREQ(AddressString, wif.toString().c_str()); } +/**/ + TEST(identities, wif_from_string) { - WIF wif("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"); - ASSERT_STREQ("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA", wif.toString().c_str()); + WIF wif(AddressString); + ASSERT_STREQ(AddressString, wif.toString().c_str()); } +/**/ + TEST(identities, wif_get_bytes) { - WIF wif("SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA"); + WIF wif(AddressString); const auto wifBytes = wif.toBytes(); for (unsigned int i = 0; i < WIF_SIZE; i++) { - ASSERT_EQ(wifBytes[i], testWIFBytes[i]); + ASSERT_EQ(wifBytes[i], TestWIFBytes[i]); }; } + +/**/ + +TEST(identities, wif_invalid) { + const auto invalidWIFStr = "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1d"; + WIF wif(invalidWIFStr); + ASSERT_FALSE(WIF::validate(wif)); +} diff --git a/test/managers/fee_manager.cpp b/test/managers/fee_manager.cpp new file mode 100644 index 00000000..1f1920f6 --- /dev/null +++ b/test/managers/fee_manager.cpp @@ -0,0 +1,100 @@ + +#include "gtest/gtest.h" + +#include + +using namespace managers; + +namespace { +static const FeePolicy kDefaultFeePolicy = defaults::Fees::StaticFeePolicy(); +static const FeePolicy kCustomFeePolicy = { + 900000000ULL, 800000000ULL, 700000000ULL, 600000000ULL, 500000000ULL, + 400000000ULL, 300000000ULL, 200000000ULL, 100000000ULL, 0ULL +}; +static const FeeManager kDefaultFeeManager = FeeManager(); +static const FeeManager kCustomFeeManager = FeeManager(kCustomFeePolicy); +static const uint8_t kInPolicyBounds = 5; +static const uint8_t kOutOfPolicyBounds = 11; +static const uint64_t kAmountZero = 0ULL; +static const uint64_t kCustomFee = 1000000000ULL; +} //namespace + +/**/ + +TEST(managers, fee_manager_constructor_default) { + FeeManager feeManager; + bool isMatching = kDefaultFeeManager == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_constructor_fee_policy) { + FeeManager feeManager(kCustomFeePolicy); + bool isMatching = kCustomFeeManager == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_fee_get_in_bounds) { + FeeManager feeManager; + ASSERT_EQ(kDefaultFeePolicy[kInPolicyBounds], + feeManager.getFee(kInPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_fee_get_out_of_bounds) { + FeeManager feeManager; + ASSERT_EQ(kAmountZero, feeManager.getFee(kOutOfPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_fee_set_in_bounds) { + FeeManager feeManager; + feeManager.setFee(kInPolicyBounds, kCustomFee); + ASSERT_EQ(kCustomFee, feeManager.getFee(kInPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_fee_set_out_of_bounds) { + FeeManager feeManager; + feeManager.setFee(kOutOfPolicyBounds, kCustomFee); + ASSERT_EQ(kCustomFee, feeManager.getFee(kOutOfPolicyBounds)); +} + +/**/ + +TEST(managers, fee_manager_policy_get) { + FeeManager feeManager; + bool isMatching = kDefaultFeePolicy == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_policy_set) { + FeeManager feeManager; + feeManager.setPolicy(kCustomFeePolicy); + bool isMatching = kCustomFeePolicy == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_comparison_equals) { + FeeManager feeManager; + bool isMatching = kDefaultFeePolicy == feeManager.getPolicy(); + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, fee_manager_comparison_not_equal) { + FeeManager feeManager(kCustomFeePolicy); + bool notMatching = kDefaultFeePolicy != feeManager.getPolicy(); + ASSERT_TRUE(notMatching); +} diff --git a/test/managers/network_manager.cpp b/test/managers/network_manager.cpp new file mode 100644 index 00000000..4e1ac0f6 --- /dev/null +++ b/test/managers/network_manager.cpp @@ -0,0 +1,67 @@ + +#include "gtest/gtest.h" + +#include + +using namespace managers; + +namespace { // NOLINT +static const Network kDefaultNetwork = Networks::Devnet(); +static const Network kCustomNetwork { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" +}; +/**/ +static const NetworkManager kDefaultNetworkManager = NetworkManager(); +static const NetworkManager kCustomNetworkManager = NetworkManager(kCustomNetwork); +} //namespace + +/**/ + +TEST(managers, network_manager_constructor_default) { + NetworkManager networkManager; + bool isMatching = kDefaultNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_network_constructor) { + NetworkManager networkManager(kCustomNetwork); + bool isMatching = kCustomNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_get) { + NetworkManager networkManager; + bool isMatching = kDefaultNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_set) { + NetworkManager networkManager; + networkManager.setNetwork(kCustomNetwork); + bool isMatching = kCustomNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_comparison_equals) { + NetworkManager networkManager; + bool isMatching = kDefaultNetworkManager == networkManager; + ASSERT_TRUE(isMatching); +} + +/**/ + +TEST(managers, network_manager_comparison_not_equal) { + NetworkManager networkManager(kCustomNetwork); + bool notMatching = kDefaultNetworkManager != networkManager; + ASSERT_TRUE(notMatching); +} \ No newline at end of file diff --git a/test/networks/abstractnetwork.cpp b/test/networks/abstractnetwork.cpp deleted file mode 100644 index 42a2ef4b..00000000 --- a/test/networks/abstractnetwork.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include "gtest/gtest.h" - -#include "networks/abstractnetwork.h" -using namespace Ark::Crypto::Networks; - -#include - -AbstractNetwork CUSTOM_NETWORK = { - { - 0x01, // BASE58_ADDRESS_P2PKH - 0x02, // BASE58_ADDRESS_P2SH - 0x03 // BASE58_WIF - }, - { - 00010100, // BIP32_PREFIX_XPUB - 00010101 // BIP32_PREFIX_XPRV - }, - "0000-00-00T00:00:00.000Z", // Epoch - false // isLocked -}; - -TEST(networks, abstract_network_base58_prefix_get) { - ASSERT_EQ(1, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(2, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(3, CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF)); -} - -TEST(networks, abstract_network_base58_prefix_set) { - CUSTOM_NETWORK.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x10); - ASSERT_EQ(0x10, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - - CUSTOM_NETWORK.setBase58Prefix(BASE58_ADDRESS_P2SH, 0x20); - ASSERT_EQ(0x20, CUSTOM_NETWORK.getBase58Prefix(BASE58_ADDRESS_P2SH)); - - CUSTOM_NETWORK.setBase58Prefix(BASE58_WIF, 0x30); - ASSERT_EQ(0x30, CUSTOM_NETWORK.getBase58Prefix(BASE58_WIF)); -} - -TEST(networks, abstract_network_bip32_prefix_get) { - ASSERT_EQ(00010100, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(00010101, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -TEST(networks, abstract_network_bip32_prefix_set) { - CUSTOM_NETWORK.setBIP32Prefix(BIP32_PREFIX_XPUB, 1000000); - ASSERT_EQ(1000000, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPUB)); - - CUSTOM_NETWORK.setBIP32Prefix(BIP32_PREFIX_XPRV, 1000001); - ASSERT_EQ(1000001, CUSTOM_NETWORK.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -TEST(networks, abstract_network_epoch) { - ASSERT_STREQ("0000-00-00T00:00:00.000Z", CUSTOM_NETWORK.epoch()); -} - -TEST(networks, abstract_network_is_locked) { - ASSERT_EQ(false, CUSTOM_NETWORK.isLocked()); -} - -TEST(networks, abstract_network_version) { - AbstractNetwork customNetwork = CUSTOM_NETWORK; - customNetwork.setBase58Prefix(BASE58_ADDRESS_P2PKH, 0x14); - ASSERT_EQ(20, customNetwork.version()); -} diff --git a/test/networks/devnet.cpp b/test/networks/devnet.cpp index f02bdc49..d65d332f 100644 --- a/test/networks/devnet.cpp +++ b/test/networks/devnet.cpp @@ -1,27 +1,19 @@ -#include "gtest/gtest.h" - -#include "networks/devnet.h" -using namespace Ark::Crypto::Networks; -TEST(networks, devnet_base58_prefix_get) { - ASSERT_EQ(0x1E, Devnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, Devnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xaa, Devnet.getBase58Prefix(BASE58_WIF)); -} - -TEST(networks, devnet_bip32_prefix_get) { - ASSERT_EQ(46090600, Devnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(46089520, Devnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -TEST(networks, devnet_epoch) { - ASSERT_STREQ("2017-03-21T13:00:00.000Z", Devnet.epoch()); -} +#include "gtest/gtest.h" +#include -TEST(networks, devnet_is_locked) { - ASSERT_EQ(true, Devnet.isLocked()); -} +namespace { // NOLINT + static const std::string Nethash = "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867"; + static const uint8_t Slip44 = 1; + static const uint8_t Wif = 0xaa; + static const uint8_t Version = 0x1E; + static const std::string Epoch = "2017-03-21T13:00:00.000Z"; +}; // namespace -TEST(networks, devnet_version) { - ASSERT_EQ(30, Devnet.version()); +TEST(networks, devnet) { + ASSERT_STREQ(Nethash.c_str(), Networks::Devnet().nethash().c_str()); + ASSERT_EQ(Slip44, Networks::Devnet().slip44()); + ASSERT_EQ(Wif, Networks::Devnet().wif()); + ASSERT_EQ(Version, Networks::Devnet().version()); + ASSERT_STREQ(Epoch.c_str(), Networks::Devnet().epoch().c_str()); } diff --git a/test/networks/mainnet.cpp b/test/networks/mainnet.cpp index 36acb4f1..91795a64 100644 --- a/test/networks/mainnet.cpp +++ b/test/networks/mainnet.cpp @@ -1,27 +1,19 @@ -#include "gtest/gtest.h" - -#include "networks/mainnet.h" -using namespace Ark::Crypto::Networks; -TEST(networks, mainnet_base58_prefix_get) { - ASSERT_EQ(0x17, Mainnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, Mainnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xaa, Mainnet.getBase58Prefix(BASE58_WIF)); -} - -TEST(networks, mainnet_bip32_prefix_get) { - ASSERT_EQ(46090600, Mainnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(46089520, Mainnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -TEST(networks, mainnet_epoch) { - ASSERT_STREQ("2017-03-21T13:00:00.000Z", Mainnet.epoch()); -} +#include "gtest/gtest.h" +#include -TEST(networks, mainnet_is_locked) { - ASSERT_EQ(true, Mainnet.isLocked()); -} +namespace { // NOLINT + static const std::string Nethash = "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988"; + static const uint8_t Slip44 = 111; + static const uint8_t Wif = 0xaa; + static const uint8_t Version = 0x17; + static const std::string Epoch = "2017-03-21T13:00:00.000Z"; +}; // namespace -TEST(networks, mainnet_version) { - ASSERT_EQ(23, Mainnet.version()); +TEST(networks, mainnet) { + ASSERT_STREQ(Nethash.c_str(), Networks::Mainnet().nethash().c_str()); + ASSERT_EQ(Slip44, Networks::Mainnet().slip44()); + ASSERT_EQ(Wif, Networks::Mainnet().wif()); + ASSERT_EQ(Version, Networks::Mainnet().version()); + ASSERT_STREQ(Epoch.c_str(), Networks::Mainnet().epoch().c_str()); } diff --git a/test/networks/testnet.cpp b/test/networks/testnet.cpp index 2a56c867..d4212951 100644 --- a/test/networks/testnet.cpp +++ b/test/networks/testnet.cpp @@ -1,27 +1,19 @@ -#include "gtest/gtest.h" - -#include "networks/testnet.h" -using namespace Ark::Crypto::Networks; -TEST(networks, testnet_base58_prefix_get) { - ASSERT_EQ(0x17, Testnet.getBase58Prefix(BASE58_ADDRESS_P2PKH)); - ASSERT_EQ(0x00, Testnet.getBase58Prefix(BASE58_ADDRESS_P2SH)); - ASSERT_EQ(0xba, Testnet.getBase58Prefix(BASE58_WIF)); -} - -TEST(networks, testnet_bip32_prefix_get) { - ASSERT_EQ(70617039, Testnet.getBIP32Prefix(BIP32_PREFIX_XPUB)); - ASSERT_EQ(70615956, Testnet.getBIP32Prefix(BIP32_PREFIX_XPRV)); -} - -TEST(networks, testnet_epoch) { - ASSERT_STREQ("2017-03-21T13:00:00.000Z", Testnet.epoch()); -} +#include "gtest/gtest.h" +#include -TEST(networks, testnet_is_locked) { - ASSERT_EQ(true, Testnet.isLocked()); -} +namespace { // NOLINT + static const std::string Nethash = "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192"; + static const uint8_t Slip44 = 1; + static const uint8_t Wif = 0xba; + static const uint8_t Version = 0x17; + static const std::string Epoch = "2017-03-21T13:00:00.000Z"; +}; // namespace -TEST(networks, testnet_version) { - ASSERT_EQ(23, Testnet.version()); +TEST(networks, testnet) { + ASSERT_STREQ(Nethash.c_str(), Networks::Testnet().nethash().c_str()); + ASSERT_EQ(Slip44, Networks::Testnet().slip44()); + ASSERT_EQ(Wif, Networks::Testnet().wif()); + ASSERT_EQ(Version, Networks::Testnet().version()); + ASSERT_STREQ(Epoch.c_str(), Networks::Testnet().epoch().c_str()); } diff --git a/test/platformio.ini b/test/platformio.ini index bbdd161c..a8bfa36d 100644 --- a/test/platformio.ini +++ b/test/platformio.ini @@ -11,13 +11,13 @@ [platformio] description = "Unit Tests for Ark-Cpp-Crypto" src_dir = .. -lib_dir = .. +build_dir = .pio/.pioenvs +libdeps_dir = .pio/.piolibdeps [common] -lib_ldf_mode = off lib_deps = micro-ecc, AUnit, ArduinoJson@6.10.0, BIP66 -build_flags = -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST -src_filter = +<*> -<.git/> - - - - -<_3rdParty> - - - - - - - - +build_flags = -I../test -I../test/iot/ -I../src -I../src/lib -I../src/include/cpp-crypto -DUNIT_TEST +src_filter = + + - upload_speed = 921600 # esp8266 unit tests disabled until support is worked out @@ -25,7 +25,6 @@ upload_speed = 921600 #platform = espressif8266 #board = huzzah #framework = arduino -#lib_ldf_mode = ${common.lib_ldf_mode} #lib_deps = ${common.lib_deps} #build_flags = ${common.build_flags} #src_filter = ${common.src_filter} @@ -35,7 +34,6 @@ upload_speed = 921600 platform = espressif32 board = esp32dev framework = arduino -lib_ldf_mode = ${common.lib_ldf_mode} lib_deps = ${common.lib_deps} build_flags = ${common.build_flags} src_filter = ${common.src_filter} diff --git a/test/transactions/builder.cpp b/test/transactions/builder.cpp index 034f8bfe..7e1512e5 100644 --- a/test/transactions/builder.cpp +++ b/test/transactions/builder.cpp @@ -1,26 +1,62 @@ + #include "gtest/gtest.h" -#include "configuration/fee.h" -#include "enums/types.h" -#include "transactions/builder.h" -using namespace Ark::Crypto::Transactions; +#include TEST(transactions, build_transfer) { - const auto actual = Ark::Crypto::Transactions::Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 100000000, - "", "Secret passphrase"); - ASSERT_EQ(Ark::Crypto::Enums::Types::TRANSFER, actual.type); - ASSERT_TRUE(Ark::Crypto::Configuration::Fee().get(Ark::Crypto::Enums::Types::TRANSFER) == actual.fee); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); - ASSERT_TRUE(100000000 == actual.amount); - ASSERT_STREQ("", actual.vendorField.c_str()); + const auto actual = + Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "", + "Secret passphrase"); + + ASSERT_EQ(0, actual.type); + ASSERT_EQ(defaults::Fees::StaticFeePolicy()[actual.type], actual.fee); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + actual.recipient.c_str()); + ASSERT_EQ(100000000ULL, actual.amount); + ASSERT_TRUE(actual.vendorField.empty()); +} + +/**/ + +TEST(transactions, build_transfer_custom_network) { + static const Network MyCustomNetwork = { + "16c891512149d6d3ff1b70e65900936140bf853a4ae79b5515157981dcc706df", + 1, 0x53, 0xaa, + "2019-04-12T13:00:00.000Z" + }; + + const Configuration myCustomConfiguration(MyCustomNetwork); + const auto transaction = Builder::buildTransfer( + "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 100000000ULL, + "this is a custom bridgechain transaction", + "this is a top secret passphrase", + "this is a top secret passphrase too", + myCustomConfiguration); + + ASSERT_EQ(0, transaction.type); + ASSERT_EQ(myCustomConfiguration.getFee(transaction.type), transaction.fee); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + transaction.recipient.c_str()); + ASSERT_EQ(100000000ULL, transaction.amount); + ASSERT_STREQ("this is a custom bridgechain transaction", + transaction.vendorField.c_str()); +} + +/**/ + +TEST(transactions, build_empty_transaction) { // test 0 ARKtoshi value const auto shouldBeEmpty = Ark::Crypto::Transactions::Builder::buildTransfer( "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 0, "", "Secret passphrase"); - ASSERT_STREQ("", shouldBeEmpty.recipientId.c_str()); - ASSERT_EQ(0, shouldBeEmpty.amount); + + ASSERT_TRUE(shouldBeEmpty.recipient.empty()); + ASSERT_EQ(0ULL, shouldBeEmpty.amount); ASSERT_FALSE(shouldBeEmpty.verify()); } diff --git a/test/transactions/deserializer.cpp b/test/transactions/deserializer.cpp index 88cbad91..dc8e6b77 100644 --- a/test/transactions/deserializer.cpp +++ b/test/transactions/deserializer.cpp @@ -1,131 +1,154 @@ + #include "gtest/gtest.h" -#include "enums/types.h" -#include "identities/address.h" -#include "identities/publickey.h" -#include "transactions/deserializer.h" +#include -TEST(transactions, deserialize_transfer) { +TEST(transactions, deserialize_transfer) { // NOLINT // transfer/passphrase-with-vendor-field.json Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f20" - "576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067bbfc8" - "fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"); + "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f" + "20576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067b" + "bfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::TRANSFER, actual.type); - ASSERT_EQ(41443847, actual.timestamp); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(10000000 == actual.fee); + ASSERT_EQ(defaults::TransactionTypes::Transfer, actual.type); + ASSERT_EQ(41443847UL, actual.timestamp); + ASSERT_STREQ( + "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + actual.senderPublicKey.c_str()); + ASSERT_TRUE(10000000ULL == actual.fee); ASSERT_STREQ("48656c6c6f20576f726c64", actual.vendorFieldHex.c_str()); ASSERT_STREQ("Hello World", actual.vendorField.c_str()); - ASSERT_TRUE(200000000 == actual.amount); - ASSERT_STREQ("ecf558fbddd62ae42edcfcba02f402d987a94b72a7636ef1121e8625487e2a1e", actual.id.c_str()); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); + ASSERT_TRUE(200000000ULL == actual.amount); + ASSERT_STREQ( + "ecf558fbddd62ae42edcfcba02f402d987a94b72a7636ef1121e8625487e2a1e", + actual.id.c_str()); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipient.c_str()); ASSERT_STREQ( - "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500ad" - "db830c79f49b9de484ec616bb1e1", + "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", actual.signature.c_str()); ASSERT_TRUE(actual.verify()); } -TEST(transactions, deserialize_second_signature_registration) { +/**/ + +TEST(transactions, deserialize_second_signature_registration) { // NOLINT // second_signature_registration/second-passphrase.json Ark::Crypto::Transactions::Deserializer deserializer( - "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003699e966b25" - "25f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf0" - "2c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"); + "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003" + "699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7" + "c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::SECOND_SIGNATURE_REGISTRATION, actual.type); - ASSERT_EQ(41271867, actual.timestamp); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(500000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); + ASSERT_EQ(defaults::TransactionTypes::SecondSignatureRegistration, actual.type); + ASSERT_EQ(41271867UL, actual.timestamp); + ASSERT_STREQ( + "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + actual.senderPublicKey.c_str()); + ASSERT_TRUE(500000000ULL == actual.fee); + ASSERT_TRUE(0UL == actual.amount); ASSERT_EQ(0, actual.expiration); - ASSERT_STREQ("6d1615924d172d352c8f44d4ded84cbbece3c03ebb3e4fc3f3334784ae332590", actual.id.c_str()); - ASSERT_STREQ("03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609", - actual.asset.signature.publicKey.c_str()); ASSERT_STREQ( - "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb46" - "10cdeca3b9e20d6c8773f869831c", + "6d1615924d172d352c8f44d4ded84cbbece3c03ebb3e4fc3f3334784ae332590", + actual.id.c_str()); + ASSERT_STREQ( + "03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609", + actual.asset.signature.publicKey.c_str()); + ASSERT_STREQ( + "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", actual.signature.c_str()); ASSERT_TRUE(actual.verify()); - // special case as the type 1 transaction itself has no recipientId + // special case as the type 1 transaction itself has no recipient const auto publicKey = Ark::Crypto::Identities::PublicKey::fromHex(actual.senderPublicKey.c_str()); const auto address = Ark::Crypto::Identities::Address::fromPublicKey(publicKey, actual.network); - ASSERT_STREQ(address.toString().c_str(), actual.recipientId.c_str()); + ASSERT_STREQ(address.toString().c_str(), actual.recipient.c_str()); } +/**/ + #if 0 -TEST(transactions, deserialize_delegate_registration) -{ - // delegate_registration/second-passphrase.json - Ark::Crypto::Transactions::Deserializer deserializer("ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f90295000000000009626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c"); - auto actual = deserializer.deserialize(); - - ASSERT_EQ(0xFF, actual.header); - ASSERT_EQ(1, actual.version); - ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::DELEGATE_REGISTRATION, actual.type); - ASSERT_EQ(41269424, actual.timestamp); - ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(2500000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); - ASSERT_EQ(0, actual.expiration); - ASSERT_STREQ("bf7e018ff9c0066f7a9f51e95d3f78c08cad5dd8581325d630d64350181a91bb", actual.id.c_str()); - ASSERT_STREQ("boldninja", actual.asset.delegate.username.c_str()); - ASSERT_STREQ("3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94", actual.signature.c_str()); - ASSERT_STREQ("304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", actual.secondSignature.c_str()); - ASSERT_TRUE(actual.verify()); +TEST(transactions, deserialize_delegate_registration) { // NOLINT + // delegate_registration/second-passphrase.json + Ark::Crypto::Transactions::Deserializer deserializer( + "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f902950000000000" + "09626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d022005" + "3b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947" + "867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c" + ); + auto actual = deserializer.deserialize(); + + ASSERT_EQ(0xFF, actual.header); + ASSERT_EQ(2, actual.type); + ASSERT_EQ(1, actual.version); + ASSERT_EQ(30, actual.network); + ASSERT_EQ(defaults::TransactionTypes::DelegateRegistration, actual.type); + ASSERT_EQ(41269424UL, actual.timestamp); + ASSERT_STREQ( + "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + actual.senderPublicKey.c_str()); + ASSERT_EQ(2500000000ULL, actual.fee); + ASSERT_EQ(0ULL, actual.amount); + ASSERT_EQ(0, actual.expiration); + ASSERT_STREQ( + "bf7e018ff9c0066f7a9f51e95d3f78c08cad5dd8581325d630d64350181a91bb", + actual.id.c_str()); + ASSERT_STREQ("boldninja", actual.asset.delegate.username.c_str()); + ASSERT_STREQ( + "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94", + actual.signature.c_str()); + ASSERT_STREQ( + "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", + actual.secondSignature.c_str()); + ASSERT_TRUE(actual.verify())); } #endif -TEST(transactions, deserialize_vote) { +/**/ + +TEST(transactions, deserialize_vote) { // NOLINT // vote/second-passphrase.json Ark::Crypto::Transactions::Deserializer deserializer( "ff011e0376b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f50500000000000101022cca95" "29ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7e" "c1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068304402201329882762a42d1af9" - "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda" - "66"); + "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(30, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::VOTE, actual.type); - ASSERT_EQ(41269366, actual.timestamp); + ASSERT_EQ(defaults::TransactionTypes::Vote, actual.type); + ASSERT_EQ(41269366UL, actual.timestamp); ASSERT_STREQ("034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", actual.senderPublicKey.c_str()); - ASSERT_TRUE(100000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); + ASSERT_TRUE(100000000ULL == actual.fee); + ASSERT_TRUE(0ULL == actual.amount); ASSERT_EQ(0, actual.expiration); ASSERT_STREQ("16f28a180cd6f3ea46c10f358a457989e956e9d355258230d0c7b07acec10b73", actual.id.c_str()); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipientId.c_str()); + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", actual.recipient.c_str()); std::vector votes = {std::string("+022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d")}; ASSERT_EQ(1, actual.asset.votes.size()); ASSERT_STREQ(votes[0].c_str(), actual.asset.votes[0].c_str()); ASSERT_STREQ( - "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0" - "d5828ed2d7c53a5e8db08cb6d068", + "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068", actual.signature.c_str()); ASSERT_STREQ( - "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353e" - "d7881dc29787a5e8ecbee2dfda66", + "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66", actual.secondSignature.c_str()); ASSERT_TRUE(actual.verify()); } -TEST(transactions, deserialize_multi_signature_registration) { +/**/ + +TEST(transactions, deserialize_multi_signature_registration) { // NOLINT // multi_signature_registration/passphrase.json Ark::Crypto::Transactions::Deserializer deserializer( "ff011704724c9a00036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d76000943577000000000002031803543c" @@ -136,23 +159,24 @@ TEST(transactions, deserialize_multi_signature_registration) { "697c711f91e8c03b9620e0b1ff304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710" "897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5d" "df07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb304402207e660489bced5ce80c33" - "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913" - "d"); + "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d"); auto actual = deserializer.deserialize(); ASSERT_EQ(0xFF, actual.header); ASSERT_EQ(1, actual.version); ASSERT_EQ(23, actual.network); - ASSERT_EQ(Ark::Crypto::Enums::Types::MULTI_SIGNATURE_REGISTRATION, actual.type); - ASSERT_EQ(10112114, actual.timestamp); + ASSERT_EQ(defaults::TransactionTypes::MultiSignatureRegistration, actual.type); + ASSERT_EQ(10112114UL, actual.timestamp); ASSERT_STREQ("036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760", actual.senderPublicKey.c_str()); - ASSERT_TRUE(2000000000 == actual.fee); - ASSERT_TRUE(0 == actual.amount); + ASSERT_TRUE(2000000000ULL == actual.fee); + ASSERT_TRUE(0ULL == actual.amount); ASSERT_EQ(0, actual.expiration); - std::vector keysgroup = {"+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", - "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", - "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31"}; + std::vector keysgroup = { + "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", + "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", + "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" + }; ASSERT_EQ(3, actual.asset.multiSignature.keysgroup.size()); ASSERT_EQ(2, actual.asset.multiSignature.min); @@ -160,26 +184,21 @@ TEST(transactions, deserialize_multi_signature_registration) { for (uint8_t i = 0; i < keysgroup.size(); i++) { ASSERT_STREQ(keysgroup[i].c_str(), actual.asset.multiSignature.keysgroup[i].c_str()); - } + }; ASSERT_STREQ("cbd6862966bb1b03ba742397b7e5a88d6eefb393a362ead0d605723b840db2af", actual.id.c_str()); ASSERT_STREQ( - "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93" - "753c82a711c3558045e787bc01a5", + "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a5", actual.signature.c_str()); ASSERT_STREQ( - "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488e" - "b89b697c711f91e8c03b9620e0b1", + "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1", actual.secondSignature.c_str()); std::vector signatures = { - "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4e" - "d1fa262097112cf5a1b3f7dade60e4", - "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2e" - "aaa4c6c7a555ef123c5e59fd41fb", - "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89" - "085c328817919939f2efeabd913d"}; + "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4", + "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb", + "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d"}; ASSERT_EQ(3, actual.signatures.size()); for (uint8_t i = 0; i < signatures.size(); i++) { @@ -188,8 +207,8 @@ TEST(transactions, deserialize_multi_signature_registration) { ASSERT_TRUE(actual.verify()); - // special case as the type 4 transaction itself has no recipientId + // special case as the type 4 transaction itself has no recipient const auto publicKey = Ark::Crypto::Identities::PublicKey::fromHex(actual.senderPublicKey.c_str()); const auto address = Ark::Crypto::Identities::Address::fromPublicKey(publicKey, actual.network); - ASSERT_STREQ(address.toString().c_str(), actual.recipientId.c_str()); + ASSERT_STREQ(address.toString().c_str(), actual.recipient.c_str()); } diff --git a/test/transactions/serializer.cpp b/test/transactions/serializer.cpp index a5b29cb1..1c457cb4 100644 --- a/test/transactions/serializer.cpp +++ b/test/transactions/serializer.cpp @@ -1,98 +1,93 @@ + #include "gtest/gtest.h" -#include "transactions/serializer.h" +#include -TEST(transactions, serialize_transfer) { +TEST(transactions, serialize_transfer) { // NOLINT // transfer/passphrase-with-vendor-field.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 0; - transaction.fee = 10000000; - transaction.amount = 200000000; - transaction.timestamp = 41443847; - transaction.recipientId = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; + transaction.fee = 10000000ULL; + transaction.amount = 200000000ULL; + transaction.timestamp = 41443847UL; + transaction.recipient = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; transaction.vendorField = "Hello World"; - transaction.signature = - "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500ad" - "db830c79f49b9de484ec616bb1e1"; + transaction.signature = "304402205616d6e361439d67a5c2067bbfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1"; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); ASSERT_STREQ( - "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f20" - "576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067bbfc8" - "fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", + "ff011e0007627802034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000b48656c6c6f" + "20576f726c6400c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402205616d6e361439d67a5c2067b" + "bfc8fce61b93061a4fa113315a1c5cf965ff6f3202200a1d99caaa98aeebcec04edd5365352500addb830c79f49b9de484ec616bb1e1", actual.c_str()); } -TEST(transactions, serialize_second_signature_registration) { +/**/ + +TEST(transactions, serialize_second_signature_registration) { // NOLINT // second_signature_registration/second-passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 1; - transaction.fee = 500000000; - transaction.timestamp = 41271867; + transaction.fee = 500000000ULL; + transaction.timestamp = 41271867UL; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = - "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb46" - "10cdeca3b9e20d6c8773f869831c"; + transaction.signature = "304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c"; transaction.asset.signature.publicKey = "03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609"; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); ASSERT_STREQ( - "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003699e966b25" - "25f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7c00ebb79223d5eaaeaf0" - "2c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", + "ff011e013bc27502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed1920065cd1d000000000003" + "699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609304402202aab49477dd3531e4473196d08fbd7" + "c00ebb79223d5eaaeaf02c52c4041a86cf02201a7d82655f9b1d22af3ea94e6f183649bb4610cdeca3b9e20d6c8773f869831c", actual.c_str()); } -TEST(transactions, serialize_delegate_registration) { +/**/ + +TEST(transactions, serialize_delegate_registration) { // NOLINT // delegate_registration/second-passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 2; - transaction.fee = 2500000000; - transaction.timestamp = 41269424; + transaction.fee = 2500000000ULL; + transaction.timestamp = 41269424UL; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = - "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7" - "e40958c7709aec0e1555087ea9ad94"; - transaction.secondSignature = - "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b34" - "5d48a9c2ae98be57dced869cf38c"; + transaction.signature = "3045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94"; + transaction.secondSignature = "304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c"; transaction.asset.delegate.username = "boldninja"; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); ASSERT_STREQ( - "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f90295000000000009626f6c646e" - "696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d0220053b06d22ed3e3ad6168c6b27a" - "a0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947867b439de3d28d38e58c844fd8c45b564302" - "200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", + "ff011e02b0b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200f902950000000000" + "09626f6c646e696e6a613045022100f21b742fa052cd18de43328e1d068539ba7cbe9d33a9dcbd862a82871383955d022005" + "3b06d22ed3e3ad6168c6b27aa0ec68e7e40958c7709aec0e1555087ea9ad94304402207da580da4feec955edcb8e8eb36947" + "867b439de3d28d38e58c844fd8c45b564302200e6741b6ad11c2588a57b3afd180df1e9b345d48a9c2ae98be57dced869cf38c", actual.c_str()); } -TEST(transactions, serialize_vote) { +/**/ + +TEST(transactions, serialize_vote) { // NOLINT // vote/second-passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 3; - transaction.fee = 100000000; - transaction.timestamp = 41269366; - transaction.recipientId = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; + transaction.fee = 100000000ULL; + transaction.timestamp = 41269366UL; + transaction.recipient = "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib"; transaction.senderPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; - transaction.signature = - "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0" - "d5828ed2d7c53a5e8db08cb6d068"; - transaction.secondSignature = - "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353e" - "d7881dc29787a5e8ecbee2dfda66"; - transaction.asset.votes = {"+022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d"}; + transaction.signature = "304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7ec1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068"; + transaction.secondSignature = "304402201329882762a42d1af9079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66"; + transaction.asset.votes = { "+022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d" }; Ark::Crypto::Transactions::Serializer serializer(transaction); std::string actual = serializer.serialize(); @@ -101,38 +96,35 @@ TEST(transactions, serialize_vote) { "ff011e0376b87502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19200e1f50500000000000101022cca95" "29ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d304402204b8bb403e2db7f9599d46d0f5d39f8bb1d0663d875af7e" "c1154448e98466e86302201e92fb57e13fb729b07e1027fa3d6e3f28e0d5828ed2d7c53a5e8db08cb6d068304402201329882762a42d1af9" - "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda" - "66", + "079c822a9e3feefa47b7476b0afe61440637408958a64402206da179b08e31d9c784fbb23abe2c9b50353ed7881dc29787a5e8ecbee2dfda66", actual.c_str()); } -TEST(transactions, serialize_multi_signature_registration) { +/**/ + +TEST(transactions, serialize_multi_signature_registration) { // NOLINT // multi_signature_registration/passphrase.json Ark::Crypto::Transactions::Transaction transaction; transaction.type = 4; transaction.version = 1; transaction.network = 23; - transaction.fee = 2000000000; - transaction.timestamp = 10112114; + transaction.fee = 2000000000ULL; + transaction.timestamp = 10112114UL; transaction.senderPublicKey = "036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760"; - transaction.signature = - "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93" - "753c82a711c3558045e787bc01a5"; - transaction.secondSignature = - "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488e" - "b89b697c711f91e8c03b9620e0b1"; + transaction.signature = "30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a5"; + transaction.secondSignature = "304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1"; transaction.signatures = { - "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4e" - "d1fa262097112cf5a1b3f7dade60e4", - "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2e" - "aaa4c6c7a555ef123c5e59fd41fb", - "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89" - "085c328817919939f2efeabd913d"}; - - transaction.asset.multiSignature.keysgroup = {"+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", - "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", - "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31"}; + "304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4", + "304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb", + "304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d" + }; + + transaction.asset.multiSignature.keysgroup = { + "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", + "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", + "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" + }; transaction.asset.multiSignature.lifetime = 24; transaction.asset.multiSignature.min = 2; @@ -148,7 +140,6 @@ TEST(transactions, serialize_multi_signature_registration) { "697c711f91e8c03b9620e0b1ff304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710" "897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5d" "df07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb304402207e660489bced5ce80c33" - "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913" - "d", + "d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d", actual.c_str()); } diff --git a/test/transactions/transaction.cpp b/test/transactions/transaction.cpp index 1870cdab..74901056 100644 --- a/test/transactions/transaction.cpp +++ b/test/transactions/transaction.cpp @@ -1,201 +1,374 @@ -#include "gtest/gtest.h" -#include "transactions/builder.h" -#include "helpers/json.h" +#include "gtest/gtest.h" #include #include -TEST(transactions, transaction_to_array) { - // Type 0 - auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 1, "", "Secret passphrase"); - std::map tArray = transfer.toArray(); - - // Amount - ASSERT_STREQ("1", tArray["amount"].c_str()); - // Fee - ASSERT_STREQ("10000000", tArray["fee"].c_str()); - // Id - ASSERT_STRNE("", tArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tArray["recipientId"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", tArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", tArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", tArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("0", tArray["type"].c_str()); - - - // Type 1 - auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration("Secret passphrase", "Second Secret passphrase"); - std::map ssArray = secondSignatureRegistration.toArray(); - - // Amount - ASSERT_STREQ("0", ssArray["amount"].c_str()); - // Asset - ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", ssArray["publicKey"].c_str()); - // Fee - ASSERT_STREQ("500000000", ssArray["fee"].c_str()); - // Id - ASSERT_STRNE("", ssArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("", ssArray["recipientId"].c_str()); - // SecondSignature - ASSERT_STRNE("", ssArray["secondSignature"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", ssArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", ssArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", ssArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("1", ssArray["type"].c_str()); - - - // Type 2 - auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration("testName", "Secret passphrase"); - std::map dArray = delegateRegistration.toArray(); - - // Amount - ASSERT_STREQ("0", dArray["amount"].c_str()); - // Asset - ASSERT_STREQ("testName", dArray["username"].c_str()); - // Fee - ASSERT_STREQ("2500000000", dArray["fee"].c_str()); - // Id - ASSERT_STRNE("", dArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("", dArray["recipientId"].c_str()); - // SecondSignature - ASSERT_STREQ("", dArray["secondSignature"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", dArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", dArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", dArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("2", dArray["type"].c_str()); - - - // Type 3 - std::vector votes = { "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" }; - auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); - std::map vArray = vote.toArray(); - - // Amount - ASSERT_STREQ("0", vArray["amount"].c_str()); - // Asset - ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6,+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vArray["votes"].c_str()); - // Fee - ASSERT_STREQ("100000000", vArray["fee"].c_str()); - // Id - ASSERT_STRNE("", vArray["id"].c_str()); - // RecipientId - ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vArray["recipientId"].c_str()); - // SecondSignature - ASSERT_STREQ("", vArray["secondSignature"].c_str()); - // SenderPublicKey - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", vArray["senderPublicKey"].c_str()); - // Signature - ASSERT_STRNE("", vArray["signature"].c_str()); - // Timestamp - ASSERT_STRNE("", vArray["timestamp"].c_str()); - // Type - ASSERT_STREQ("3", vArray["type"].c_str()); +#include + +#include "helpers/json.h" + +using namespace Ark::Crypto::Transactions; + +TEST(transactions, transaction_default) { + Transaction transaction; + ASSERT_FALSE(transaction.verify()); +}; + +/**/ + +TEST(transactions, transaction_to_array) { // NOLINT + // Type 0 // + auto transfer = Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 1, + "", + "Secret passphrase"); + + auto tArray = transfer.toArray(); + + // Amount + ASSERT_STREQ("1", tArray["amount"].c_str()); + + // Fee + ASSERT_STREQ("10000000", tArray["fee"].c_str()); + + // Id + ASSERT_FALSE(tArray["id"].empty()); + + // Recipient + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tArray["recipient"].c_str()); + + // SenderPublicKey + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + tArray["senderPublicKey"].c_str()); + + // Signature + ASSERT_FALSE(tArray["signature"].empty()); + + // Timestamp + ASSERT_FALSE(tArray["timestamp"].empty()); + + // Type + ASSERT_STREQ("0", tArray["type"].c_str()); + + // Type 1 // + auto secondSignatureRegistration = Builder::buildSecondSignatureRegistration( + "Secret passphrase", + "Second Secret passphrase"); + + auto ssArray = secondSignatureRegistration.toArray(); + + // Amount + ASSERT_STREQ("0", ssArray["amount"].c_str()); + + // Asset + ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", + ssArray["publicKey"].c_str()); + + // Fee + ASSERT_STREQ("500000000", ssArray["fee"].c_str()); + + // Id + ASSERT_FALSE(ssArray["id"].empty()); + + // Recipient + ASSERT_TRUE(ssArray["recipient"].empty()); + + // SecondSignature + ASSERT_FALSE(ssArray["secondSignature"].empty()); + + // SenderPublicKey + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + ssArray["senderPublicKey"].c_str()); + + // Signature + ASSERT_FALSE(ssArray["signature"].empty()); + + // Timestamp + ASSERT_FALSE(ssArray["timestamp"].empty()); + + // Type + ASSERT_STREQ("1", ssArray["type"].c_str()); + + // Type 2 // + auto delegateRegistration = Builder::buildDelegateRegistration( + "testName", + "Secret passphrase"); + + auto dArray = delegateRegistration.toArray(); + + // Amount + ASSERT_STREQ("0", dArray["amount"].c_str()); + + // Asset + ASSERT_STREQ("testName", dArray["username"].c_str()); + + // Fee + ASSERT_STREQ("2500000000", dArray["fee"].c_str()); + + // Id + ASSERT_FALSE(dArray["id"].empty()); + + // Recipient + ASSERT_TRUE(dArray["recipient"].empty()); + + // SecondSignature + ASSERT_TRUE(dArray["secondSignature"].empty()); + + // SenderPublicKey + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + dArray["senderPublicKey"].c_str()); + + // Signature + ASSERT_FALSE(dArray["signature"].empty()); + + // ASSERT_FALSE + ASSERT_FALSE(dArray["timestamp"].empty()); + + // Type + ASSERT_STREQ("2", dArray["type"].c_str()); + + // Type 3 // + std::vector votes = { + "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" + }; + + auto vote = Builder::buildVote(votes, "Secret passphrase"); + + auto vArray = vote.toArray(); + + // Amount + ASSERT_STREQ("0", vArray["amount"].c_str()); + + // Asset + ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6," + "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + vArray["votes"].c_str()); + + // Fee + ASSERT_STREQ("100000000", vArray["fee"].c_str()); + + // Id + ASSERT_FALSE(vArray["id"].empty()); + + // Recipient + ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", + vArray["recipient"].c_str()); + + // SecondSignature + ASSERT_TRUE(vArray["secondSignature"].empty()); + + // SenderPublicKey + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + vArray["senderPublicKey"].c_str()); + + // Signature + ASSERT_FALSE(vArray["signature"].empty()); + + // Timestamp + ASSERT_FALSE(vArray["timestamp"].empty()); + + // Type + ASSERT_STREQ("3", vArray["type"].c_str()); } -TEST(transactions, transaction_to_json) { - - // Type 0 - auto transfer = Ark::Crypto::Transactions::Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", 1, "", "Secret passphrase"); - std::string tJson = transfer.toJson(); - - const size_t tCapacity = JSON_OBJECT_SIZE(8) + 450; - DynamicJsonDocument tDoc(tCapacity); - - DeserializationError tError = deserializeJson(tDoc, tJson); - ASSERT_FALSE(tError); - - ASSERT_EQ(tDoc["amount"], 1); - ASSERT_EQ(tDoc["fee"], 10000000); - ASSERT_STRNE("", tDoc["id"].as()); - ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", tDoc["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", tDoc["senderPublicKey"].as()); - ASSERT_STRNE("", tDoc["signature"].as()); - ASSERT_GT(tDoc["timestamp"], 50000000); - ASSERT_LT(tDoc["timestamp"], 1000000000); - ASSERT_EQ(tDoc["type"], 0); - - - // Type 1 - auto secondSignatureRegistration = Ark::Crypto::Transactions::Builder::buildSecondSignatureRegistration("Secret passphrase", "Second Secret passphrase"); - std::string ssJson = secondSignatureRegistration.toJson(); - - const size_t ssCapacity = 2 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(10) + 690; - DynamicJsonDocument ssDoc(ssCapacity); - - DeserializationError ssError = deserializeJson(ssDoc, ssJson); - ASSERT_FALSE(ssError); - - ASSERT_EQ(ssDoc["amount"], 0); - ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", ssDoc["asset"]["signature"]["publicKey"].as()); - ASSERT_EQ(ssDoc["fee"], 500000000); - ASSERT_STRNE("", ssDoc["id"].as()); - ASSERT_STREQ("", ssDoc["recipientId"].as()); - ASSERT_STRNE("", ssDoc["secondSignature"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", ssDoc["senderPublicKey"].as()); - ASSERT_STRNE("", ssDoc["signature"].as()); - ASSERT_GT(ssDoc["timestamp"], 50000000); - ASSERT_LT(ssDoc["timestamp"], 1000000000); - ASSERT_EQ(ssDoc["type"], 1); - - - // Type 2 - auto delegateRegistration = Ark::Crypto::Transactions::Builder::buildDelegateRegistration("testName", "Secret passphrase"); - std::string dJson = delegateRegistration.toJson(); - - const size_t dCapacity = 2*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 450; - DynamicJsonDocument dDoc(dCapacity); - - DeserializationError dError = deserializeJson(dDoc, dJson); - ASSERT_FALSE(dError); - - ASSERT_EQ(dDoc["amount"], 0); - ASSERT_STREQ("testName", dDoc["asset"]["delegate"]["username"].as()); - ASSERT_EQ(dDoc["fee"], 2500000000); - ASSERT_STRNE("", dDoc["id"].as()); - ASSERT_STREQ("", dDoc["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", dDoc["senderPublicKey"].as()); - ASSERT_STRNE("", dDoc["signature"].as()); - ASSERT_GT(dDoc["timestamp"], 50000000); - ASSERT_LT(dDoc["timestamp"], 1000000000); - ASSERT_EQ(dDoc["type"], 2); - - - // Type 3 - std::vector votes = { "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6,+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" }; - auto vote = Ark::Crypto::Transactions::Builder::buildVote(votes, "Secret passphrase"); - std::string vJson = vote.toJson(); - - const size_t vCapacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 700; - DynamicJsonDocument vDoc(vCapacity); - - DeserializationError vError = deserializeJson(vDoc, vJson); - ASSERT_FALSE(vError); - - ASSERT_EQ(vDoc["amount"], 0); - ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vDoc["asset"]["votes"][0].as()); - ASSERT_STREQ("+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", vDoc["asset"]["votes"][1].as()); - ASSERT_EQ(vDoc["fee"], 100000000); - ASSERT_STRNE("", vDoc["id"].as()); - ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", vDoc["recipientId"].as()); - ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", vDoc["senderPublicKey"].as()); - ASSERT_STRNE("", vDoc["signature"].as()); - ASSERT_GT(vDoc["timestamp"], 50000000); - ASSERT_LT(vDoc["timestamp"], 1000000000); - ASSERT_EQ(vDoc["type"], 3); +/**/ + +TEST(transactions, transaction_to_json) { // NOLINT + // Type 0 // + auto transfer = Builder::buildTransfer("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + 1, + "", + "Secret passphrase"); + + auto tJson = transfer.toJson(); + + const size_t tCapacity = JSON_OBJECT_SIZE(8) + 450; + DynamicJsonDocument tDoc(tCapacity); + + DeserializationError tError = deserializeJson(tDoc, tJson); + ASSERT_FALSE(tError); + + ASSERT_STREQ("1", tDoc["amount"].as()); + + ASSERT_STREQ("10000000", tDoc["fee"].as()); + + ASSERT_FALSE(tDoc["id"].as().empty()); + + ASSERT_STREQ("D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + tDoc["recipient"].as()); + + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + tDoc["senderPublicKey"].as()); + + ASSERT_FALSE(tDoc["signature"].as().empty()); + + ASSERT_GT(tDoc["timestamp"].as(), 50000000UL); + + ASSERT_LT(tDoc["timestamp"].as(), 1000000000UL); + + ASSERT_EQ(tDoc["type"].as(), 0); + + // Type 1 // + auto secondSignatureRegistration = Builder::buildSecondSignatureRegistration( + "Secret passphrase", + "Second Secret passphrase"); + + auto ssJson = secondSignatureRegistration.toJson(); + + const size_t ssCapacity = 2 * JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(10) + 690; + DynamicJsonDocument ssDoc(ssCapacity); + + DeserializationError ssError = deserializeJson(ssDoc, ssJson); + ASSERT_FALSE(ssError); + + ASSERT_STREQ("0", ssDoc["amount"].as()); + + ASSERT_STREQ("02e1684d8990c0a5625aec85977fcf22204884bc08d45dbc71b2859e5fa4f45104", + ssDoc["asset"]["signature"]["publicKey"].as()); + + ASSERT_STREQ("500000000", ssDoc["fee"].as()); + + ASSERT_FALSE(ssDoc["id"].as().empty()); + + ASSERT_TRUE(ssDoc["recipient"].as().empty()); + + ASSERT_FALSE(ssDoc["secondSignature"].as().empty()); + + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + ssDoc["senderPublicKey"].as()); + + ASSERT_FALSE(ssDoc["signature"].as().empty()); + + ASSERT_GT(ssDoc["timestamp"].as(), 50000000UL); + ASSERT_LT(ssDoc["timestamp"].as(), 1000000000UL); + + ASSERT_EQ(ssDoc["type"].as(), 1); + + // Type 2 // + auto delegateRegistration = Builder::buildDelegateRegistration( + "testName", + "Secret passphrase"); + + auto dJson = delegateRegistration.toJson(); + + const size_t dCapacity = 2*JSON_OBJECT_SIZE(1) + JSON_OBJECT_SIZE(9) + 450; + DynamicJsonDocument dDoc(dCapacity); + + DeserializationError dError = deserializeJson(dDoc, dJson); + ASSERT_FALSE(dError); + + ASSERT_STREQ("0", dDoc["amount"].as()); + + ASSERT_STREQ("testName", + dDoc["asset"]["delegate"]["username"].as()); + + ASSERT_STREQ("2500000000", dDoc["fee"].as()); + + ASSERT_FALSE(dDoc["id"].as().empty()); + + ASSERT_TRUE(dDoc["recipient"].as().empty()); + + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + dDoc["senderPublicKey"].as()); + + ASSERT_FALSE(dDoc["signature"].as().empty()); + + ASSERT_GT(dDoc["timestamp"].as(), 50000000UL); + ASSERT_LT(dDoc["timestamp"].as(), 1000000000UL); + + ASSERT_EQ(dDoc["type"].as(), 2); + + // Type 3 // + std::vector votes = { + "-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6," + "+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6" + }; + + auto vote = Builder::buildVote(votes, "Secret passphrase"); + + auto vJson = vote.toJson(); + + const size_t vCapacity = JSON_ARRAY_SIZE(1) + + JSON_OBJECT_SIZE(1) + + JSON_OBJECT_SIZE(9) + + 700; + DynamicJsonDocument vDoc(vCapacity); + + DeserializationError vError = deserializeJson(vDoc, vJson); + ASSERT_FALSE(vError); + + ASSERT_STREQ("0", vDoc["amount"].as()); + + ASSERT_STREQ("-0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + vDoc["asset"]["votes"][0].as()); + + ASSERT_STREQ("+0250b742256f9321bd7d46f3ed9769b215a7c2fb02be951acf43bc51eb57ceadf6", + vDoc["asset"]["votes"][1].as()); + + ASSERT_STREQ("100000000", vDoc["fee"].as()); + + ASSERT_FALSE(vDoc["id"].as().empty()); + + ASSERT_STREQ("DPgZq5MK6rm5yVks9b7TrA22F8FwRvkCtF", + vDoc["recipient"].as()); + + ASSERT_STREQ("02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699", + vDoc["senderPublicKey"].as()); + + ASSERT_FALSE(vDoc["signature"].as().empty()); + + ASSERT_GT(vDoc["timestamp"].as(), 50000000UL); + ASSERT_LT(vDoc["timestamp"].as(), 1000000000UL); + + ASSERT_EQ(vDoc["type"].as(), 3); }; + +/**/ + +TEST(transactions, transaction_empty) { + Ark::Crypto::Transactions::Transaction transaction; + bool isValid = transaction.verify(); + ASSERT_FALSE(isValid); +} + +/**/ + +TEST(transactions, transaction_asset_signature) { // NOLINT + const auto publicKeyString = "02f21aca9b6d224ea86a1689f57910534af21c3cc9f80602fed252c13e275f0699"; + TransactionAsset asset; + asset.signature.publicKey = publicKeyString; + ASSERT_STREQ(asset.signature.publicKey.c_str(), publicKeyString); +} + +/**/ + +TEST(transactions, transaction_asset_delegate) { + const auto testUsername = "testUsername"; + TransactionAsset asset; + asset.delegate.username = "testUsername"; + ASSERT_STREQ(asset.delegate.username.c_str(), testUsername); +} + +/**/ + +TEST(transactions, transaction_asset_multisignature) { + const auto min = 2; + const auto lifetime = 24; + std::vector keysgroup = { + "+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8", + "+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc", + "+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31" + }; + + TransactionAsset asset; + asset.multiSignature.min = min; + asset.multiSignature.lifetime = lifetime; + asset.multiSignature.keysgroup = keysgroup; + ASSERT_EQ(asset.multiSignature.min, min); + ASSERT_EQ(asset.multiSignature.lifetime, lifetime); + ASSERT_TRUE(asset.multiSignature.keysgroup[0] == keysgroup[0]); + ASSERT_TRUE(asset.multiSignature.keysgroup[1] == keysgroup[1]); + ASSERT_TRUE(asset.multiSignature.keysgroup[2] == keysgroup[2]); +} diff --git a/test/utils/message.cpp b/test/utils/message.cpp index a538045c..45333523 100644 --- a/test/utils/message.cpp +++ b/test/utils/message.cpp @@ -6,51 +6,52 @@ #include namespace { // NOLINT - -// ARK Core test fixtures: -// https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/utils/message.test.ts -const auto text = "Hello World"; -const auto passphrase = "this is a top secret passphrase"; -const auto expectedSignature = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; -const auto expectedPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; -const auto expectedJsonString = "{\"publickey\":\"034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192\",\"signature\":\"304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8\",\"message\":\"Hello World\"}"; - + //ARK Core test fixtures: + // https://github.com/ARKEcosystem/core/blob/develop/__tests__/unit/crypto/utils/message.test.ts + const auto text = "Hello World"; + const auto passphrase = "this is a top secret passphrase"; + const auto expectedSignature = "304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8"; + const auto expectedPublicKey = "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192"; + const auto expectedJsonString = "{" + "\"publickey\":\"034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192\"," + "\"signature\":\"304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8\"," + "\"message\":\"Hello World\"" + "}"; } // namespace +/**/ + TEST(utils, message_sign) { Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - ASSERT_STREQ(expectedSignature, BytesToHex(message.signature).c_str()); ASSERT_TRUE(message.verify()); } +/**/ + TEST(utils, message_to_array) { Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - std::map messageArray = message.toArray(); - ASSERT_STREQ(expectedPublicKey, messageArray["publickey"].c_str()); ASSERT_STREQ(expectedSignature, messageArray["signature"].c_str()); ASSERT_STREQ(text, messageArray["message"].c_str()); } +/**/ + TEST(utils, message_to_json) { Ark::Crypto::Utils::Message message; - message.sign(text, passphrase); - ASSERT_STREQ(expectedJsonString, message.toJson().c_str()); } +/**/ + TEST(utils, message_verify) { PublicKey publicKey = PublicKey::fromHex(expectedPublicKey); std::vector signature = HexToBytes(expectedSignature); - Ark::Crypto::Utils::Message message(text, publicKey, signature); - ASSERT_TRUE(message.verify()); } diff --git a/test/utils/slot.cpp b/test/utils/slot.cpp index 80a46b41..aaf3679a 100644 --- a/test/utils/slot.cpp +++ b/test/utils/slot.cpp @@ -1,24 +1,26 @@ -#include "gtest/gtest.h" + #include "gtest/gtest.h" -#include "helpers/crypto_helpers.h" -#include "utils/slot.h" +#include "arkCrypto.h" TEST(utilities, slots_epoch) { - const auto devnet = Ark::Crypto::Networks::Devnet; - const auto arkEpoch = 1490101200ull; - ASSERT_EQ(arkEpoch, Ark::Crypto::Utils::Slot::epoch(devnet)); + const auto devnet = Networks::Devnet(); + const auto arkEpoch = 1490101200ULL; + ASSERT_EQ(arkEpoch, Slot::epoch(devnet)); } +/**/ + TEST(utilities, slots_time) { - const auto devnet = Ark::Crypto::Networks::Devnet; + const auto devnet = Networks::Devnet(); + // const auto mainnet = Networks::Mainnet; // 28 Jan 2019(in seconds) - Ark Epoch (seconds) - const auto testTime = (1548725761ull - 1490101200ull); - const auto slotTime = Ark::Crypto::Utils::Slot::time(devnet); + const auto testTime = (1548725761ULL - 1490101200ULL); + const auto slotTime = Slot::time(devnet); // test that slot-time is more recent than 'testTime', ASSERT_GT(slotTime , testTime); // also check that the 'slotTime' is not too large (e.g. from an overflow). - ASSERT_LT(slotTime, (testTime) + 315360000); // 315360000s = 10yrs + ASSERT_LT(slotTime, (testTime) + 315360000ULL); // 315360000s = 10yrs }