Browse Source

Merge branch 'master' into jl777

jl777
jl777 7 years ago
parent
commit
65281360a7
  1. 20
      CMakeLists.txt
  2. 19
      README.md
  3. 15
      cmake/DownloadProject.CMakeLists.cmake.in
  4. 182
      cmake/DownloadProject.cmake
  5. 17
      iguana/exchanges/CMakeLists.txt
  6. 7
      iguana/exchanges/LP_coins.c
  7. 10
      iguana/exchanges/LP_commands.c
  8. 337
      iguana/exchanges/LP_etomic.c
  9. 54
      iguana/exchanges/LP_etomic.h
  10. 5
      iguana/exchanges/LP_include.h
  11. 8
      iguana/exchanges/LP_nativeDEX.c
  12. 8
      iguana/exchanges/LP_portfolio.c
  13. 37
      iguana/exchanges/LP_remember.c
  14. 39
      iguana/exchanges/LP_swap.c
  15. 78
      iguana/exchanges/LP_transaction.c
  16. 26
      iguana/exchanges/LP_utxo.c
  17. 15
      iguana/exchanges/etomicswap/CMakeLists.txt
  18. 199
      iguana/exchanges/etomicswap/bob.c
  19. 312
      iguana/exchanges/etomicswap/etomiccurl.c
  20. 38
      iguana/exchanges/etomicswap/etomiccurl.h
  21. 437
      iguana/exchanges/etomicswap/etomiclib.cpp
  22. 69
      iguana/exchanges/etomicswap/etomiclib.h
  23. 2
      iguana/exchanges/install
  24. 6
      iguana/exchanges/splitfunds
  25. 1
      iguana/iguana_payments.c
  26. 31
      iguana/m_notary_testnet
  27. 2
      iguana/secp256k1/CMakeLists.txt
  28. 17
      iguana/secp256k1/src/secp256k1.c

20
CMakeLists.txt

@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5.1)
cmake_minimum_required(VERSION 3.9.6)
include("cmake/HunterGate.cmake")
HunterGate(
URL "https://github.com/ruslo/hunter/archive/v0.19.173.tar.gz"
@ -6,6 +6,24 @@ HunterGate(
LOCAL
)
project(SuperNET)
set(DEPS_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS Off)
include(cmake/DownloadProject.cmake)
# Download and install nanomsg at CMake configure time
download_project(PROJ nanomsg
GIT_REPOSITORY https://github.com/nanomsg/nanomsg.git
GIT_TAG 1.1.2
GIT_SHALLOW 1
GIT_PROGRESS 1
CMAKE_ARGS "-DNN_STATIC_LIB=ON -DNN_ENABLE_DOC=OFF -DNN_TESTS=OFF -DNN_TOOLS=OFF -DNN_ENABLE_NANOCAT=OFF -DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_PREFIX}"
UPDATE_DISCONNECTED 1
)
find_library(NANOMSG_LIBRARY NAMES nanomsg PATHS ${DEPS_INSTALL_PREFIX}/lib)
include_directories("${CMAKE_SOURCE_DIR}")
add_subdirectory(cpp-ethereum)
add_subdirectory(iguana/exchanges)

19
README.md

@ -257,13 +257,14 @@ Execute the OSX deploy script:
The iguana binary and its linked libraries are in ```$HOME/tmp/iguana```.
# Cmake build of marketmaker with linked etomic lib for ETH/ERC20 atomic swaps:
0. `make sure g++-7 ln to /usr/bin/g++`
1. `make sure g++-7 ln to /usr/bin/g++`
1. `cd ~/SuperNET`
2. `git checkout dev`
3. `git submodule update --init --recursive`
4. `mkdir build`
5. `cd build`
6. `cmake ..`
7. `cmake --build . --target marketmaker`
8. `cd build/iguana/exchanges`
9. `./marketmaker`
1. `git checkout dev`
1. `git submodule update --init --recursive`
1. `mkdir build`
1. `cd build`
1. `cmake ..`
1. `cmake --build . --target marketmaker-testnet` for Ropsten Ethereum testnet.
1. `cmake --build . --target marketmaker-mainnet` for Ethereum mainnet.
1. `cd build/iguana/exchanges`
1. `./marketmaker-testnet` or `./marketmaker-mainnet`

15
cmake/DownloadProject.CMakeLists.cmake.in

@ -0,0 +1,15 @@
# Distributed under the OSI-approved MIT License. See accompanying
# file LICENSE or https://github.com/Crascit/DownloadProject for details.
cmake_minimum_required(VERSION 2.8.2)
project(${DL_ARGS_PROJ}-download NONE)
include(ExternalProject)
ExternalProject_Add(${DL_ARGS_PROJ}-download
${DL_ARGS_UNPARSED_ARGUMENTS}
SOURCE_DIR "${DL_ARGS_SOURCE_DIR}"
BINARY_DIR "${DL_ARGS_BINARY_DIR}"
BUILD_COMMAND ""
TEST_COMMAND ""
)

182
cmake/DownloadProject.cmake

@ -0,0 +1,182 @@
# Distributed under the OSI-approved MIT License. See accompanying
# file LICENSE or https://github.com/Crascit/DownloadProject for details.
#
# MODULE: DownloadProject
#
# PROVIDES:
# download_project( PROJ projectName
# [PREFIX prefixDir]
# [DOWNLOAD_DIR downloadDir]
# [SOURCE_DIR srcDir]
# [BINARY_DIR binDir]
# [QUIET]
# ...
# )
#
# Provides the ability to download and unpack a tarball, zip file, git repository,
# etc. at configure time (i.e. when the cmake command is run). How the downloaded
# and unpacked contents are used is up to the caller, but the motivating case is
# to download source code which can then be included directly in the build with
# add_subdirectory() after the call to download_project(). Source and build
# directories are set up with this in mind.
#
# The PROJ argument is required. The projectName value will be used to construct
# the following variables upon exit (obviously replace projectName with its actual
# value):
#
# projectName_SOURCE_DIR
# projectName_BINARY_DIR
#
# The SOURCE_DIR and BINARY_DIR arguments are optional and would not typically
# need to be provided. They can be specified if you want the downloaded source
# and build directories to be located in a specific place. The contents of
# projectName_SOURCE_DIR and projectName_BINARY_DIR will be populated with the
# locations used whether you provide SOURCE_DIR/BINARY_DIR or not.
#
# The DOWNLOAD_DIR argument does not normally need to be set. It controls the
# location of the temporary CMake build used to perform the download.
#
# The PREFIX argument can be provided to change the base location of the default
# values of DOWNLOAD_DIR, SOURCE_DIR and BINARY_DIR. If all of those three arguments
# are provided, then PREFIX will have no effect. The default value for PREFIX is
# CMAKE_BINARY_DIR.
#
# The QUIET option can be given if you do not want to show the output associated
# with downloading the specified project.
#
# In addition to the above, any other options are passed through unmodified to
# ExternalProject_Add() to perform the actual download, patch and update steps.
# The following ExternalProject_Add() options are explicitly prohibited (they
# are reserved for use by the download_project() command):
#
# CONFIGURE_COMMAND
# BUILD_COMMAND
# INSTALL_COMMAND
# TEST_COMMAND
#
# Only those ExternalProject_Add() arguments which relate to downloading, patching
# and updating of the project sources are intended to be used. Also note that at
# least one set of download-related arguments are required.
#
# If using CMake 3.2 or later, the UPDATE_DISCONNECTED option can be used to
# prevent a check at the remote end for changes every time CMake is run
# after the first successful download. See the documentation of the ExternalProject
# module for more information. It is likely you will want to use this option if it
# is available to you. Note, however, that the ExternalProject implementation contains
# bugs which result in incorrect handling of the UPDATE_DISCONNECTED option when
# using the URL download method or when specifying a SOURCE_DIR with no download
# method. Fixes for these have been created, the last of which is scheduled for
# inclusion in CMake 3.8.0. Details can be found here:
#
# https://gitlab.kitware.com/cmake/cmake/commit/bdca68388bd57f8302d3c1d83d691034b7ffa70c
# https://gitlab.kitware.com/cmake/cmake/issues/16428
#
# If you experience build errors related to the update step, consider avoiding
# the use of UPDATE_DISCONNECTED.
#
# EXAMPLE USAGE:
#
# include(DownloadProject)
# download_project(PROJ googletest
# GIT_REPOSITORY https://github.com/google/googletest.git
# GIT_TAG master
# UPDATE_DISCONNECTED 1
# QUIET
# )
#
# add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
#
#========================================================================================
set(_DownloadProjectDir "${CMAKE_CURRENT_LIST_DIR}")
include(CMakeParseArguments)
function(download_project)
set(options QUIET)
set(oneValueArgs
PROJ
PREFIX
DOWNLOAD_DIR
SOURCE_DIR
BINARY_DIR
# Prevent the following from being passed through
CONFIGURE_COMMAND
BUILD_COMMAND
INSTALL_COMMAND
TEST_COMMAND
)
set(multiValueArgs "")
cmake_parse_arguments(DL_ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# Hide output if requested
if (DL_ARGS_QUIET)
set(OUTPUT_QUIET "OUTPUT_QUIET")
else()
unset(OUTPUT_QUIET)
message(STATUS "Downloading/updating ${DL_ARGS_PROJ}")
endif()
# Set up where we will put our temporary CMakeLists.txt file and also
# the base point below which the default source and binary dirs will be.
# The prefix must always be an absolute path.
if (NOT DL_ARGS_PREFIX)
set(DL_ARGS_PREFIX "${CMAKE_BINARY_DIR}")
else()
get_filename_component(DL_ARGS_PREFIX "${DL_ARGS_PREFIX}" ABSOLUTE
BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if (NOT DL_ARGS_DOWNLOAD_DIR)
set(DL_ARGS_DOWNLOAD_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-download")
endif()
# Ensure the caller can know where to find the source and build directories
if (NOT DL_ARGS_SOURCE_DIR)
set(DL_ARGS_SOURCE_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-src")
endif()
if (NOT DL_ARGS_BINARY_DIR)
set(DL_ARGS_BINARY_DIR "${DL_ARGS_PREFIX}/${DL_ARGS_PROJ}-build")
endif()
set(${DL_ARGS_PROJ}_SOURCE_DIR "${DL_ARGS_SOURCE_DIR}" PARENT_SCOPE)
set(${DL_ARGS_PROJ}_BINARY_DIR "${DL_ARGS_BINARY_DIR}" PARENT_SCOPE)
# The way that CLion manages multiple configurations, it causes a copy of
# the CMakeCache.txt to be copied across due to it not expecting there to
# be a project within a project. This causes the hard-coded paths in the
# cache to be copied and builds to fail. To mitigate this, we simply
# remove the cache if it exists before we configure the new project. It
# is safe to do so because it will be re-generated. Since this is only
# executed at the configure step, it should not cause additional builds or
# downloads.
file(REMOVE "${DL_ARGS_DOWNLOAD_DIR}/CMakeCache.txt")
# Create and build a separate CMake project to carry out the download.
# If we've already previously done these steps, they will not cause
# anything to be updated, so extra rebuilds of the project won't occur.
# Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
# has this set to something not findable on the PATH.
configure_file("${_DownloadProjectDir}/DownloadProject.CMakeLists.cmake.in"
"${DL_ARGS_DOWNLOAD_DIR}/CMakeLists.txt")
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}"
-D "CMAKE_MAKE_PROGRAM:FILE=${CMAKE_MAKE_PROGRAM}"
.
RESULT_VARIABLE result
${OUTPUT_QUIET}
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
)
if(result)
message(FATAL_ERROR "CMake step for ${DL_ARGS_PROJ} failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
${OUTPUT_QUIET}
WORKING_DIRECTORY "${DL_ARGS_DOWNLOAD_DIR}"
)
if(result)
message(FATAL_ERROR "Build step for ${DL_ARGS_PROJ} failed: ${result}")
endif()
endfunction()

17
iguana/exchanges/CMakeLists.txt

@ -1,7 +1,14 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_executable(marketmaker mm.c)
set(MM_SOURCES mm.c ../mini-gmp.c ../groestl.c ../segwit_addr.c ../keccak.c LP_etomic.c)
set(MM_LIBS ${NANOMSG_LIBRARY} curl pthread libcrypto777 libjpeg libsecp256k1)
add_executable(marketmaker-testnet ${MM_SOURCES})
add_executable(marketmaker-mainnet ${MM_SOURCES})
include_directories(../../crypto777)
target_sources(marketmaker PRIVATE ../mini-gmp.c)
target_sources(marketmaker PRIVATE ../groestl.c)
target_sources(marketmaker PRIVATE ../segwit_addr.c)
target_link_libraries(marketmaker PRIVATE nanomsg curl pthread m libcrypto777 libjpeg libsecp256k1 "-Wl,--allow-multiple-definition" etomiclib)
target_compile_definitions(marketmaker-testnet PRIVATE ETOMIC_TESTNET USE_STATIC_NANOMSG)
target_compile_definitions(marketmaker-mainnet PRIVATE USE_STATIC_NANOMSG)
if(UNIX)
target_link_libraries(marketmaker-testnet m)
target_link_libraries(marketmaker-mainnet m)
endif()
target_link_libraries(marketmaker-testnet ${MM_LIBS} etomiclib-testnet)
target_link_libraries(marketmaker-mainnet ${MM_LIBS} etomiclib-mainnet)

7
iguana/exchanges/LP_coins.c

@ -236,6 +236,13 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
jaddnum(item,"balance",dstr(balance));
jaddnum(item,"KMDvalue",dstr(LP_KMDvalue(coin,balance)));
}
#ifndef NOTETOMIC
else if (coin->etomic[0] != 0) {
balance = LP_etomic_get_balance(coin, coin->smartaddr);
jaddnum(item,"height",-1);
jaddnum(item,"balance",dstr(balance));
}
#endif
else
{
jaddnum(item,"height",-1);

10
iguana/exchanges/LP_commands.c

@ -118,7 +118,7 @@ inventory(coin, reset=0, [passphrase=])\n\
lastnonce()\n\
buy(base, rel, price, relvolume, timeout=10, duration=3600, nonce)\n\
sell(base, rel, price, basevolume, timeout=10, duration=3600, nonce)\n\
withdraw(coin, outputs[])\n\
withdraw(coin, outputs[], broadcast=0)\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus(pending=0, fast=0)\n\
swapstatus(coin, limit=10)\n\
@ -611,6 +611,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
}
return(clonestr("{\"error\":\"cant find coind\"}"));
}
#ifndef NOTETOMIC
else if ( strcmp(method,"eth_withdraw") == 0 )
{
if ( (ptr= LP_coinsearch(coin)) != 0 ) {
return LP_eth_withdraw(ptr, argjson);
}
}
#endif
else if ( strcmp(method,"setconfirms") == 0 )
{
int32_t n;

337
iguana/exchanges/LP_etomic.c

@ -21,9 +21,58 @@
//
// Created by artem on 24.01.18.
//
#include "etomicswap/etomiclib.h"
#include "etomicswap/etomiccurl.h"
#include <inttypes.h>
#include "LP_etomic.h"
int32_t LP_etomic_wait_for_confirmation(char *txId)
{
return(waitForConfirmation(txId));
}
char *LP_etomicalice_send_fee(struct basilisk_swap *swap)
{
char amount[100], secretKey[70];
satoshisToWei(amount, swap->myfee.I.amount);
uint8arrayToHex(secretKey, swap->persistent_privkey.bytes, 32);
if (strcmp(swap->I.alicestr,"ETH") == 0 ) {
return(sendEth(ETH_FEE_ACCEPTOR, amount, secretKey, 1));
} else {
return(sendErc20(swap->I.alicetomic, ETH_FEE_ACCEPTOR, amount, secretKey, 1));
}
}
uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap)
{
if (waitForConfirmation(swap->otherfee.I.ethTxid) < 0) {
printf("Alice fee tx %s does not exist", swap->otherfee.I.ethTxid);
return(0);
}
EthTxData data = getEthTxData(swap->otherfee.I.ethTxid);
if (strcmp(data.from, swap->I.etomicdest) != 0) {
printf("Alice fee tx %s was sent from wrong address %s\n", swap->otherfee.I.ethTxid, data.from);
return(0);
}
if ( strcmp(swap->I.alicestr,"ETH") == 0 ) {
if (strcmp(data.to, ETH_FEE_ACCEPTOR) != 0) {
printf("Alice fee %s was sent to wrong address %s\n", swap->otherfee.I.ethTxid, data.to);
return(0);
}
uint64_t txValue = weiToSatoshi(data.valueHex);
if (txValue != swap->otherfee.I.amount) {
printf("Alice fee %s amount %" PRIu64 " is not equal to expected %" PRIu64 "\n", swap->otherfee.I.ethTxid, txValue, swap->otherfee.I.amount);
return(0);
}
return(1);
} else {
if (strcmp(data.to, swap->I.alicetomic) != 0) {
printf("Alice ERC20 fee %s token address %s is not equal to expected %s\n", swap->otherfee.I.ethTxid, data.to, swap->I.alicetomic);
return(0);
}
char weiAmount[70];
satoshisToWei(weiAmount, swap->otherfee.I.amount);
return(verifyAliceErc20FeeData(swap->I.alicetomic, ETH_FEE_ACCEPTOR, weiAmount, data.input));
}
}
char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
{
@ -49,23 +98,94 @@ char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
else
{
memset(&input20,0,sizeof(input20));
strcpy(input20.bobAddress, swap->I.etomicdest);
strcpy(input20.bobAddress, swap->I.etomicsrc);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
uint8arrayToHex(input20.dealId, swap->alicepayment.utxotxid.bytes, 32);
uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32);
strcpy(input20.tokenAddress, swap->I.alicetomic);
satoshisToWei(input20.amount, swap->I.alicesatoshis);
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.from, swap->I.etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT);
strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
uint64_t allowance = getErc20Allowance(swap->I.etomicdest, ETOMIC_ALICECONTRACT, swap->I.alicetomic);
if (allowance < swap->I.alicesatoshis) {
printf("Alice token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.alicetomic);
strcpy(approveErc20Input.owner, swap->I.etomicdest);
strcpy(approveErc20Input.spender, ETOMIC_ALICECONTRACT);
char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicdest, swap->I.alicetomic);
strcpy(approveErc20Input.amount, tokenBalance);
free(tokenBalance);
strcpy(approveErc20Input.secret, txData.secretKey);
char *allowTxId = approveErc20(approveErc20Input);
LP_etomic_wait_for_confirmation(allowTxId);
free(allowTxId);
}
return(aliceSendsErc20Payment(input20,txData));
}
}
uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
{
if (waitForConfirmation(txId) < 0) {
printf("Alice payment %s does not exist\n", txId);
return(0);
}
EthTxData data = getEthTxData(txId);
if (strcmp(data.to, ETOMIC_ALICECONTRACT) != 0) {
printf("Alice payment %s was sent to wrong address %s\n", txId, data.to);
return(0);
}
if (strcmp(data.from, swap->I.etomicdest) != 0) {
printf("Alice payment %s was done from wrong address %s\n", txId, data.from);
return(0);
}
AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20;
if ( strcmp(swap->I.alicestr,"ETH") == 0 ) {
uint64_t paymentAmount = weiToSatoshi(data.valueHex);
if (paymentAmount != swap->I.alicesatoshis) {
printf("Alice payment amount %" PRIu64 " does not match expected %" PRIu64 "\n", paymentAmount, swap->I.alicesatoshis);
return(0);
}
memset(&input,0,sizeof(input));
strcpy(input.bobAddress, swap->I.etomicsrc);
uint8arrayToHex(input.bobHash, swap->I.secretBn, 20);
uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20);
uint8arrayToHex(input.dealId, swap->alicepayment.I.actualtxid.bytes, 32);
return(verifyAliceEthPaymentData(input, data.input));
} else {
memset(&input20,0,sizeof(input20));
strcpy(input20.bobAddress, swap->I.etomicsrc);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
uint8arrayToHex(input20.dealId, swap->alicepayment.I.actualtxid.bytes, 32);
strcpy(input20.tokenAddress, swap->I.alicetomic);
satoshisToWei(input20.amount, swap->I.alicesatoshis);
return(verifyAliceErc20PaymentData(input20, data.input));
}
}
char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
{
if (waitForConfirmation(swap->alicePaymentEthTx) < 0) {
printf("Alice ETH payment %s is not found, can't reclaim\n", swap->alicePaymentEthTx);
return NULL;
}
EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx);
if (strcmp(receipt.status, "0x1") != 0) {
printf("Alice payment receipt status failed, can't reclaim\n");
return NULL;
}
AliceReclaimsAlicePaymentInput input;
BasicTxData txData;
memset(&txData,0,sizeof(txData));
@ -77,14 +197,14 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32);
satoshisToWei(input.amount, swap->values[BASILISK_ALICEPAYMENT]);
satoshisToWei(input.amount, swap->destamount);
if (swap->alicetomic[0] != 0) {
strcpy(input.tokenAddress, swap->alicetomic);
} else {
strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000");
}
strcpy(input.bobAddress, swap->etomicdest);
strcpy(input.bobAddress, swap->etomicsrc);
uint8arrayToHex(input.aliceHash, swap->secretAm, 20);
bits256 invertedSecret;
int32_t i;
@ -93,7 +213,7 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
}
uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32);
strcpy(txData.from, swap->etomicsrc);
strcpy(txData.from, swap->etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT);
strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, privkey.bytes, 32);
@ -102,6 +222,15 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap)
{
if (waitForConfirmation(swap->alicePaymentEthTx) < 0) {
printf("Alice ETH payment %s is not found, can't spend\n", swap->alicePaymentEthTx);
return NULL;
}
EthTxReceipt receipt = getEthTxReceipt(swap->alicePaymentEthTx);
if (strcmp(receipt.status, "0x1") != 0) {
printf("Alice payment receipt status failed, can't spend\n");
return NULL;
}
BobSpendsAlicePaymentInput input;
BasicTxData txData;
@ -149,6 +278,7 @@ char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap)
uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
strcpy(input.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input.bobHash, swap->I.secretBn, 20);
input.lockTime = swap->bobdeposit.I.locktime;
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -161,17 +291,84 @@ char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap)
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
satoshisToWei(input20.amount, swap->bobdeposit.I.amount);
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobdeposit.I.locktime;
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic);
if (allowance < swap->bobdeposit.I.amount) {
printf("Bob token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic);
strcpy(approveErc20Input.owner, swap->I.etomicsrc);
strcpy(approveErc20Input.spender, ETOMIC_BOBCONTRACT);
char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicsrc, swap->I.bobtomic);
strcpy(approveErc20Input.amount, tokenBalance);
free(tokenBalance);
strcpy(approveErc20Input.secret, txData.secretKey);
char *allowTxId = approveErc20(approveErc20Input);
LP_etomic_wait_for_confirmation(allowTxId);
free(allowTxId);
}
return bobSendsErc20Deposit(input20, txData);
}
}
uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
{
if (waitForConfirmation(txId) < 0) {
printf("Bob deposit txid %s does not exist\n", txId);
return(0);
}
EthTxData data = getEthTxData(txId);
if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) {
printf("Bob deposit txid %s was sent to wrong address %s\n", txId, data.to);
return(0);
}
if (strcmp(data.from, swap->I.etomicsrc) != 0) {
printf("Bob deposit txid %s was sent from wrong address %s\n", txId, data.from);
return(0);
}
BobSendsEthDepositInput input;
BobSendsErc20DepositInput input20;
memset(&input,0,sizeof(input));
memset(&input20,0,sizeof(input20));
if ( strcmp(swap->I.bobstr,"ETH") == 0 ) {
uint64_t depositAmount = weiToSatoshi(data.valueHex);
if (depositAmount != swap->bobdeposit.I.amount) {
printf("Bob deposit %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, depositAmount, swap->bobdeposit.I.amount);
return(0);
}
uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
strcpy(input.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input.bobHash, swap->I.secretBn, 20);
input.lockTime = swap->bobdeposit.I.locktime;
return verifyBobEthDepositData(input, data.input);
} else {
uint8arrayToHex(input20.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
strcpy(input20.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
satoshisToWei(input20.amount, swap->bobdeposit.I.amount);
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobdeposit.I.locktime;
return verifyBobErc20DepositData(input20, data.input);
}
}
char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
{
if (waitForConfirmation(swap->bobDepositEthTx) < 0) {
printf("Bob deposit %s is not found, can't refund\n", swap->bobDepositEthTx);
return NULL;
}
BobRefundsDepositInput input;
BasicTxData txData;
memset(&txData,0,sizeof(txData));
@ -183,9 +380,12 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx);
if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob deposit %s receipt status failed, can't refund\n", swap->bobDepositEthTx);
return NULL;
}
uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32);
strcpy(input.aliceAddress, swap->etomicdest);
sprintf(input.aliceCanClaimAfter, "%" PRIu64, receipt.blockNumber + 960);
bits256 invertedSecret;
int32_t i;
@ -221,6 +421,7 @@ char *LP_etomicbob_sends_payment(struct basilisk_swap *swap)
uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
strcpy(input.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20);
input.lockTime = swap->bobpayment.I.locktime;
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -233,17 +434,83 @@ char *LP_etomicbob_sends_payment(struct basilisk_swap *swap)
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
satoshisToWei(input20.amount, swap->bobpayment.I.amount);
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobpayment.I.locktime;
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic);
if (allowance < swap->bobpayment.I.amount) {
printf("Bob token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic);
strcpy(approveErc20Input.owner, swap->I.etomicsrc);
strcpy(approveErc20Input.spender, ETOMIC_BOBCONTRACT);
char *tokenBalance = getErc20BalanceHexWei(swap->I.etomicsrc, swap->I.bobtomic);
strcpy(approveErc20Input.amount, tokenBalance);
free(tokenBalance);
strcpy(approveErc20Input.secret, txData.secretKey);
char *allowTxId = approveErc20(approveErc20Input);
LP_etomic_wait_for_confirmation(allowTxId);
free(allowTxId);
}
return bobSendsErc20Payment(input20, txData);
}
}
uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId)
{
if (waitForConfirmation(txId) < 0) {
printf("Bob payment %s is not found\n", txId);
return 0;
}
EthTxData data = getEthTxData(txId);
if (strcmp(data.to, ETOMIC_BOBCONTRACT) != 0) {
printf("Bob payment %s was sent to wrong address %s\n", txId, data.to);
}
if (strcmp(data.from, swap->I.etomicsrc) != 0) {
printf("Bob payment %s was sent from wrong address %s\n", txId, data.from);
}
BobSendsEthPaymentInput input;
BobSendsErc20PaymentInput input20;
memset(&input,0,sizeof(input));
memset(&input20,0,sizeof(input20));
if ( strcmp(swap->I.bobstr,"ETH") == 0 ) {
uint64_t paymentAmount = weiToSatoshi(data.valueHex);
if (paymentAmount != swap->bobpayment.I.amount) {
printf("Bob payment %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, paymentAmount, swap->bobpayment.I.amount);
return(0);
}
uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
strcpy(input.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20);
input.lockTime = swap->bobpayment.I.locktime;
return verifyBobEthPaymentData(input, data.input);
} else {
uint8arrayToHex(input20.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
strcpy(input20.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
satoshisToWei(input20.amount, swap->bobpayment.I.amount);
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobpayment.I.locktime;
return verifyBobErc20PaymentData(input20, data.input);
}
}
char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
{
if (waitForConfirmation(swap->bobPaymentEthTx) < 0) {
printf("Bob payment %s is not found, can't reclaim\n", swap->bobPaymentEthTx);
return NULL;
}
BobReclaimsBobPaymentInput input;
BasicTxData txData;
memset(&txData,0,sizeof(txData));
@ -255,9 +522,12 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx);
if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob payment receipt status failed, can't reclaim\n");
return NULL;
}
uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32);
strcpy(input.aliceAddress, swap->etomicdest);
sprintf(input.bobCanClaimAfter, "%" PRIu64, receipt.blockNumber + 480);
uint8arrayToHex(input.aliceHash, swap->secretAm, 20);
if (swap->bobtomic[0] != 0) {
@ -276,13 +546,20 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
{
if (waitForConfirmation(swap->bobPaymentEthTx) < 0) {
printf("Bob payment %s is not found, can't spend\n", swap->bobPaymentEthTx);
return NULL;
}
AliceSpendsBobPaymentInput input;
BasicTxData txData;
memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input));
EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx);
if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob payment %s receipt status failed, can't spend\n", swap->bobPaymentEthTx);
return NULL;
}
struct iguana_info *ecoin;
bits256 privkey;
ecoin = LP_coinfind("ETOMIC");
@ -290,7 +567,6 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32);
satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]);
sprintf(input.bobCanClaimAfter, "%" PRIu64, receipt.blockNumber + 480);
if (swap->bobtomic[0] != 0) {
strcpy(input.tokenAddress, swap->bobtomic);
@ -315,12 +591,20 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap)
{
if (waitForConfirmation(swap->bobDepositEthTx) < 0) {
printf("Bob deposit %s is not found, can't claim\n", swap->bobDepositEthTx);
return NULL;
}
AliceClaimsBobDepositInput input;
BasicTxData txData;
memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input));
EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx);
if (strcmp(receipt.status, "0x1") != 0) {
printf("Bob deposit receipt status failed, can't claim\n");
return NULL;
}
struct iguana_info *ecoin;
bits256 privkey;
@ -329,7 +613,6 @@ char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap)
uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32);
satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]);
sprintf(input.aliceCanClaimAfter, "%" PRIu64, receipt.blockNumber + 960);
if (swap->bobtomic[0] != 0) {
strcpy(input.tokenAddress, swap->bobtomic);
@ -355,9 +638,11 @@ char *sendEthTx(struct basilisk_swap *swap, struct basilisk_rawtx *rawtx)
return LP_etomicbob_sends_deposit(swap);
} else if (rawtx == &swap->bobpayment && swap->I.bobtomic[0] != 0) {
return LP_etomicbob_sends_payment(swap);
} else if (swap->I.iambob == 0 && rawtx == &swap->myfee && swap->I.alicetomic[0] != 0) {
return LP_etomicalice_send_fee(swap);
} else {
char *result = malloc(67);
strcpy(result, "0x0000000000000000000000000000000000000000000000000000000000000000");
strcpy(result, EMPTY_ETH_TX_ID);
return result;
}
}
@ -404,3 +689,25 @@ int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64])
}
return(-1);
}
uint8_t LP_etomic_is_empty_tx_id(char *txId)
{
if (strcmp(txId, EMPTY_ETH_TX_ID) == 0) {
return 1;
}
return 0;
}
uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr)
{
if (coin->etomic[0] == 0) {
printf("Trying to get etomic balance for non-etomic coin %s!", coin->symbol);
return 0;
}
if (strcmp(coin->symbol, "ETH") == 0) {
return getEthBalance(coinaddr);
} else {
return getErc20BalanceSatoshi(coinaddr, coin->etomic);
}
}

54
iguana/exchanges/LP_etomic.h

@ -0,0 +1,54 @@
//
// Created by artem on 13.03.18.
//
#ifndef SUPERNET_LP_ETOMIC_H
#define SUPERNET_LP_ETOMIC_H
#include "etomicswap/etomiclib.h"
#include "etomicswap/etomiccurl.h"
#include <inttypes.h>
#include "LP_include.h"
int32_t LP_etomic_wait_for_confirmation(char *txId);
char *LP_etomicalice_send_fee(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap);
char *LP_etomicalice_send_payment(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId);
char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap);
char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap);
char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId);
char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap);
char *LP_etomicbob_sends_payment(struct basilisk_swap *swap);
uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId);
char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap);
char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap);
char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap);
char *sendEthTx(struct basilisk_swap *swap, struct basilisk_rawtx *rawtx);
int32_t LP_etomic_priv2addr(char *coinaddr,bits256 privkey);
int32_t LP_etomic_priv2pub(uint8_t *pub64,bits256 privkey);
int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64]);
uint8_t LP_etomic_is_empty_tx_id(char *txId);
uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr);
#endif //SUPERNET_LP_ETOMIC_H

5
iguana/exchanges/LP_include.h

@ -266,7 +266,7 @@ struct basilisk_swapinfo
#define BASILISK_ALICERECLAIM 9
#define BASILISK_ALICECLAIM 10
//0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0
char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
static char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment", "bobdeposit", "otherfee", "myfee", "bobrefund", "bobreclaim", "alicereclaim", "aliceclaim" };
struct LP_swap_remember
{
@ -276,7 +276,7 @@ struct LP_swap_remember
uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)];
uint8_t secretAm[20],secretAm256[32],secretBn[20],secretBn256[32],Predeemscript[1024],Dredeemscript[1024],pubkey33[33],other33[33];
char Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)],bobDepositEthTx[75],bobPaymentEthTx[75];
char Agui[65],Bgui[65],gui[65],src[65],dest[65],bobtomic[128],alicetomic[128],etomicsrc[65],etomicdest[65],destaddr[64],Adestaddr[64],Sdestaddr[64],alicepaymentaddr[64],bobpaymentaddr[64],bobdepositaddr[64],alicecoin[65],bobcoin[65],*txbytes[sizeof(txnames)/sizeof(*txnames)],bobDepositEthTx[75],bobPaymentEthTx[75],alicePaymentEthTx[75];
};
struct LP_outpoint
@ -579,5 +579,6 @@ int bech32_convert_bits(uint8_t *out,int32_t *outlen,int outbits,const uint8_t *
int bech32_decode(char *hrp,uint8_t *data,int32_t *data_len,const char *input);
int bech32_encode(char *output,const char *hrp,const uint8_t *data,int32_t data_len);
void HashGroestl(void * buf, const void * pbegin, int len);
bits256 LP_privkey(char *symbol,char *coinaddr,uint8_t taddr);
#endif

8
iguana/exchanges/LP_nativeDEX.c

@ -85,6 +85,11 @@ void LP_millistats_update(struct LP_millistats *mp)
}
#include "LP_include.h"
#ifndef NOTETOMIC
#include "LP_etomic.h"
#endif
portable_mutex_t LP_peermutex,LP_UTXOmutex,LP_utxomutex,LP_commandmutex,LP_cachemutex,LP_swaplistmutex,LP_forwardmutex,LP_pubkeymutex,LP_networkmutex,LP_psockmutex,LP_coinmutex,LP_messagemutex,LP_portfoliomutex,LP_electrummutex,LP_butxomutex,LP_reservedmutex,LP_nanorecvsmutex,LP_tradebotsmutex,LP_gcmutex,LP_inusemutex,LP_cJSONmutex,LP_logmutex,LP_statslogmutex,LP_tradesmutex,LP_commandQmutex,LP_blockinit_mutex,LP_pendswap_mutex,LP_listmutex;
int32_t LP_canbind;
char *Broadcaststr,*Reserved_msgs[2][1000];
@ -178,9 +183,6 @@ char *blocktrail_listtransactions(char *symbol,char *coinaddr,int32_t num,int32_
#include "LP_prices.c"
#include "LP_scan.c"
#include "LP_transaction.c"
#ifndef NOTETOMIC
#include "LP_etomic.c"
#endif
#include "LP_stats.c"
#include "LP_remember.c"
#include "LP_instantdex.c"

8
iguana/exchanges/LP_portfolio.c

@ -95,6 +95,14 @@ uint64_t LP_balance(uint64_t *valuep,int32_t iambob,char *symbol,char *coinaddr)
cJSON *array,*item; bits256 zero; int32_t i,n; uint64_t valuesum,satoshisum,value;
valuesum = satoshisum = 0;
memset(zero.bytes,0,sizeof(zero));
/*
#ifndef NOTETOMIC
struct iguana_info *coin = LP_coinfind(symbol);
if (coin->etomic[0] != 0) {
valuesum = LP_etomic_get_balance(coin, coinaddr);
} else
#endif
*/
if ( (array= LP_listunspent(symbol,coinaddr,zero,zero)) != 0 )
{
if ( is_cJSON_Array(array) != 0 && (n= cJSON_GetArraySize(array)) > 0 )

37
iguana/exchanges/LP_remember.c

@ -75,6 +75,9 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
if (swap->bobpayment.I.ethTxid[0] != 0) {
fprintf(fp,",\"bobPaymentEthTx\":\"%s\"", swap->bobpayment.I.ethTxid);
}
if (swap->alicepayment.I.ethTxid[0] != 0) {
fprintf(fp,",\"alicePaymentEthTx\":\"%s\"", swap->alicepayment.I.ethTxid);
}
fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr);
if ( swap->I.alicetomic[0] != 0 )
@ -901,6 +904,10 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag)
strcpy(rswap->bobPaymentEthTx, jstr(txobj,"bobPaymentEthTx"));
}
if (jstr(txobj,"alicePaymentEthTx") != 0) {
strcpy(rswap->alicePaymentEthTx, jstr(txobj,"alicePaymentEthTx"));
}
if (jstr(txobj,"bobtomic") != 0) {
strcpy(rswap->bobtomic, jstr(txobj,"bobtomic"));
}
@ -1256,7 +1263,11 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
if ( rswap.bobtomic[0] != 0 )
{
char *aliceSpendEthTxId = LP_etomicalice_spends_bob_payment(&rswap);
free(aliceSpendEthTxId);
if (aliceSpendEthTxId != NULL) {
free(aliceSpendEthTxId);
} else {
printf("Alice spend ETH tx send failed!\n");
}
}
#endif
}
@ -1301,7 +1312,11 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
if ( rswap.bobtomic[0] != 0 )
{
char *aliceClaimsEthTxId = LP_etomicalice_claims_bob_deposit(&rswap);
free(aliceClaimsEthTxId);
if (aliceClaimsEthTxId != NULL) {
free(aliceClaimsEthTxId);
} else {
printf("Alice Bob deposit claim ETH tx failed!\n");
}
}
#endif
}
@ -1373,7 +1388,11 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
if ( rswap.alicetomic[0] != 0 )
{
char *bobSpendEthTx = LP_etomicbob_spends_alice_payment(&rswap);
free(bobSpendEthTx);
if (bobSpendEthTx != NULL) {
free(bobSpendEthTx);
} else {
printf("Bob spends Alice payment ETH tx send failed!\n");
}
}
#endif
//printf("bobspend.(%s)\n",rswap.txbytes[BASILISK_BOBSPEND]);
@ -1406,7 +1425,11 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
if ( rswap.bobtomic[0] != 0 )
{
char *bobReclaimEthTx = LP_etomicbob_reclaims_payment(&rswap);
free(bobReclaimEthTx);
if (bobReclaimEthTx != NULL) {
free(bobReclaimEthTx);
} else {
printf("Bob reclaims payment ETH tx send failed!\n");
}
}
#endif
//int32_t z;
@ -1448,7 +1471,11 @@ cJSON *basilisk_remember(int32_t fastflag,int64_t *KMDtotals,int64_t *BTCtotals,
if ( rswap.bobtomic[0] != 0 )
{
char *bobRefundsEthTx = LP_etomicbob_refunds_deposit(&rswap);
free(bobRefundsEthTx);
if (bobRefundsEthTx != NULL) {
free(bobRefundsEthTx);
} else {
printf("Bob refunds deposit ETH tx send failed!\n");
}
}
#endif
//printf("pubB1.(%s) bobrefund.(%s)\n",bits256_str(str,rswap.pubB1),rswap.txbytes[BASILISK_BOBREFUND]);

39
iguana/exchanges/LP_swap.c

@ -107,7 +107,7 @@
depositspent.(f34e04ad74e290f63f3d0bccb7d0d50abfa54eea58de38816fdc596a19767add) alice.1 bob.0
*/
#define TX_WAIT_TIMEOUT 1800
uint32_t LP_atomic_locktime(char *base,char *rel)
{
@ -721,15 +721,20 @@ uint32_t LP_swapdata_rawtxsend(int32_t pairsock,struct basilisk_swap *swap,uint3
if ( swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0 )
{
char *ethTxId = sendEthTx(swap, rawtx);
strcpy(rawtx->I.ethTxid, ethTxId);
free(ethTxId);
if (ethTxId != NULL) {
strcpy(rawtx->I.ethTxid, ethTxId);
free(ethTxId);
} else {
printf("Error sending ETH tx\n");
return(-1);
}
}
#endif
sendlen = 0;
sendbuf[sendlen++] = rawtx->I.datalen & 0xff;
sendbuf[sendlen++] = (rawtx->I.datalen >> 8) & 0xff;
sendbuf[sendlen++] = rawtx->I.redeemlen;
if ( rawtx->I.ethTxid[0] != 0 && strlen(rawtx->I.ethTxid) == 66 )
if ( rawtx->I.ethTxid[0] != 0 && strlen(rawtx->I.ethTxid) == 66 )
{
uint8_t ethTxidBytes[32];
// ETH txid always starts with 0x
@ -857,7 +862,7 @@ void LP_bobloop(void *_swap)
//LP_swapsfp_update(&swap->I.req);
LP_swap_critical = (uint32_t)time(NULL);
LP_unavailableset(swap->bobdeposit.utxotxid,swap->bobdeposit.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash);
if ( LP_waitfor(swap->N.pair,swap,LP_SWAPSTEP_TIMEOUT*10,LP_verify_otherfee) < 0 )
if ( LP_waitfor(swap->N.pair,swap,TX_WAIT_TIMEOUT,LP_verify_otherfee) < 0 )
{
error = 1;
err = -2004, printf("error waiting for alicefee\n");
@ -871,7 +876,7 @@ void LP_bobloop(void *_swap)
}
}
LP_unavailableset(swap->bobpayment.utxotxid,swap->bobpayment.utxovout,(uint32_t)time(NULL)+60,swap->I.otherhash);
if ( error == 0 && LP_waitfor(swap->N.pair,swap,1800,LP_verify_alicepayment) < 0 )
if ( error == 0 && LP_waitfor(swap->N.pair,swap,TX_WAIT_TIMEOUT,LP_verify_alicepayment) < 0 )
{
error = 1;
err = -2006, printf("error waiting for alicepayment\n");
@ -945,7 +950,7 @@ void LP_aliceloop(void *_swap)
LP_swap_critical = (uint32_t)time(NULL);
if ( LP_swapdata_rawtxsend(swap->N.pair,swap,0x80,data,maxlen,&swap->myfee,0x40,0) == 0 )
err = -1004, printf("error sending alicefee\n");
else if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobdeposit) < 0 )
else if ( LP_waitfor(swap->N.pair,swap,TX_WAIT_TIMEOUT,LP_verify_bobdeposit) < 0 )
err = -1005, printf("error waiting for bobdeposit\n");
else
{
@ -970,7 +975,7 @@ void LP_aliceloop(void *_swap)
}
//swap->sentflag = 1;
LP_swap_critical = (uint32_t)time(NULL);
if ( LP_waitfor(swap->N.pair,swap,1800,LP_verify_bobpayment) < 0 )
if ( LP_waitfor(swap->N.pair,swap,TX_WAIT_TIMEOUT,LP_verify_bobpayment) < 0 )
err = -1007, printf("error waiting for bobpayment\n");
else
{
@ -1222,10 +1227,20 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
swap->I.bobconfirms = swap->I.bobmaxconfirms;
if ( swap->I.aliceconfirms > swap->I.alicemaxconfirms )
swap->I.aliceconfirms = swap->I.alicemaxconfirms;
if ( bobcoin->isassetchain != 0 )
swap->I.bobconfirms = BASILISK_DEFAULT_MAXCONFIRMS/2;
if ( alicecoin->isassetchain != 0 )
swap->I.aliceconfirms = BASILISK_DEFAULT_MAXCONFIRMS/2;
if ( bobcoin->isassetchain != 0 ) {
if (strcmp(bobstr, "ETOMIC") != 0) {
swap->I.bobconfirms = BASILISK_DEFAULT_MAXCONFIRMS / 2;
} else {
swap->I.bobconfirms = 1;
}
}
if ( alicecoin->isassetchain != 0 ) {
if (strcmp(alicestr, "ETOMIC") != 0) {
swap->I.aliceconfirms = BASILISK_DEFAULT_MAXCONFIRMS / 2;
} else {
swap->I.aliceconfirms = 1;
}
}
if ( strcmp("BAY",swap->I.req.src) != 0 && strcmp("BAY",swap->I.req.dest) != 0 )
{
swap->I.bobconfirms *= !swap->I.bobistrusted;

78
iguana/exchanges/LP_transaction.c

@ -13,7 +13,6 @@
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
//
// LP_transaction.c
// marketmaker
@ -1329,8 +1328,8 @@ char *LP_createrawtransaction(cJSON **txobjp,int32_t *numvinsp,struct iguana_inf
spendlen = (int32_t)strlen(scriptstr) >> 1;
if ( spendlen < sizeof(script) )
{
decode_hex(script,spendlen,scriptstr);
printf("i.%d using external script.(%s)\n",i,scriptstr);
decode_hex(spendscript,spendlen,scriptstr);
//printf("i.%d using external script.(%s) %d\n",i,scriptstr,spendlen);
}
else
{
@ -1522,7 +1521,7 @@ char *LP_opreturndecrypt(void *ctx,char *symbol,bits256 utxotxid,char *passphras
char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
{
static void *ctx;
int32_t allocated_outputs=0,iter,i,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; struct LP_address *ap; char changeaddr[64],vinaddr[64],str[65],*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000;
int32_t broadcast,allocated_outputs=0,iter,i,utxovout,autofee,completed=0,maxV,numvins,numvouts,datalen,suppress_pubkeys; bits256 privkey; struct LP_address *ap; char changeaddr[64],vinaddr[64],str[65],*signret,*signedtx=0,*rawtx=0; struct vin_info *V; uint32_t locktime; cJSON *retjson,*item,*outputs,*vins=0,*txobj=0,*privkeys=0; struct iguana_msgtx msgtx; bits256 utxotxid,signedtxid; uint64_t txfee,newtxfee=10000;
//printf("withdraw.%s %s\n",coin->symbol,jprint(argjson,0));
if ( coin->etomic[0] != 0 )
{
@ -1531,6 +1530,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
}
if ( ctx == 0 )
ctx = bitcoin_ctx();
broadcast = jint(argjson,"broadcast");
if ( (outputs= jarray(&numvouts,argjson,"outputs")) == 0 )
{
if ( jstr(argjson,"opreturn") == 0 )
@ -1593,7 +1593,7 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
printf("incomplete signing withdraw (%s)\n",jprint(vins,0));
if ( signedtx != 0 )
free(signedtx), signedtx = 0;
} //else printf("LP_withdraw.%s %s -> %s\n",coin->symbol,jprint(argjson,0),bits256_str(str,signedtxid));
}
if ( signedtx == 0 )
break;
datalen = (int32_t)strlen(signedtx) / 2;
@ -1622,7 +1622,6 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
{
if ( completed == 0 && (numvins= cJSON_GetArraySize(vins)) > 0 )
{
for (i=0; i<numvins; i++)
{
item = jitem(vins,i);
@ -1635,9 +1634,23 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
free_json(privkeys);
retjson = cJSON_CreateObject();
if ( rawtx != 0 )
{
jaddstr(retjson,"rawtx",rawtx);
free(rawtx);
}
if ( signedtx != 0 )
{
jaddstr(retjson,"hex",signedtx);
if ( broadcast != 0 )
{
if ( (signret= LP_sendrawtransaction(coin->symbol,signedtx)) != 0 )
{
printf("LP_withdraw.%s %s -> %s (%s)\n",coin->symbol,jprint(argjson,0),bits256_str(str,signedtxid),signret);
free(signret);
}
}
free(signedtx);
}
if ( txobj != 0 )
jadd(retjson,"tx",txobj);
jaddbits256(retjson,"txid",signedtxid);
@ -1647,6 +1660,31 @@ char *LP_withdraw(struct iguana_info *coin,cJSON *argjson)
return(jprint(retjson,1));
}
#ifndef NOTETOMIC
char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson)
{
cJSON *retjson = cJSON_CreateObject();
char *dest_addr, *tx_id, privkey_str[70], amount_str[100];
int64_t amount;
bits256 privkey;
dest_addr = jstr(argjson, "to");
amount = jdouble(argjson, "amount") * 100000000;
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
satoshisToWei(amount_str, amount);
if (strcmp(coin->symbol, "ETH") == 0) {
tx_id = sendEth(dest_addr, amount_str, privkey_str, 0);
} else {
tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0);
}
jaddstr(retjson, "tx_id", tx_id);
return(jprint(retjson,1));
}
#endif
int32_t basilisk_rawtx_gen(void *ctx,char *str,uint32_t swapstarted,uint8_t *pubkey33,int32_t iambob,int32_t lockinputs,struct basilisk_rawtx *rawtx,uint32_t locktime,uint8_t *script,int32_t scriptlen,int64_t txfee,int32_t minconf,int32_t delay,bits256 privkey,uint8_t *changermd160,char *vinaddr)
{
struct iguana_info *coin; int32_t len,retval=-1; char *retstr,*hexstr; cJSON *argjson,*outputs,*item,*retjson,*obj;
@ -2259,6 +2297,13 @@ int32_t LP_verify_otherfee(struct basilisk_swap *swap,uint8_t *data,int32_t data
//printf("dexfee verified\n");
}
else printf("locktime mismatch in otherfee, reject %u vs %u\n",swap->otherfee.I.locktime,swap->I.started+1);
#ifndef NOTETOMIC
if (swap->otherfee.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->otherfee.I.ethTxid) == 0) {
if (LP_etomic_wait_for_confirmation(swap->otherfee.I.ethTxid) < 0 || LP_etomic_verify_alice_fee(swap) == 0) {
return(-1);
}
}
#endif
return(0);
} else printf("destaddress mismatch in other fee, reject (%s) vs (%s)\n",swap->otherfee.I.destaddr,swap->otherfee.p2shaddr);
}
@ -2336,6 +2381,13 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da
printf("%02x",swap->aliceclaim.txbytes[i]);
printf(" <- aliceclaim\n");*/
//basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration);
#ifndef NOTETOMIC
if (swap->bobdeposit.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->bobdeposit.I.ethTxid) == 0) {
if (LP_etomic_wait_for_confirmation(swap->bobdeposit.I.ethTxid) < 0 || LP_etomic_verify_bob_deposit(swap, swap->bobdeposit.I.ethTxid) == 0) {
return(-1);
}
}
#endif
return(LP_waitmempool(coin->symbol,swap->bobdeposit.I.destaddr,swap->bobdeposit.I.signedtxid,0,60));
} else printf("error signing aliceclaim suppress.%d vin.(%s)\n",swap->aliceclaim.I.suppress_pubkeys,swap->bobdeposit.I.destaddr);
}
@ -2359,6 +2411,13 @@ int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t
if ( bits256_nonz(swap->alicepayment.I.signedtxid) != 0 )
swap->aliceunconf = 1;
basilisk_dontforget_update(swap,&swap->alicepayment);
#ifndef NOTETOMIC
if (swap->alicepayment.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->alicepayment.I.ethTxid) == 0) {
if (LP_etomic_verify_alice_payment(swap, swap->alicepayment.I.ethTxid) == 0) {
return(-1);
}
}
#endif
return(LP_waitmempool(coin->symbol,swap->alicepayment.I.destaddr,swap->alicepayment.I.signedtxid,0,60));
//printf("import alicepayment address.(%s)\n",swap->alicepayment.p2shaddr);
//LP_importaddress(coin->symbol,swap->alicepayment.p2shaddr);
@ -2411,6 +2470,13 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da
memcpy(swap->alicespend.I.pubkey33,swap->persistent_pubkey33,33);
bitcoin_address(coin->symbol,swap->alicespend.I.destaddr,coin->taddr,coin->pubtype,swap->persistent_pubkey33,33);
//char str[65],str2[65]; printf("bobpaid privAm.(%s) myprivs[0].(%s)\n",bits256_str(str,swap->I.privAm),bits256_str(str2,swap->I.myprivs[0]));
#ifndef NOTETOMIC
if (swap->bobpayment.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->bobpayment.I.ethTxid) == 0) {
if (LP_etomic_wait_for_confirmation(swap->bobpayment.I.ethTxid) < 0 || LP_etomic_verify_bob_payment(swap, swap->bobpayment.I.ethTxid) == 0) {
return(-1);
}
}
#endif
if ( (retval= basilisk_rawtx_sign(coin->symbol,coin->wiftaddr,coin->taddr,coin->pubtype,coin->p2shtype,coin->isPoS,coin->wiftype,swap,&swap->alicespend,&swap->bobpayment,swap->I.myprivs[0],0,userdata,len,1,swap->changermd160,swap->bobpayment.I.destaddr,coin->zcash)) == 0 )
{
/*for (i=0; i<swap->bobpayment.I.datalen; i++)

26
iguana/exchanges/LP_utxo.c

@ -406,7 +406,7 @@ void LP_mark_spent(char *symbol,bits256 txid,int32_t vout)
int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,struct iguana_info *coin,char *coinaddr,bits256 txid,int32_t vout,uint64_t value,int32_t height,int32_t spendheight)
{
struct LP_address *ap; cJSON *txobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65];
struct LP_address *ap; char *hexstr; cJSON *txobj,*sobj; struct LP_transaction *tx; struct LP_address_utxo *up,*tmp; int32_t flag,retval = 0; //char str[65];
if ( coin == 0 )
return(0);
if ( spendheight > 0 ) // dont autocreate entries for spends we dont care about
@ -443,7 +443,20 @@ int32_t LP_address_utxoadd(int32_t skipsearch,uint32_t timestamp,char *debug,str
{
//char str[65]; printf("prevent utxoadd since gettxout %s %s %s/v%d missing\n",coin->symbol,coinaddr,bits256_str(str,txid),vout);
return(0);
} else free_json(txobj);
}
if ( (sobj= jobj(txobj,"scriptPubKey")) != 0 )
{
if ( (hexstr= jstr(sobj,"hex")) != 0 )
{
if ( strlen(hexstr) != 25*2 )
{
//printf("skip non-standard utxo.(%s)\n",hexstr);
free_json(txobj);
return(0);
}
}
}
free_json(txobj);
}
up = calloc(1,sizeof(*up));
up->U.txid = txid;
@ -524,7 +537,9 @@ struct LP_address *LP_address_utxo_reset(struct iguana_info *coin)
}
LP_address_utxoadd(1,now,"withdraw",coin,coin->smartaddr,txid,vout,value,height,-1);
if ( (up= LP_address_utxofind(coin,coin->smartaddr,txid,vout)) == 0 )
printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value));
{
//printf("couldnt find just added %s/%d ht.%d %.8f\n",bits256_str(str,txid),vout,height,dstr(value));
}
else
{
m++;
@ -626,6 +641,11 @@ cJSON *LP_address_balance(struct iguana_info *coin,char *coinaddr,int32_t electr
{
cJSON *array,*retjson,*item; bits256 zero; int32_t i,n; uint64_t balance = 0;
memset(zero.bytes,0,sizeof(zero));
#ifndef NOTETOMIC
if (coin->etomic[0] != 0) {
balance = LP_etomic_get_balance(coin, coinaddr);
} else
#endif
if ( coin->electrum == 0 )
{
if ( (array= LP_listunspent(coin->symbol,coinaddr,zero,zero)) != 0 )

15
iguana/exchanges/etomicswap/CMakeLists.txt

@ -1,10 +1,11 @@
cmake_minimum_required(VERSION 2.8.9)
add_library(etomiclib etomiclib.cpp)
add_library(etomiccurl etomiccurl.c)
cmake_minimum_required(VERSION 3.5.1)
add_library(etomiclib-testnet etomiclib.cpp etomiccurl.c)
add_library(etomiclib-mainnet etomiclib.cpp etomiccurl.c)
target_compile_definitions(etomiclib-testnet PRIVATE ETOMIC_TESTNET)
add_executable(alice alice.c)
add_executable(bob bob.c)
include_directories("${CMAKE_SOURCE_DIR}/cpp-ethereum")
target_link_libraries(etomiccurl PUBLIC curl libcrypto777)
target_link_libraries(etomiclib PUBLIC ethcore devcrypto devcore etomiccurl)
target_link_libraries(alice PUBLIC etomiclib)
target_link_libraries(bob PUBLIC etomiclib etomiccurl)
target_link_libraries(etomiclib-testnet PUBLIC curl libcrypto777 ethcore devcrypto devcore pthread)
target_link_libraries(etomiclib-mainnet PUBLIC curl libcrypto777 ethcore devcrypto devcore pthread)
target_link_libraries(alice PUBLIC etomiclib-testnet)
target_link_libraries(bob PUBLIC etomiclib-testnet)

199
iguana/exchanges/etomicswap/bob.c

@ -11,9 +11,14 @@
char* bobContractAddress = "0x9387Fd3a016bB0205e4e131Dde886B9d2BC000A2";
char* aliceAddress = "0x485d2cc2d13a9e12E4b53D606DB1c8adc884fB8a";
char* bobAddress = "0xA7EF3f65714AE266414C9E58bB4bAa4E6FB82B41";
char* bobAddress = "0xbAB36286672fbdc7B250804bf6D14Be0dF69fa29";
char* tokenAddress = "0xc0eb7AeD740E1796992A08962c15661bDEB58003";
void *erc20ApproveThread(ApproveErc20Input *input) {
char *result = approveErc20(*input);
free(result);
}
int main(int argc, char** argv)
{
enum {
@ -28,7 +33,8 @@ int main(int argc, char** argv)
BOB_APPROVES_ERC20,
BOB_ETH_BALANCE,
BOB_ERC20_BALANCE,
TX_RECEIPT
TX_RECEIPT,
TX_DATA
};
if (argc < 2) {
return 1;
@ -51,8 +57,12 @@ int main(int argc, char** argv)
strcpy(input.bobHash, argv[3]);
result = bobSendsEthDeposit(input, txData);
printf("%s\n", result);
free(result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
break;
case BOB_ERC20_DEPOSIT:
strcpy(txData.amount, "0");
@ -70,7 +80,12 @@ int main(int argc, char** argv)
strcpy(input1.tokenAddress, tokenAddress);
result = bobSendsErc20Deposit(input1, txData);
printf("%s\n", result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_CLAIMS_DEPOSIT:
@ -84,11 +99,15 @@ int main(int argc, char** argv)
strcpy(input2.amount, "1000000000000000000");
strcpy(input2.aliceAddress, aliceAddress);
strcpy(input2.tokenAddress, argv[3]);
strcpy(input2.aliceCanClaimAfter, argv[4]);
strcpy(input2.bobSecret, argv[5]);
result = bobRefundsDeposit(input2, txData);
printf("%s\n", result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case ALICE_CLAIMS_DEPOSIT:
@ -102,11 +121,15 @@ int main(int argc, char** argv)
strcpy(input3.amount, "1000000000000000000");
strcpy(input3.bobAddress, bobAddress);
strcpy(input3.tokenAddress, argv[3]);
strcpy(input3.aliceCanClaimAfter, argv[4]);
strcpy(input3.bobHash, argv[5]);
result = aliceClaimsBobDeposit(input3, txData);
printf("%s\n", result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_ETH_PAYMENT:
@ -121,7 +144,12 @@ int main(int argc, char** argv)
strcpy(input4.aliceAddress, aliceAddress);
result = bobSendsEthPayment(input4, txData);
printf("%s\n", result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_ERC20_PAYMENT:
@ -139,7 +167,12 @@ int main(int argc, char** argv)
strcpy(input5.aliceHash, argv[3]);
result = bobSendsErc20Payment(input5, txData);
printf("%s\n", result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case BOB_CLAIMS_PAYMENT:
@ -154,11 +187,15 @@ int main(int argc, char** argv)
strcpy(input6.aliceAddress, aliceAddress);
strcpy(input6.amount, "1000000000000000000");
strcpy(input6.tokenAddress, argv[3]);
strcpy(input6.bobCanClaimAfter, argv[4]);
strcpy(input6.aliceHash, argv[5]);
result = bobReclaimsBobPayment(input6, txData);
printf("%s\n", result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
free(result);
break;
case ALICE_CLAIMS_PAYMENT:
@ -173,39 +210,127 @@ int main(int argc, char** argv)
strcpy(input7.bobAddress, bobAddress);
strcpy(input7.amount, "1000000000000000000");
strcpy(input7.tokenAddress, argv[3]);
strcpy(input7.bobCanClaimAfter, argv[4]);
strcpy(input7.aliceSecret, argv[5]);
result = aliceSpendsBobPayment(input7, txData);
printf("%s\n", result);
free(result);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
break;
case BOB_APPROVES_ERC20:
result = approveErc20(
"10000000000000000000",
"0xA7EF3f65714AE266414C9E58bB4bAa4E6FB82B41",
getenv("BOB_PK")
);
printf("%s\n", result);
free(result);
printf("approving erc20\n");
ApproveErc20Input input8;
strcpy(input8.amount, "0");
strcpy(input8.spender, bobContractAddress);
strcpy(input8.owner, bobAddress);
strcpy(input8.tokenAddress, tokenAddress);
strcpy(input8.secret, getenv("BOB_PK"));
ApproveErc20Input input123;
strcpy(input123.amount, "100");
strcpy(input123.spender, bobContractAddress);
strcpy(input123.owner, bobAddress);
strcpy(input123.tokenAddress, tokenAddress);
strcpy(input123.secret, getenv("BOB_PK"));
pthread_t t1, t2;
pthread_create(&t1, NULL, erc20ApproveThread, &input8);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_create(&t2, NULL, erc20ApproveThread, &input123);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
/*result = approveErc20(input8);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
result = approveErc20(&input8);
if (result != NULL) {
printf("%s\n", result);
free(result);
} else {
printf("Tx send result was NULL\n");
}
*/
break;
case BOB_ETH_BALANCE:
printf("%" PRIu64 "\n", getEthBalance(bobAddress));
break;
case BOB_ERC20_BALANCE:
printf("%" PRIu64 "\n", getErc20Balance(bobAddress, tokenAddress));
printf("%" PRIu64 "\n", getErc20BalanceSatoshi(bobAddress, tokenAddress));
break;
case TX_RECEIPT:
printf("getTxReceipt\n");
EthTxReceipt txReceipt;
txReceipt = getEthTxReceipt("0x82afa1b00f8a63e1a91430162e5cb2d4ebe915831ffd56e6e3227814913e23e6");
printf("%" PRIu64 "\n", txReceipt.blockNumber);
printf("%s\n", txReceipt.blockHash);
txReceipt = getEthTxReceipt("0xc337b9cfe76aaa9022d9399a9e4ecdc1b7044d65ef74e8911a4b47874bee60c6");
printf("blockNumber: %" PRIu64 "\n", txReceipt.blockNumber);
printf("blockHash: %s\n", txReceipt.blockHash);
printf("status: %s\n", txReceipt.status);
printf("confirmations: %" PRIu64 "\n", txReceipt.confirmations);
break;
case TX_DATA:
printf("getTxData\n");
EthTxData ethTxData;
ethTxData = getEthTxData("0xc337b9cfe76aaa9022d9399a9e4ecdc1b7044d65ef74e8911a4b47874bee60c6");
printf("from : %s\n", ethTxData.from);
printf("to: %s\n", ethTxData.to);
printf("value: %s\n", ethTxData.valueHex);
printf("input: %s\n", ethTxData.input);
printf("exists: %d\n", ethTxData.exists);
break;
default:
return 1;
}
/*
char *pubkey = getPubKeyFromPriv(getenv("BOB_PK"));
printf("pubkey: %s\n", pubkey);
free(pubkey);
@ -214,5 +339,23 @@ int main(int argc, char** argv)
char weiBuffer[100];
satoshisToWei(weiBuffer, satoshis);
printf("wei: %s\n", weiBuffer);
uint8_t decimals = getErc20Decimals(tokenAddress);
printf("decimals: %d\n", decimals);
uint64_t tokenAllowance = getErc20Allowance(bobAddress, bobContractAddress, tokenAddress);
printf("allowance: %" PRIu64 "\n", tokenAllowance);
char *sendEthTx = sendEth(bobAddress, "100000000000000", getenv("BOB_PK"));
printf("sent ETH: %s\n", sendEthTx);
free(sendEthTx);
char *sendErc20Tx = sendErc20(tokenAddress, bobAddress, "100000000000000", getenv("BOB_PK"));
printf("sent Erc20: %s\n", sendErc20Tx);
free(sendErc20Tx);
uint64_t gasPrice = getGasPriceFromStation();
printf("gasPrice: %" PRIu64 "\n", gasPrice);
*/
return 0;
}

312
iguana/exchanges/etomicswap/etomiccurl.c

@ -1,10 +1,8 @@
#include "etomiccurl.h"
#include <curl/curl.h>
#include <memory.h>
#include <stdlib.h>
#include "../../../includes/cJSON.h"
static char *ethRpcUrl = ETOMIC_URL;
pthread_mutex_t sendTxMutex = PTHREAD_MUTEX_INITIALIZER;
struct string {
char *ptr;
@ -36,6 +34,28 @@ size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
return size*nmemb;
}
cJSON *parseEthRpcResponse(char *requestResult)
{
printf("Trying to parse ETH RPC response: %s\n", requestResult);
cJSON *json = cJSON_Parse(requestResult);
if (json == NULL) {
printf("ETH RPC response parse failed!\n");
return NULL;
}
cJSON *tmp = cJSON_GetObjectItem(json, "result");
cJSON *error = cJSON_GetObjectItem(json, "error");
cJSON *result = NULL;
if (!is_cJSON_Null(tmp)) {
result = cJSON_Duplicate(tmp, 1);
} else if (error != NULL && !is_cJSON_Null(error)) {
char *errorString = cJSON_PrintUnformatted(error);
printf("Got ETH rpc error: %s\n", errorString);
free(errorString);
}
cJSON_Delete(json);
return result;
}
char* sendRequest(char* request)
{
CURL *curl;
@ -69,128 +89,256 @@ char* sendRequest(char* request)
}
}
char* sendRawTx(char* rawTx)
cJSON *sendRpcRequest(char *method, cJSON *params)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_sendRawTransaction"));
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
cJSON_AddStringToObject(request, "jsonrpc", "2.0");
cJSON_AddStringToObject(request, "method", method);
cJSON_AddItemToObject(request, "params", cJSON_Duplicate(params, 1));
cJSON_AddNumberToObject(request, "id", 1);
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON *json = cJSON_Parse(requestResult);
free(string);
cJSON_Delete(request);
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring;
char* txId = (char*)malloc(strlen(tmp) + 1);
strcpy(txId, tmp);
cJSON_Delete(json);
cJSON *result = parseEthRpcResponse(requestResult);
free(requestResult);
free(string);
return result;
}
char* sendRawTxWaitConfirm(char* rawTx)
{
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx));
cJSON *resultJson = sendRpcRequest("eth_sendRawTransaction", params);
cJSON_Delete(params);
char *txId = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
char* tmp = resultJson->valuestring;
txId = (char *) malloc(strlen(tmp) + 1);
strcpy(txId, tmp);
}
/*
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
char* tmp = resultJson->valuestring;
if (waitForConfirmation(tmp) > 0) {
txId = (char *) malloc(strlen(tmp) + 1);
strcpy(txId, tmp);
}
}
*/
cJSON_Delete(resultJson);
pthread_mutex_unlock(&sendTxMutex);
return txId;
}
int getNonce(char* address)
char* sendRawTx(char* rawTx)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getTransactionCount"));
cJSON_AddItemToArray(params, cJSON_CreateString(rawTx));
cJSON *resultJson = sendRpcRequest("eth_sendRawTransaction", params);
cJSON_Delete(params);
char *txId = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
char* tmp = resultJson->valuestring;
txId = (char *) malloc(strlen(tmp) + 1);
strcpy(txId, tmp);
}
cJSON_Delete(resultJson);
pthread_mutex_unlock(&sendTxMutex);
return txId;
}
int64_t getNonce(char* address)
{
// we should lock this mutex and unlock it only when transaction was already sent.
// make sure that sendRawTx is called after getting a nonce!
if (pthread_mutex_lock(&sendTxMutex) != 0) {
printf("Nonce mutex lock failed\n");
};
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToArray(params, cJSON_CreateString(address));
cJSON_AddItemToArray(params, cJSON_CreateString("pending"));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
int nonce = (int)strtol(cJSON_GetObjectItem(json, "result")->valuestring, NULL, 0);
cJSON_Delete(json);
free(requestResult);
free(string);
// cJSON_AddItemToArray(params, cJSON_CreateString("pending"));
int64_t nonce = -1;
cJSON *nonceJson = sendRpcRequest("parity_nextNonce", params);
cJSON_Delete(params);
if (nonceJson != NULL && is_cJSON_String(nonceJson) && nonceJson != NULL) {
nonce = (int64_t) strtol(nonceJson->valuestring, NULL, 0);
}
cJSON_Delete(nonceJson);
printf("Got ETH nonce %d\n", (int)nonce);
return nonce;
}
char* getEthBalanceRequest(char* address)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getBalance"));
cJSON_AddItemToArray(params, cJSON_CreateString(address));
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring;
char* balance = (char*)malloc(strlen(tmp) + 1);
strcpy(balance, tmp);
cJSON_Delete(json);
free(requestResult);
free(string);
cJSON *balanceJson = sendRpcRequest("eth_getBalance", params);
cJSON_Delete(params);
char *balance = NULL;
if (balanceJson != NULL && is_cJSON_String(balanceJson) && balanceJson->valuestring != NULL) {
balance = (char *) malloc(strlen(balanceJson->valuestring) + 1);
strcpy(balance, balanceJson->valuestring);
}
cJSON_Delete(balanceJson);
return balance;
}
char* ethCall(char* to, const char* data)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_call"));
cJSON_AddStringToObject(txObject, "to", to);
cJSON_AddStringToObject(txObject, "data", data);
cJSON_AddItemToArray(params, txObject);
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
char* tmp = cJSON_GetObjectItem(json, "result")->valuestring;
char* result = (char*)malloc(strlen(tmp) + 1);
strcpy(result, tmp);
cJSON_Delete(json);
free(requestResult);
free(string);
cJSON *resultJson = sendRpcRequest("eth_call", params);
cJSON_Delete(params);
char* result = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (char *) malloc(strlen(resultJson->valuestring) + 1);
strcpy(result, resultJson->valuestring);
}
cJSON_Delete(resultJson);
return result;
}
EthTxReceipt getEthTxReceipt(char *txId)
{
EthTxReceipt result;
char* string;
cJSON *request = cJSON_CreateObject();
memset(&result, 0, sizeof(result));
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToObject(request, "jsonrpc", cJSON_CreateString("2.0"));
cJSON_AddItemToObject(request, "method", cJSON_CreateString("eth_getTransactionReceipt"));
cJSON_AddItemToArray(params, cJSON_CreateString(txId));
cJSON_AddItemToObject(request, "params", params);
cJSON_AddItemToObject(request, "id", cJSON_CreateNumber(2));
string = cJSON_PrintUnformatted(request);
char *requestResult = sendRequest(string);
cJSON_Delete(request);
cJSON *json = cJSON_Parse(requestResult);
cJSON *tmp = cJSON_GetObjectItem(json, "result");
if (is_cJSON_Null(tmp)) {
cJSON *receiptJson = sendRpcRequest("eth_getTransactionReceipt", params);
cJSON_Delete(params);
if (receiptJson == NULL || is_cJSON_Null(cJSON_GetObjectItem(receiptJson, "blockHash")) || is_cJSON_Null(cJSON_GetObjectItem(receiptJson, "blockNumber"))) {
printf("ETH tx %s is not confirmed yet or does not exist at all\n", txId);
strcpy(result.blockHash, "0x0000000000000000000000000000000000000000000000000000000000000000");
result.blockNumber = 0;
} else {
strcpy(result.blockHash, cJSON_GetObjectItem(tmp, "blockHash")->valuestring);
result.blockNumber = (uint64_t) strtol(cJSON_GetObjectItem(tmp, "blockNumber")->valuestring, NULL, 0);
uint64_t currentBlockNumber = getEthBlockNumber();
strcpy(result.blockHash, cJSON_GetObjectItem(receiptJson, "blockHash")->valuestring);
strcpy(result.status, cJSON_GetObjectItem(receiptJson, "status")->valuestring);
result.blockNumber = (uint64_t) strtol(cJSON_GetObjectItem(receiptJson, "blockNumber")->valuestring, NULL, 0);
if (currentBlockNumber >= result.blockNumber) {
result.confirmations = currentBlockNumber - result.blockNumber + 1;
}
}
cJSON_Delete(json);
free(requestResult);
free(string);
cJSON_Delete(receiptJson);
return result;
}
uint64_t getEthBlockNumber()
{
uint64_t result = 0;
cJSON *params = cJSON_CreateArray();
cJSON *blockNumberJson = sendRpcRequest("eth_blockNumber", params);
cJSON_Delete(params);
if (blockNumberJson != NULL && is_cJSON_String(blockNumberJson) && blockNumberJson->valuestring != NULL) {
result = (uint64_t) strtol(blockNumberJson->valuestring, NULL, 0);
}
cJSON_Delete(blockNumberJson);
return result;
}
EthTxData getEthTxData(char *txId)
{
EthTxData result;
memset(&result, 0, sizeof(result));
cJSON *params = cJSON_CreateArray();
cJSON_AddItemToArray(params, cJSON_CreateString(txId));
cJSON *dataJson = sendRpcRequest("eth_getTransactionByHash", params);
cJSON_Delete(params);
if (dataJson == NULL) {
result.exists = 0;
printf("ETH tx %s get data error or txId does not exist\n", txId);
} else {
result.exists = 1;
strcpy(result.from, cJSON_GetObjectItem(dataJson, "from")->valuestring);
strcpy(result.to, cJSON_GetObjectItem(dataJson, "to")->valuestring);
strcpy(result.input, cJSON_GetObjectItem(dataJson, "input")->valuestring);
strcpy(result.valueHex, cJSON_GetObjectItem(dataJson, "value")->valuestring);
}
free(dataJson);
return result;
}
uint64_t getGasPriceFromStation()
{
CURL *curl;
CURLcode res;
struct curl_slist *headers = NULL;
curl = curl_easy_init();
if (curl) {
struct string s;
init_eth_string(&s);
headers = curl_slist_append(headers, "Accept: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
curl_easy_setopt(curl, CURLOPT_URL, "https://ethgasstation.info/json/ethgasAPI.json");
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
return DEFAULT_GAS_PRICE;
}
/* always cleanup */
curl_easy_cleanup(curl);
cJSON *resultJson = cJSON_Parse(s.ptr);
uint64_t result = DEFAULT_GAS_PRICE;
free(s.ptr);
if (resultJson == NULL) {
return result;
}
if (is_cJSON_Number(cJSON_GetObjectItem(resultJson, "average"))) {
#ifdef ETOMIC_TESTNET
result = (uint64_t)(cJSON_GetObjectItem(resultJson, "average")->valuedouble / 10) + 10;
#else
result = (uint64_t)(cJSON_GetObjectItem(resultJson, "average")->valuedouble / 10) + 1;
#endif
}
cJSON_Delete(resultJson);
return result;
} else {
return DEFAULT_GAS_PRICE;
}
}
int32_t waitForConfirmation(char *txId)
{
EthTxReceipt receipt;
EthTxData txData;
uint8_t retries = 0;
do {
receipt = getEthTxReceipt(txId);
if (receipt.confirmations < 1) {
txData = getEthTxData(txId);
if (txData.exists == 0) {
retries++;
if (retries >= 30) {
printf("Have not found ETH tx %s after 10 checks, aborting\n", txId);
return (-1);
}
}
} else {
break;
}
printf("waiting for ETH txId to be confirmed: %s\n", txId);
sleep(15);
} while (1);
if (strcmp(receipt.status, "0x1") != 0) {
printf("ETH txid %s receipt status failed\n", txId);
return(-1);
}
return((int32_t)receipt.confirmations);
}

38
iguana/exchanges/etomicswap/etomiccurl.h

@ -1,28 +1,54 @@
#ifndef ETOMIC_CURL_HEADER
#define ETOMIC_CURL_HEADER
#include <stdint.h>
#include <includes/cJSON.h>
#ifdef _WIN32
#include "../../../OSlibs/win/pthread.h"
#endif
#ifdef __cplusplus
extern "C"{
#endif
#define ETOMIC_TESTNET
#ifdef ETOMIC_TESTNET
#define ETOMIC_URL "https://ropsten.infura.io/y07GHxUyTgeN2mdfOonu"
#define ETOMIC_URL "http://195.201.0.6:8545"
#define DEFAULT_GAS_PRICE 100
#else
#define ETOMIC_URL "https://mainnet.infura.io/y07GHxUyTgeN2mdfOonu"
#define ETOMIC_URL "http://195.201.0.6:8555"
#define DEFAULT_GAS_PRICE 4
#endif
typedef struct
{
uint64_t blockNumber;
uint64_t confirmations;
char blockHash[75];
char status[10];
} EthTxReceipt;
typedef struct
{
char from[50];
char to[50];
char input[1000];
char valueHex[70];
uint8_t exists;
} EthTxData;
char* sendRawTx(char* rawTx);
char* sendRawTxWaitConfirm(char* rawTx);
char* ethCall(char* to, const char* data);
int getNonce(char* address);
int64_t getNonce(char* address);
char* getEthBalanceRequest(char* address);
EthTxReceipt getEthTxReceipt(char *txId);
EthTxData getEthTxData(char *txId);
uint64_t getEthBlockNumber();
uint64_t getGasPriceFromStation();
int32_t waitForConfirmation(char *txId);
#ifdef __cplusplus
}
#endif
#endif

437
iguana/exchanges/etomicswap/etomiclib.cpp

@ -12,7 +12,7 @@
using namespace dev;
using namespace dev::eth;
char* stringStreamToChar(std::stringstream& ss)
char *stringStreamToChar(std::stringstream& ss)
{
const std::string tmp = ss.str();
auto result = (char*)malloc(strlen(tmp.c_str()) + 1);
@ -26,13 +26,13 @@ TransactionSkeleton txDataToSkeleton(BasicTxData txData)
tx.from = jsToAddress(txData.from);
tx.to = jsToAddress(txData.to);
tx.value = jsToU256(txData.amount);
tx.gas = 300000;
tx.gasPrice = ETOMIC_GASMULT * exp10<9>();
tx.gas = 100000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(txData.from);
return tx;
}
char* signTx(TransactionSkeleton& tx, char* secret)
char *signTx(TransactionSkeleton& tx, char* secret)
{
Secret& secretKey = *(new Secret(secret));
auto baseTx = new TransactionBase(tx, secretKey);
@ -43,30 +43,29 @@ char* signTx(TransactionSkeleton& tx, char* secret)
return stringStreamToChar(ss);
}
char* approveErc20(char* amount, char* from, char* secret)
char *approveErc20(ApproveErc20Input input)
{
TransactionSkeleton tx;
tx.from = jsToAddress(from);
tx.to = jsToAddress("0xc0eb7AeD740E1796992A08962c15661bDEB58003");
tx.value = 0; // exp10<18>();
tx.from = jsToAddress(input.owner);
tx.to = jsToAddress(input.tokenAddress);
tx.value = 0;
tx.gas = 300000;
tx.gasPrice = ETOMIC_GASMULT * exp10<9>();
tx.nonce = getNonce(from);
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(input.owner);
std::stringstream ss;
ss << "0x095ea7b3"
<< "000000000000000000000000"
<< toHex(jsToAddress("0xe1D4236C5774D35Dc47dcc2E5E0CcFc463A3289c"))
<< toHex(toBigEndian(jsToU256(amount)));
<< toHex(jsToAddress(input.spender))
<< toHex(toBigEndian(jsToU256(input.amount)));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, secret);
char* result = sendRawTx(rawTx);
char* rawTx = signTx(tx, input.secret);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData)
std::stringstream aliceSendsEthPaymentData(AliceSendsEthPaymentInput input)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss;
ss << "0x47c7b6e2"
<< toHex(jsToBytes(input.dealId))
@ -76,20 +75,41 @@ char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData)
<< "000000000000000000000000"
<< toHex(jsToBytes(input.bobHash))
<< "000000000000000000000000";
return ss;
}
char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = aliceSendsEthPaymentData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char *rawTx = signTx(tx, txData.secretKey);
char *result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData)
uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = aliceSendsEthPaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
printf("Alice ETH payment data %s does not match expected %s\n", data, ss.str().c_str());
return 0;
}
return 1;
}
std::stringstream aliceSendsErc20PaymentData(AliceSendsErc20PaymentInput input)
{
uint8_t decimals = getErc20Decimals(input.tokenAddress);
u256 amount = jsToU256(input.amount);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
std::stringstream ss;
ss << "0x184db3bf"
<< toHex(jsToBytes(input.dealId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(amount))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.bobAddress))
<< toHex(jsToBytes(input.aliceHash))
@ -98,22 +118,47 @@ char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txDa
<< "000000000000000000000000"
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress));
return ss;
}
char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = aliceSendsErc20PaymentData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
uint8_t verifyAliceErc20PaymentData(AliceSendsErc20PaymentInput input, char *data)
{
std::stringstream ss = aliceSendsErc20PaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
printf("Alice ERC20 payment data %s is not equal to expected %s\n", data, ss.str().c_str());
return 0;
}
return 1;
}
char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss;
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0x8b9a167a"
<< toHex(jsToBytes(input.dealId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(amount))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress))
<< toHex(tokenAddress)
<< "000000000000000000000000"
<< toHex(jsToAddress(input.bobAddress))
<< toHex(jsToBytes(input.aliceHash))
@ -123,7 +168,7 @@ char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxDat
<< toHex(jsToBytes(input.bobSecret));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -132,11 +177,19 @@ char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss;
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0x392ec66b"
<< toHex(jsToBytes(input.dealId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(amount))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress))
<< toHex(tokenAddress)
<< "000000000000000000000000"
<< toHex(jsToAddress(input.aliceAddress))
<< toHex(jsToBytes(input.bobHash))
@ -146,21 +199,29 @@ char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData
<< toHex(jsToBytes(input.aliceSecret));
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData)
std::stringstream bobSendsEthDepositData(BobSendsEthDepositInput input)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
u256 lockTime = input.lockTime;
std::stringstream ss;
ss << "0xc2c5143f"
ss << "0xdd23795f"
<< toHex(jsToBytes(input.depositId))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.aliceAddress))
<< toHex(jsToBytes(input.bobHash))
<< "000000000000000000000000";
<< "000000000000000000000000"
<< toHex(toBigEndian(lockTime));
return ss;
}
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsEthDepositData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
@ -168,44 +229,82 @@ char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData)
return result;
}
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData)
uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsEthDepositData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
printf("Bob deposit data %s != expected %s\n", data, ss.str().c_str());
return 0;
}
return 1;
}
std::stringstream bobSendsErc20DepositData(BobSendsErc20DepositInput input)
{
uint8_t decimals = getErc20Decimals(input.tokenAddress);
u256 amount = jsToU256(input.amount);
u256 lockTime = input.lockTime;
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
std::stringstream ss;
ss << "0xce8bbe4b"
ss << "0x5d567259"
<< toHex(jsToBytes(input.depositId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(amount))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.aliceAddress))
<< toHex(jsToBytes(input.bobHash))
<< "000000000000000000000000"
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress));
<< toHex(jsToAddress(input.tokenAddress))
<< toHex(toBigEndian(lockTime));
return ss;
}
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsErc20DepositData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
uint8_t verifyBobErc20DepositData(BobSendsErc20DepositInput input, char *data)
{
std::stringstream ss = bobSendsErc20DepositData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
printf("Bob deposit data %s != expected %s\n", data, ss.str().c_str());
return 0;
}
return 1;
}
char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss;
ss << "0x1dbe6508"
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0x1f7a72f7"
<< toHex(jsToBytes(input.depositId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(jsToU256(input.aliceCanClaimAfter)))
<< toHex(toBigEndian(amount))
<< toHex(jsToBytes(input.bobSecret))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.aliceAddress))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress))
<< "00000000000000000000000000000000000000000000000000000000000000c0"
<< "0000000000000000000000000000000000000000000000000000000000000020"
<< toHex(jsToBytes(input.bobSecret));
<< toHex(tokenAddress);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -214,77 +313,132 @@ char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss;
ss << "0x960173b5"
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0x4b915a68"
<< toHex(jsToBytes(input.depositId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(jsToU256(input.aliceCanClaimAfter)))
<< toHex(toBigEndian(amount))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.bobAddress))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress))
<< toHex(tokenAddress)
<< toHex(jsToBytes(input.bobHash))
<< "000000000000000000000000";
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData)
std::stringstream bobSendsEthPaymentData(BobSendsEthPaymentInput input)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
u256 lockTime = input.lockTime;
std::stringstream ss;
ss << "0xcf36fe8e"
ss << "0x5ab30d95"
<< toHex(jsToBytes(input.paymentId))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.aliceAddress))
<< toHex(jsToBytes(input.aliceHash))
<< "000000000000000000000000";
<< "000000000000000000000000"
<< toHex(toBigEndian(lockTime));
return ss;
}
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsEthPaymentData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData)
uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsEthPaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
printf("Bob payment data %s != expected %s\n", data, ss.str().c_str());
return 0;
}
return 1;
}
std::stringstream bobSendsErc20PaymentData(BobSendsErc20PaymentInput input)
{
uint8_t decimals = getErc20Decimals(input.tokenAddress);
u256 amount = jsToU256(input.amount);
u256 lockTime = input.lockTime;
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
std::stringstream ss;
ss << "0x34f64dfd"
ss << "0xb8a15b1d"
<< toHex(jsToBytes(input.paymentId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(amount))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.aliceAddress))
<< toHex(jsToBytes(input.aliceHash))
<< "000000000000000000000000"
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress));
<< toHex(jsToAddress(input.tokenAddress))
<< toHex(toBigEndian(lockTime));
return ss;
}
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsErc20PaymentData(input);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
uint8_t verifyBobErc20PaymentData(BobSendsErc20PaymentInput input, char *data)
{
std::stringstream ss = bobSendsErc20PaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
printf("Bob payment data %s != expected %s\n", data, ss.str().c_str());
return 0;
}
return 1;
}
char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss;
ss << "0xb7cc2312"
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0xe45ef4ad"
<< toHex(jsToBytes(input.paymentId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(jsToU256(input.bobCanClaimAfter)))
<< toHex(toBigEndian(amount))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.aliceAddress))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress))
<< toHex(tokenAddress)
<< toHex(jsToBytes(input.aliceHash))
<< "000000000000000000000000";
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -293,20 +447,25 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss;
ss << "0x97004255"
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0x113ee583"
<< toHex(jsToBytes(input.paymentId))
<< toHex(toBigEndian(jsToU256(input.amount)))
<< toHex(toBigEndian(jsToU256(input.bobCanClaimAfter)))
<< toHex(toBigEndian(amount))
<< toHex(jsToBytes(input.aliceSecret))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.bobAddress))
<< "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress))
<< "00000000000000000000000000000000000000000000000000000000000000c0"
<< "0000000000000000000000000000000000000000000000000000000000000020"
<< toHex(jsToBytes(input.aliceSecret));
<< toHex(tokenAddress);
tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx);
char* result = sendRawTxWaitConfirm(rawTx);
free(rawTx);
return result;
}
@ -339,12 +498,12 @@ uint64_t getEthBalance(char* address)
{
char* hexBalance = getEthBalanceRequest(address);
// convert wei to satoshi
u256 balance = jsToU256(hexBalance) / exp10<10>();
u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10);
free(hexBalance);
return static_cast<uint64_t>(balance);
}
uint64_t getErc20Balance(char* address, char* tokenAddress)
uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress)
{
std::stringstream ss;
ss << "0x70a08231"
@ -353,11 +512,54 @@ uint64_t getErc20Balance(char* address, char* tokenAddress)
std::stringstream& resultStream = *(new std::stringstream);
char* hexBalance = ethCall(tokenAddress, ss.str().c_str());
// convert wei to satoshi
u256 balance = jsToU256(hexBalance) / exp10<10>();
uint8_t decimals = getErc20Decimals(tokenAddress);
u256 balance = jsToU256(hexBalance);
if (decimals < 18) {
balance *= boost::multiprecision::pow(u256(10), 18 - decimals);
}
balance /= boost::multiprecision::pow(u256(10), 10);
free(hexBalance);
return static_cast<uint64_t>(balance);
}
char *getErc20BalanceHexWei(char *address, char *tokenAddress)
{
std::stringstream ss;
ss << "0x70a08231"
<< "000000000000000000000000"
<< toHex(jsToAddress(address));
char *hexBalance = ethCall(tokenAddress, ss.str().c_str());
return hexBalance;
}
uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress)
{
std::stringstream ss;
ss << "0xdd62ed3e"
<< "000000000000000000000000"
<< toHex(jsToAddress(owner))
<< "000000000000000000000000"
<< toHex(jsToAddress(spender));
char* hexAllowance = ethCall(tokenAddress, ss.str().c_str());
uint8_t decimals = getErc20Decimals(tokenAddress);
u256 allowance = jsToU256(hexAllowance);
if (decimals < 18) {
allowance *= boost::multiprecision::pow(u256(10), 18 - decimals);
}
// convert wei to satoshi
allowance /= boost::multiprecision::pow(u256(10), 10);
free(hexAllowance);
return static_cast<uint64_t>(allowance);
}
uint8_t getErc20Decimals(char *tokenAddress)
{
char* hexDecimals = ethCall(tokenAddress, "0x313ce567");
auto decimals = (uint8_t) strtol(hexDecimals, NULL, 0);
free(hexDecimals);
return decimals;
}
void uint8arrayToHex(char *dest, uint8_t *input, int len)
{
strcpy(dest, "0x");
@ -373,3 +575,82 @@ void satoshisToWei(char *dest, uint64_t input)
sprintf(dest, "%" PRIu64, input);
strcat(dest, "0000000000");
}
uint64_t weiToSatoshi(char *wei)
{
u256 satoshi = jsToU256(wei) / boost::multiprecision::pow(u256(10), 10);
return static_cast<uint64_t>(satoshi);
}
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm)
{
TransactionSkeleton tx;
char *from = privKey2Addr(privKey), *result;
tx.from = jsToAddress(from);
tx.to = jsToAddress(to);
tx.value = jsToU256(amount);
tx.gas = 21000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(from);
free(from);
char *rawTx = signTx(tx, privKey);
if (waitConfirm == 0) {
result = sendRawTx(rawTx);
} else {
result = sendRawTxWaitConfirm(rawTx);
}
free(rawTx);
return result;
}
std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount)
{
u256 amountWei = jsToU256(amount);
uint8_t decimals = getErc20Decimals(tokenAddress);
if (decimals < 18) {
amountWei /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
// convert wei to satoshi
std::stringstream ss;
ss << "0xa9059cbb"
<< "000000000000000000000000"
<< toHex(jsToAddress(to))
<< toHex(toBigEndian(amountWei));
return ss;
}
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm)
{
TransactionSkeleton tx;
char *from = privKey2Addr(privKey), *result;
tx.from = jsToAddress(from);
tx.to = jsToAddress(tokenAddress);
tx.value = 0;
tx.gas = 60000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(from);
free(from);
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount);
tx.data = jsToBytes(ss.str());
char *rawTx = signTx(tx, privKey);
if (waitConfirm == 0) {
result = sendRawTx(rawTx);
} else {
result = sendRawTxWaitConfirm(rawTx);
}
free(rawTx);
return result;
}
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data)
{
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount);
if (strcmp(ss.str().c_str(), data) != 0) {
printf("Alice ERC20 fee data %s is not equal to expected %s\n", data, ss.str().c_str());
return 0;
}
return 1;
}

69
iguana/exchanges/etomicswap/etomiclib.h

@ -6,19 +6,17 @@
#ifdef __cplusplus
extern "C" {
#endif
#define ETOMIC_TESTNET
#ifdef ETOMIC_TESTNET
#define ETOMIC_ALICECONTRACT "0xe1D4236C5774D35Dc47dcc2E5E0CcFc463A3289c"
#define ETOMIC_BOBCONTRACT "0x9387Fd3a016bB0205e4e131Dde886B9d2BC000A2"
#define ETOMIC_GASMULT 100
#define ETOMIC_ALICECONTRACT "0xe1d4236c5774d35dc47dcc2e5e0ccfc463a3289c"
#define ETOMIC_BOBCONTRACT "0x2a8e4f9ae69c86e277602c6802085febc4bd5986"
#else
#define ETOMIC_ALICECONTRACT "0x9bC5418CEdED51dB08467fc4b62F32C5D9EBdA55"
#define ETOMIC_BOBCONTRACT "0xB1Ad803ea4F57401639c123000C75F5B66E4D123"
#define ETOMIC_GASMULT 4
#define ETOMIC_ALICECONTRACT "0x9bc5418ceded51db08467fc4b62f32c5d9ebda55"
#define ETOMIC_BOBCONTRACT "0xfef736cfa3b884669a4e0efd6a081250cce228e7"
#endif
#define ETOMIC_SATOSHICAT "0000000000"
#define EMPTY_ETH_TX_ID "0x0000000000000000000000000000000000000000000000000000000000000000"
#define ETH_FEE_ACCEPTOR "0x485d2cc2d13a9e12e4b53d606db1c8adc884fb8a"
typedef struct {
char from[65];
@ -65,6 +63,7 @@ typedef struct {
char depositId[70];
char aliceAddress[65];
char bobHash[65];
uint64_t lockTime;
} BobSendsEthDepositInput;
typedef struct {
@ -73,6 +72,7 @@ typedef struct {
char tokenAddress[65];
char aliceAddress[65];
char bobHash[65];
uint64_t lockTime;
} BobSendsErc20DepositInput;
typedef struct {
@ -81,7 +81,6 @@ typedef struct {
char tokenAddress[65];
char aliceAddress[65];
char bobSecret[70];
char aliceCanClaimAfter[100];
} BobRefundsDepositInput;
typedef struct {
@ -90,13 +89,13 @@ typedef struct {
char tokenAddress[65];
char bobAddress[65];
char bobHash[65];
char aliceCanClaimAfter[100];
} AliceClaimsBobDepositInput;
typedef struct {
char paymentId[70];
char aliceAddress[65];
char aliceHash[65];
uint64_t lockTime;
} BobSendsEthPaymentInput;
typedef struct {
@ -105,6 +104,7 @@ typedef struct {
char tokenAddress[65];
char aliceAddress[65];
char aliceHash[65];
uint64_t lockTime;
} BobSendsErc20PaymentInput;
typedef struct {
@ -113,7 +113,6 @@ typedef struct {
char tokenAddress[65];
char aliceAddress[65];
char aliceHash[65];
char bobCanClaimAfter[100];
} BobReclaimsBobPaymentInput;
typedef struct {
@ -122,29 +121,67 @@ typedef struct {
char tokenAddress[65];
char aliceSecret[70];
char bobAddress[65];
char bobCanClaimAfter[100];
} AliceSpendsBobPaymentInput;
char* approveErc20(char amount[100], char* from, char* secret);
typedef struct {
char tokenAddress[65];
char owner[65];
char spender[65];
char amount[100];
char secret[70];
} ApproveErc20Input;
char *approveErc20(ApproveErc20Input input);
char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData);
uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data);
char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData);
uint8_t verifyAliceErc20PaymentData(AliceSendsErc20PaymentInput input, char *data);
char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData);
char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData);
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData);
uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data);
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData);
uint8_t verifyBobErc20DepositData(BobSendsErc20DepositInput input, char *data);
char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData);
char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData);
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData);
uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data);
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData);
uint8_t verifyBobErc20PaymentData(BobSendsErc20PaymentInput input, char *data);
char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData);
char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData);
char* privKey2Addr(char* privKey);
char* pubKey2Addr(char* pubKey);
char* getPubKeyFromPriv(char* privKey);
// returns satoshis, not wei!
uint64_t getEthBalance(char* address);
uint64_t getErc20Balance(char* address, char tokenAddress[65]);
uint64_t getErc20BalanceSatoshi(char* address, char tokenAddress[65]);
char *getErc20BalanceHexWei(char* address, char tokenAddress[65]);
uint8_t getErc20Decimals(char *tokenAddress);
// returns satoshis, not wei!
uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress);
void uint8arrayToHex(char *dest, uint8_t *input, int len);
void satoshisToWei(char *dest, uint64_t input);
uint64_t weiToSatoshi(char *wei);
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm);
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm);
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data);
// Your prototype or Definition
#ifdef __cplusplus
}

2
iguana/exchanges/install

@ -1,5 +1,5 @@
#!/bin/bash
cp install get_supernet trackbtc auto_chipskmd auto_chipsbtc pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx client_static run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp install updateprices get_supernet trackbtc auto_chipskmd auto_chipsbtc pendingswaps fundvalue balances dynamictrust getcoin kickstart tradesarray claim deposit10 deposit1 invreset sendrawtransaction processfiles stop millis mnzservers bot_buy bot_list bot_statuslist bot_pause bot_resume bot_sell bot_settings bot_status bot_stop guistats pubkeystats pendings coinswaps baserelswaps setpassphrase notarizations getrawtransaction parselog statsdisp m_js trust trusted setconfirms balance listunspent electrum snapshot_balance snapshot_loop secretaddresses dividends snapshot goals goal portfolio autoprice deletemessages getmessages debug buy sell bestfit orderbook client run_osx client_osx client_static run coins disable enable myprice myprices getcoins getpeers getpeersIP getprices help inv setprice status ../dexscripts
cp coins.json ..
cd ../dexscripts
#cp ../exchanges/passphrase ../exchanges/userpass .

6
iguana/exchanges/splitfunds

@ -0,0 +1,6 @@
#!/bin/bash
source userpass
export address=RGPido1EWcPWngDfkAcn4M4HXYt8avR4vs
export script=2103f82c8c363d23076420a39904f9616d59c26a3d8dc7c51f67d8d3a94335431970ac
curl --url "http://127.0.0.1:7783" --data "{\"broadcast\":1,\"userpass\":\"$userpass\",\"method\":\"withdraw\",\"coin\":\"$1\",\"outputs\":[{\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"$address\":0.0005,\"script\":\"$script\"}, {\"RGPido1EWcPWngDfkAcn4M4HXYt8avR4vs\":0.0001}]}"

1
iguana/iguana_payments.c

@ -464,6 +464,7 @@ char *iguana_calcrawtx(struct supernet_info *myinfo,struct iguana_info *coin,cJS
}
if ( strlen(spendscriptstr) != 50 || strncmp("76a914",spendscriptstr,6) != 0 || strcmp("88ac",&spendscriptstr[50-4]) != 0 )
continue;
//printf("utxo.(%s)\n",jprint(item,0));
unspents = realloc(unspents,(1 + max) * sizeof(*unspents));
value = jdouble(item,"amount") * SATOSHIDEN;
if ( (0) && jdouble(item,"interest") != 0 )

31
iguana/m_notary_testnet

@ -0,0 +1,31 @@
#!/bin/bash
pkill -15 iguana
rm -f ../agents/iguana *.o
git pull
cd secp256k1; ./m_unix; cd ..
cd ../crypto777; ./m_LP; cd ../iguana
clang -g -Wno-deprecated -c -O2 -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 *.c ../basilisk/basilisk.c ../gecko/gecko.c ../datachain/datachain.c
clang -g -Wno-deprecated -c -DISNOTARYNODE=1 -DLIQUIDITY_PROVIDER=1 main.c iguana777.c iguana_bundles.c ../basilisk/basilisk.c
clang -g -o ../agents/iguana *.o ../agents/libcrypto777.a -lnanomsg -lcurl -lssl -lcrypto -lpthread -lz -lm
wget -qO testnet https://raw.githubusercontent.com/KomodoPlatform/vote2018/master/testnet/testnet.json
../agents/iguana testnet & #> iguana.log 2> error.log &
myip=`curl -s4 checkip.amazonaws.com`
source pubkey.txt
sleep 4
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"SuperNET\",\"method\":\"myipaddr\",\"ipaddr\":\"$myip\"}"
sleep 3
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"145.239.204.33\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"167.114.116.173\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"167.99.16.61\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"172.104.107.94\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"208.79.81.98\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"139.99.148.62\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"addnotary\",\"ipaddr\":\"172.104.244.83\"}"
coins/btc_7776
coins/kmd_7776
./wp_7776
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"BEER.conf\",\"path\":\"${HOME#"/"}/.komodo/BEER\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"BEER\",\"name\":\"BEER\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"9fecbb6e\",\"p2p\":8922,\"rpc\":8923,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"
curl --url "http://127.0.0.1:7776" --data "{\"conf\":\"PIZZA.conf\",\"path\":\"${HOME#"/"}/.komodo/PIZZA\",\"unitval\":\"20\",\"zcash\":1,\"RELAY\":-1,\"VALIDATE\":0,\"prefetchlag\":-1,\"poll\":100,\"active\":1,\"agent\":\"iguana\",\"method\":\"addcoin\",\"startpend\":4,\"endpend\":4,\"services\":129,\"maxpeers\":8,\"newcoin\":\"PIZZA\",\"name\":\"PIZZA\",\"hasheaders\":1,\"useaddmultisig\":0,\"netmagic\":\"adbe523c\",\"p2p\":11607,\"rpc\":11608,\"pubval\":60,\"p2shval\":85,\"wifval\":188,\"txfee_satoshis\":\"10000\",\"isPoS\":0,\"minoutput\":10000,\"minconfirms\":2,\"genesishash\":\"027e3758c3a65b12aa1046462b486d0a63bfa1beae327897f56c5cfb7daaae71\",\"protover\":170002,\"genesisblock\":\"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a000000000000000000000000000000000000000000000000000000000000000029ab5f490f0f0f200b00000000000000000000000000000000000000000000000000000000000000fd4005000d5ba7cda5d473947263bf194285317179d2b0d307119c2e7cc4bd8ac456f0774bd52b0cd9249be9d40718b6397a4c7bbd8f2b3272fed2823cd2af4bd1632200ba4bf796727d6347b225f670f292343274cc35099466f5fb5f0cd1c105121b28213d15db2ed7bdba490b4cedc69742a57b7c25af24485e523aadbb77a0144fc76f79ef73bd8530d42b9f3b9bed1c135ad1fe152923fafe98f95f76f1615e64c4abb1137f4c31b218ba2782bc15534788dda2cc08a0ee2987c8b27ff41bd4e31cd5fb5643dfe862c9a02ca9f90c8c51a6671d681d04ad47e4b53b1518d4befafefe8cadfb912f3d03051b1efbf1dfe37b56e93a741d8dfd80d576ca250bee55fab1311fc7b3255977558cdda6f7d6f875306e43a14413facdaed2f46093e0ef1e8f8a963e1632dcbeebd8e49fd16b57d49b08f9762de89157c65233f60c8e38a1f503a48c555f8ec45dedecd574a37601323c27be597b956343107f8bd80f3a925afaf30811df83c402116bb9c1e5231c70fff899a7c82f73c902ba54da53cc459b7bf1113db65cc8f6914d3618560ea69abd13658fa7b6af92d374d6eca9529f8bd565166e4fcbf2a8dfb3c9b69539d4d2ee2e9321b85b331925df195915f2757637c2805e1d4131e1ad9ef9bc1bb1c732d8dba4738716d351ab30c996c8657bab39567ee3b29c6d054b711495c0d52e1cd5d8e55b4f0f0325b97369280755b46a02afd54be4ddd9f77c22272b8bbb17ff5118fedbae2564524e797bd28b5f74f7079d532ccc059807989f94d267f47e724b3f1ecfe00ec9e6541c961080d8891251b84b4480bc292f6a180bea089fef5bbda56e1e41390d7c0e85ba0ef530f7177413481a226465a36ef6afe1e2bca69d2078712b3912bba1a99b1fbff0d355d6ffe726d2bb6fbc103c4ac5756e5bee6e47e17424ebcbf1b63d8cb90ce2e40198b4f4198689daea254307e52a25562f4c1455340f0ffeb10f9d8e914775e37d0edca019fb1b9c6ef81255ed86bc51c5391e0591480f66e2d88c5f4fd7277697968656a9b113ab97f874fdd5f2465e5559533e01ba13ef4a8f7a21d02c30c8ded68e8c54603ab9c8084ef6d9eb4e92c75b078539e2ae786ebab6dab73a09e0aa9ac575bcefb29e930ae656e58bcb513f7e3c17e079dce4f05b5dbc18c2a872b22509740ebe6a3903e00ad1abc55076441862643f93606e3dc35e8d9f2caef3ee6be14d513b2e062b21d0061de3bd56881713a1a5c17f5ace05e1ec09da53f99442df175a49bd154aa96e4949decd52fed79ccf7ccbce32941419c314e374e4a396ac553e17b5340336a1a25c22f9e42a243ba5404450b650acfc826a6e432971ace776e15719515e1634ceb9a4a35061b668c74998d3dfb5827f6238ec015377e6f9c94f38108768cf6e5c8b132e0303fb5a200368f845ad9d46343035a6ff94031df8d8309415bb3f6cd5ede9c135fdabcc030599858d803c0f85be7661c88984d88faa3d26fb0e9aac0056a53f1b5d0baed713c853c4a2726869a0a124a8a5bbc0fc0ef80c8ae4cb53636aa02503b86a1eb9836fcc259823e2692d921d88e1ffc1e6cb2bde43939ceb3f32a611686f539f8f7c9f0bf00381f743607d40960f06d347d1cd8ac8a51969c25e37150efdf7aa4c2037a2fd0516fb444525ab157a0ed0a7412b2fa69b217fe397263153782c0f64351fbdf2678fa0dc8569912dcd8e3ccad38f34f23bbbce14c6a26ac24911b308b82c7e43062d180baeac4ba7153858365c72c63dcf5f6a5b08070b730adb017aeae925b7d0439979e2679f45ed2f25a7edcfd2fb77a8794630285ccb0a071f5cce410b46dbf9750b0354aae8b65574501cc69efb5b6a43444074fee116641bb29da56c2b4a7f456991fc92b2\",\"debug\":0,\"seedipaddr\":\"78.47.196.146\"}"
curl --url "http://127.0.0.1:7776" --data "{\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"KMD\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"BEER\",\"pubkey\":\"$pubkey\"}"
curl --url "http://127.0.0.1:7776" --data "{\"timeout\":60000,\"agent\":\"iguana\",\"method\":\"dpow\",\"symbol\":\"PIZZA\",\"pubkey\":\"$pubkey\"}"

2
iguana/secp256k1/CMakeLists.txt

@ -1,5 +1,5 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB sources "src/secp256k1.c")
file(GLOB headers "src/*.h")
add_definitions(-DHAVE_CONFIG_H)
add_definitions(-DHAVE_CONFIG_H -DEXTERNAL_SECP256)
add_library(libsecp256k1 ${sources} ${headers})

17
iguana/secp256k1/src/secp256k1.c

@ -66,6 +66,8 @@ struct secp256k1_context_struct {
secp256k1_callback error_callback;
};
#ifndef EXTERNAL_SECP256
secp256k1_context* secp256k1_context_create(unsigned int flags) {
secp256k1_context* ret = (secp256k1_context*)checked_malloc(&default_error_callback, sizeof(secp256k1_context));
ret->illegal_callback = default_illegal_callback;
@ -137,7 +139,7 @@ void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(co
ctx->error_callback.data = data;
}
static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) {
int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge, const secp256k1_pubkey* pubkey) {
if (sizeof(secp256k1_ge_storage) == 64) {
/* When the secp256k1_ge_storage type is exactly 64 byte, use its
* representation inside secp256k1_pubkey, as conversion is very fast.
@ -156,7 +158,8 @@ static int secp256k1_pubkey_load(const secp256k1_context* ctx, secp256k1_ge* ge,
return 1;
}
static void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) {
void secp256k1_pubkey_save(secp256k1_pubkey* pubkey, secp256k1_ge* ge) {
if (sizeof(secp256k1_ge_storage) == 64) {
secp256k1_ge_storage s;
secp256k1_ge_to_storage(&s, ge);
@ -577,14 +580,16 @@ int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *
# include "modules/ecdh/main_impl.h"
#endif
#ifdef ENABLE_MODULE_SCHNORR
# include "modules/schnorr/main_impl.h"
#endif
#ifdef ENABLE_MODULE_RECOVERY
# include "modules/recovery/main_impl.h"
#endif
#endif
#ifdef ENABLE_MODULE_SCHNORR
# include "modules/schnorr/main_impl.h"
#endif
#ifdef ENABLE_MODULE_RANGEPROOF
# include "modules/rangeproof/main_impl.h"
#endif

Loading…
Cancel
Save