Browse Source

Merge pull request #76 from artemii235/etomic

Etomic
pass-iguana-arg
Artem Pikulin 7 years ago
committed by GitHub
parent
commit
f532c1d27a
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      .dockerignore
  2. 8
      .gitignore
  3. 34
      .travis.yml
  4. 9
      Dockerfile.clientnode
  5. 9
      Dockerfile.seednode
  6. 53
      Jenkinsfile
  7. 32
      appveyor.yml
  8. 2
      cpp-ethereum
  9. 41
      docker-compose.yml
  10. 5
      etomic_build/client
  11. 4
      etomic_build/client/buy_BEER_OTHER
  12. 4
      etomic_build/client/client
  13. 7
      etomic_build/client/enable
  14. 1
      etomic_build/client/myipaddr
  15. 1
      etomic_build/client/passphrase
  16. 4
      etomic_build/client/setpassphrase
  17. 2
      etomic_build/client/userpass
  18. 2
      etomic_build/coins
  19. 1
      etomic_build/passphrase
  20. 5
      etomic_build/run
  21. 7
      etomic_build/seed/enable
  22. 1
      etomic_build/seed/myipaddr
  23. 1
      etomic_build/seed/passphrase
  24. 4
      etomic_build/seed/run
  25. 4
      etomic_build/seed/sell_BEER_OTHER
  26. 4
      etomic_build/seed/setpassphrase
  27. 2
      etomic_build/seed/userpass
  28. 7
      iguana/exchanges/CMakeLists.txt
  29. 18
      iguana/exchanges/LP_coins.c
  30. 46
      iguana/exchanges/LP_commands.c
  31. 145
      iguana/exchanges/LP_etomic.c
  32. 6
      iguana/exchanges/LP_include.h
  33. 16
      iguana/exchanges/LP_nativeDEX.c
  34. 4
      iguana/exchanges/LP_portfolio.c
  35. 6
      iguana/exchanges/LP_remember.c
  36. 5
      iguana/exchanges/LP_rpc.c
  37. 10
      iguana/exchanges/LP_signatures.c
  38. 33
      iguana/exchanges/LP_swap.c
  39. 96
      iguana/exchanges/LP_transaction.c
  40. 88
      iguana/exchanges/etomicswap/etomiccurl.c
  41. 9
      iguana/exchanges/etomicswap/etomiccurl.h
  42. 270
      iguana/exchanges/etomicswap/etomiclib.cpp
  43. 43
      iguana/exchanges/etomicswap/etomiclib.h
  44. 1
      iguana/exchanges/mm.c
  45. 60
      marketmaker_build_depends.cmd
  46. 7
      marketmaker_build_etomic.cmd
  47. 12
      start_BEER_OTHER_trade.sh
  48. 12
      start_BEER_OTHER_trade_inverted.sh

3
.dockerignore

@ -0,0 +1,3 @@
.git
.vscode
cmake-build-debug

8
.gitignore

@ -263,4 +263,12 @@ Release/*
build_win64_release/*
DB/*
.env.client
.env.seed
etomic_build/client/DB
etomic_build/client/stats.log
etomic_build/client/unparsed.txt
etomic_build/seed/DB
etomic_build/seed/stats.log
etomic_build/seed/unparsed.txt
iguana/exchanges/manychains

34
.travis.yml

@ -4,12 +4,6 @@ matrix:
include:
- os: linux
compiler: gcc
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-7
env: OS_NAME=Linux MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
- os: osx
compiler: clang
@ -17,14 +11,34 @@ matrix:
osx_image: xcode9.2
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y && sudo apt-get update && sudo apt-get install -y g++-7; fi
- git submodule update --init --recursive
script:
- export VERSION=`echo "$(git tag -l --points-at HEAD)"`
- mkdir build && cd build
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cmake -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 ..; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake ..; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then cmake -DMM_VERSION="$VERSION" -DCMAKE_C_COMPILER=/usr/bin/gcc-7 -DCMAKE_CXX_COMPILER=/usr/bin/g++-7 ..; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake -DMM_VERSION="$VERSION" ..; fi
- cmake --build . --target marketmaker-mainnet
- cmake --build . --target marketmaker-testnet
cache:
directories:
- $HOME/.hunter
apt: true
directories:
- $HOME/.hunter
before_deploy:
- export TAG=`echo "$(git rev-parse --short HEAD)"`
- mkdir deploy
- strip iguana/exchanges/marketmaker-mainnet
- strip iguana/exchanges/marketmaker-testnet
- tar -cvzf deploy/marketmaker-"$TRAVIS_OS_NAME"-"$TAG".tar.gz -C iguana/exchanges marketmaker-mainnet marketmaker-testnet
deploy:
provider: releases
api_key:
secure: "JDwFBGO4WLra9bXr2dsovet8y/ymC0Y+LJNr5/qlUIDt97zVytGbIlUc8BuI2VZFcnAvrtfOGdCs9m/PcLzZd4bMxXSsuaU0AJk/Vj9KzrIIGPJ4uS39KpO1USUpPW+5e0Bisf30JN3N2NypwMbMu42TKjVqaXSbVQfh79Iu6PdnyfiFbbTEfMeiRRrD72c00rwAw7kmndf7Sv9MiMN8WTFe0cQz5eH8GU/BSbnDorSrtClU4r7McR98zXaig/8XVcT543tcqdYW95QO7OqOjAid3XzzA/bPUTjC/nF/AyTJDco26nts0bCrCYeZRXIWdEInFLIeRHhHD7sW7dILRT/I7WlaLWnRtwo8e1L+U1k1yZ84dQMpgBznttdwH3vSj0crwCbFuMaRMMbPeW0H8C1VitLy1mlapw3RDI9yKlcw4V6WjPbz0YKhAoZgT/M/SaGr4ZkoWNCPoV5+Gub78p24Y8Y9BptJgj5t9KAcmDwbJ9wPt006ObWnbXvapo+6N5Dk2zuyQe9seoupzy4CAiNdluzAAVWsV/SjnN2aapjXoxaAaLQC6T8C1l1BpYri9LSKrjerr4QLVl/nw2yovAKNEobLLBVpSwfg4R72fu1BMS65gVsOqtFfs+R47CY+1D1Slev+UmKNMdE51+aXM+1XeC6wDUS5d13mW1NLhOE="
file_glob: true
file: "deploy/*"
on:
tags: true
skip_cleanup: true

9
Dockerfile.clientnode

@ -0,0 +1,9 @@
FROM ubuntu:17.10
USER root
RUN apt-get update && apt-get install -y rinetd curl libcurl3-gnutls
RUN echo "0.0.0.0 10271 10.100.0.1 10271" >> /etc/rinetd.conf
RUN echo "0.0.0.0 8923 10.100.0.1 8923" >> /etc/rinetd.conf
RUN useradd -u 111 jenkins
USER jenkins
WORKDIR /usr/mm/etomic_build/client
CMD /usr/sbin/rinetd && rm -rf DB && ./client

9
Dockerfile.seednode

@ -0,0 +1,9 @@
FROM ubuntu:17.10
USER root
RUN apt-get update && apt-get install -y rinetd curl libcurl3-gnutls
RUN echo "0.0.0.0 10271 10.100.0.1 10271" >> /etc/rinetd.conf
RUN echo "0.0.0.0 8923 10.100.0.1 8923" >> /etc/rinetd.conf
RUN useradd -u 111 jenkins
USER jenkins
WORKDIR /usr/mm/etomic_build/seed
CMD /usr/sbin/rinetd && rm -rf DB && ./run

53
Jenkinsfile

@ -1,11 +1,12 @@
pipeline {
agent {
docker {
image 'artempikulin/cmake-ubuntu'
}
}
agent any
stages {
stage('Prepare') {
steps {
sh '''cp -r /root/.env.client .env.client
cp -r /root/.env.seed .env.seed'''
}
}
stage('Build') {
steps {
sh '''git submodule update --init --recursive
@ -13,7 +14,45 @@ rm -rf build
mkdir build
cd build
cmake ..
cmake --build . --target marketmaker-testnet'''
cmake --build . --target marketmaker-testnet
cd ../
docker-compose build'''
}
}
stage('Trade BEER/ETH') {
steps {
sh '''docker-compose up -d
./start_BEER_OTHER_trade.sh ETH
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode)
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode)
docker-compose down'''
}
}
stage('Trade ETH/BEER') {
steps {
sh '''docker-compose up -d
./start_BEER_OTHER_trade_inverted.sh ETH
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode)
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode)
docker-compose down'''
}
}
stage('Trade BEER/ETOMIC') {
steps {
sh '''docker-compose up -d
./start_BEER_OTHER_trade.sh ETOMIC
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode)
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode)
docker-compose down'''
}
}
stage('Trade ETOMIC/BEER') {
steps {
sh '''docker-compose up -d
./start_BEER_OTHER_trade_inverted.sh ETOMIC
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f clientnode)
timeout 600 grep -q "SWAP completed" <(COMPOSE_HTTP_TIMEOUT=600 docker-compose logs -f seednode)
docker-compose down'''
}
}
}

32
appveyor.yml

@ -1,6 +1,30 @@
version: 1.0.{build}
branches:
only:
- etomic
build_script:
- cmd: marketmaker_build_etomic.cmd
- cmd: marketmaker_build_etomic.cmd
cache:
- C:\.hunter
- marketmaker_depends
after_build:
- '7z a mm-win.zip
.\build_win64_release\iguana\exchanges\Release\marketmaker-mainnet.exe
.\marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll
.\marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll
"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\redist\\x64\\Microsoft.VC140.CRT\\msvcp140.dll"
"C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\VC\\redist\\x64\\Microsoft.VC140.CRT\\vcruntime140.dll"'
artifacts:
- path: mm-win.zip
name: marketmaker-mainnet
deploy:
release: v$(appveyor_build_version)
provider: GitHub
auth_token:
secure: iabzoz73JgtOIyE/Nmz4a4XefmK+7pIeup+1Hunj4hGKrdfesFN+176DMApgfu8t
artifact: marketmaker-mainnet
draft: false
prerelease: false
on:
branch: master
appveyor_repo_tag: false

2
cpp-ethereum

@ -1 +1 @@
Subproject commit 633c62c08bc73c7c3935c948a8d6c656a3659976
Subproject commit e804e95d9a71e87fc5e3e69a2888448f23bc724f

41
docker-compose.yml

@ -0,0 +1,41 @@
version: '2'
services:
seednode:
build:
context: ./
dockerfile: Dockerfile.seednode
volumes:
- ~/.zcash-params:/home/jenkins/.zcash-params
- ~/.komodo:/home/jenkins/.komodo
- .:/usr/mm
env_file:
- .env.seed
tty: true
networks:
default:
ipv4_address: 10.100.0.2
clientnode:
build:
context: ./
dockerfile: Dockerfile.clientnode
volumes:
- ~/.zcash-params:/home/jenkins/.zcash-params
- ~/.komodo:/home/jenkins/.komodo
- .:/usr/mm
links:
- seednode
tty: true
env_file:
- .env.client
networks:
default:
ipv4_address: 10.100.0.3
networks:
default:
driver: bridge
ipam:
config:
- subnet: 10.100.0.0/16
gateway: 10.100.0.1

5
etomic_build/client

@ -1,5 +0,0 @@
#!/bin/bash
source passphrase
source coins
./stop
iguana/exchanges/marketmaker "{\"netid\":9999,\"seednode\":\"5.9.253.204\",\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

4
etomic_build/client/buy_BEER_OTHER

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"$1\",\"rel\":\"BEER\",\"price\":1}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"$1\",\"rel\":\"BEER\",\"basevolume\":0.1,\"price\":1}"

4
etomic_build/client/client

@ -0,0 +1,4 @@
#!/bin/bash
source passphrase
source ../coins
../../build/iguana/exchanges/marketmaker-testnet "{\"netid\":9999,\"seednode\":\"10.100.0.2\",\"gui\":\"nogui\",\"client\":1, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}"

7
etomic_build/client/enable

@ -0,0 +1,7 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"NODEC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JST\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}"

1
etomic_build/client/myipaddr

@ -0,0 +1 @@
10.100.0.3

1
etomic_build/client/passphrase

@ -0,0 +1 @@
export passphrase="$PASSPHRASE"

4
etomic_build/client/setpassphrase

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
source passphrase
curl --url "http://127.0.0.1:7783" --data "{\"netid\":9999,\"seednode\":\"10.100.0.2\",\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"passphrase\",\"passphrase\":\"$passphrase\",\"gui\":\"nogui\"}"

2
etomic_build/client/userpass

@ -0,0 +1,2 @@
#export userpass="<put the userpass value from the first API call here>"
export userpass="$USERPASS"

2
etomic_build/coins

File diff suppressed because one or more lines are too long

1
etomic_build/passphrase

@ -1 +0,0 @@
export passphrase="<put a very strong passphrase here>"

5
etomic_build/run

@ -1,5 +0,0 @@
#!/bin/bash
source passphrase
source coins
./stop
$1 iguana/exchanges/marketmaker "{\"netid\":9999,\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}" &

7
etomic_build/seed/enable

@ -0,0 +1,7 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETOMIC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"ETH\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"NODEC\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"JST\"}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"enable\",\"coin\":\"BEER\"}"

1
etomic_build/seed/myipaddr

@ -0,0 +1 @@
10.100.0.2

1
etomic_build/seed/passphrase

@ -0,0 +1 @@
export passphrase="$PASSPHRASE"

4
etomic_build/seed/run

@ -0,0 +1,4 @@
#!/bin/bash
source passphrase
source ../coins
../../build/iguana/exchanges/marketmaker-testnet "{\"netid\":9999,\"gui\":\"nogui\", \"profitmargin\":0.01, \"userhome\":\"/${HOME#"/"}\", \"passphrase\":\"$passphrase\", \"coins\":$coins}"

4
etomic_build/seed/sell_BEER_OTHER

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"setprice\",\"base\":\"BEER\",\"rel\":\"$1\",\"price\":0.9}"
curl --url "http://127.0.0.1:7783" --data "{\"userpass\":\"$userpass\",\"method\":\"sell\",\"base\":\"BEER\",\"rel\":\"$1\",\"basevolume\":0.1,\"price\":0.9}"

4
etomic_build/seed/setpassphrase

@ -0,0 +1,4 @@
#!/bin/bash
source userpass
source passphrase
curl --url "http://127.0.0.1:7783" --data "{\"netid\":9999,\"seednode\":\"5.9.253.204\",\"userpass\":\"1d8b27b21efabcd96571cd56f91a40fb9aa4cc623d273c63bf9223dc6f8cd81f\",\"method\":\"passphrase\",\"passphrase\":\"$passphrase\",\"gui\":\"nogui\"}"

2
etomic_build/seed/userpass

@ -0,0 +1,2 @@
#export userpass="<put the userpass value from the first API call here>"
export userpass="$USERPASS"

7
iguana/exchanges/CMakeLists.txt

@ -31,4 +31,9 @@ target_link_libraries(marketmaker-mainnet ${MM_LIBS} etomiclib-mainnet)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
target_link_libraries(marketmaker-mainnet -static-libgcc -static-libstdc++)
target_link_libraries(marketmaker-testnet -static-libgcc -static-libstdc++)
endif()
endif()
if(NOT DEFINED MM_VERSION)
SET(MM_VERSION UNKNOWN)
endif()
target_compile_definitions(marketmaker-mainnet PRIVATE -DMM_VERSION="${MM_VERSION}")
target_compile_definitions(marketmaker-testnet PRIVATE -DMM_VERSION="${MM_VERSION}")

18
iguana/exchanges/LP_coins.c

@ -251,10 +251,13 @@ cJSON *LP_coinjson(struct iguana_info *coin,int32_t showwif)
}
#ifndef NOTETOMIC
else if (coin->etomic[0] != 0) {
//balance = LP_etomic_get_balance(coin, coin->smartaddr);
if (coin->inactive == 0) {
balance = LP_etomic_get_balance(coin, coin->smartaddr);
} else {
balance = 0;
}
jaddnum(item,"height",-1);
//jaddnum(item,"balance",dstr(balance));
jaddnum(item,"balance",0);
jaddnum(item,"balance",dstr(balance));
}
#endif
else
@ -374,7 +377,7 @@ struct iguana_info *LP_coinadd(struct iguana_info *cdata)
}
void *curl_easy_init();
uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath)
uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *assetname,int32_t isPoS,uint16_t port,uint8_t pubtype,uint8_t p2shtype,uint8_t wiftype,uint64_t txfee,double estimatedrate,int32_t longestchain,uint8_t wiftaddr,uint8_t taddr,uint16_t busport,char *confpath,uint8_t decimals)
{
static void *ctx;
char *name2; uint16_t origport = port;
@ -437,6 +440,7 @@ uint16_t LP_coininit(struct iguana_info *coin,char *symbol,char *name,char *asse
}
coin->curl_handle = curl_easy_init();
portable_mutex_init(&coin->curl_mutex);
coin->decimals = decimals;
return(port);
}
@ -480,7 +484,7 @@ struct iguana_info *LP_coinfind(char *symbol)
else if ( strcmp(symbol,"KMD") == 0 )
name = "komodo";
else return(0);
port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0);
port = LP_coininit(&cdata,symbol,name,assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,0,0,busport,0,0);
if ( port == 0 )
isinactive = 1;
else isinactive = 0;
@ -522,7 +526,9 @@ struct iguana_info *LP_coincreate(cJSON *item)
}
else if ( (name= jstr(item,"name")) == 0 )
name = symbol;
if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath")) < 0 )
uint8_t decimals = juint(item,"decimals");
if ( LP_coininit(&cdata,symbol,name,assetname==0?"":assetname,isPoS,port,pubtype,p2shtype,wiftype,txfee,estimatedrate,longestchain,juint(item,"wiftaddr"),juint(item,"taddr"),LP_busport(port),jstr(item,"confpath"),decimals) < 0 )
{
coin = LP_coinadd(&cdata);
coin->inactive = (uint32_t)time(NULL);

46
iguana/exchanges/LP_commands.c

@ -120,6 +120,7 @@ cancel(uuid)\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[], broadcast=0)\n\
eth_withdraw(coin, to, amount, gas, gas_price, broadcast=0)\n\
txblast(coin, utxotxid, utxovout, utxovalue, txfee, passphrase, outputs[], broadcast=0)\n\
sendrawtransaction(coin, signedtx)\n\
swapstatus(pending=0, fast=0)\n\
@ -176,7 +177,13 @@ getfee(coin)\n\
sleep(seconds=60)\n\
listtransactions(coin, address, count=10, skip=0)\n\
jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
version\n\
\"}"));
if ( strcmp(method,"version") == 0 ) {
retjson = cJSON_CreateObject();
jaddstr(retjson,"result",MM_VERSION);
return(jprint(retjson,1));
}
if ( (base= jstr(argjson,"base")) == 0 )
base = "";
@ -232,9 +239,14 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
{
if ( (ptr= LP_coinsearch("KMD")) != 0 )
{
if ( jint(argjson,"weeks") <= 0 || jdouble(argjson,"amount") < 10. )
return(clonestr("{\"error\":\"instantdex_deposit needs to have weeks and amount\"}"));
else return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1));
if ( jint(argjson,"weeks") <= 0 ) {
return(clonestr("{\"error\":\"instantdex_deposit weeks param must be greater than zero\"}"));
}
if ( jdouble(argjson,"amount") < 10. ) {
return(clonestr("{\"error\":\"instantdex_deposit amount param must be equal or greater than 10\"}"));
}
return(LP_instantdex_deposit(ptr,juint(argjson,"weeks"),jdouble(argjson,"amount"),jobj(argjson,"broadcast") != 0 ? jint(argjson,"broadcast") : 1));
}
return(clonestr("{\"error\":\"cant find KMD\"}"));
}
@ -396,11 +408,6 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
jaddbits256(retjson,"privkey",privkey);
bitcoin_priv2wif(coin,wiftaddr,wifstr,privkey,wiftype);
jaddstr(retjson,"wif",wifstr);
#ifndef NOTETOMIC
char ethaddr[50];
LP_etomic_pubkeystr_to_addr(pubsecp, ethaddr);
jaddstr(retjson,"ethaddr",ethaddr);
#endif
return(jprint(retjson,1));
} else return(clonestr("{\"error\":\"need to have passphrase\"}"));
}
@ -456,6 +463,12 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
}
else if ( strcmp(method,"inuse") == 0 )
return(jprint(LP_inuse_json(),1));
#ifndef NOTETOMIC
else if ( strcmp(method,"eth_gas_price") == 0 )
{
return LP_eth_gas_price();
}
#endif
else if ( (retstr= LP_istradebots_command(ctx,pubsock,method,argjson)) != 0 )
return(retstr);
if ( base[0] != 0 && rel[0] != 0 )
@ -584,6 +597,23 @@ jpg(srcfile, destfile, power2=7, password, data="", required, ind=0)\n\
jaddstr(retjson,"coin",coin);
return(jprint(retjson,1));
}
#ifndef NOT_ETOMIC
if (strcmp(coin, "ETOMIC") == 0) {
char eth_addr[100];
bits256 privkey = LP_privkey("ETOMIC", ptr->smartaddr, ptr->taddr);
LP_etomic_priv2addr(eth_addr, privkey);
if (get_etomic_from_faucet(eth_addr, ptr->smartaddr) != 1) {
return(clonestr("{\"error\":\"Could not get ETOMIC from faucet!\"}"));
}
}
if (ptr->etomic[0] != 0) {
struct iguana_info *etomic_coin = LP_coinsearch("ETOMIC");
if (etomic_coin->inactive != 0) {
return(clonestr("{\"error\":\"Enable ETOMIC first to use ETH/ERC20!\"}"));
}
}
#endif
if ( LP_conflicts_find(ptr) == 0 )
{
cJSON *array;

145
iguana/exchanges/LP_etomic.c

@ -22,6 +22,9 @@
// Created by artem on 24.01.18.
//
#include "LP_etomic.h"
#define ALICE_PAYMENT_SENT 1
#define BOB_DEPOSIT_SENT 1
#define BOB_PAYMENT_SENT 1
int32_t LP_etomic_wait_for_confirmation(char *txId)
{
@ -38,13 +41,15 @@ void LP_etomic_pubkeystr_to_addr(char *pubkey, char *output)
char *LP_etomicalice_send_fee(struct basilisk_swap *swap)
{
char amount[100], secretKey[70], dexaddr[50];
satoshisToWei(amount, swap->myfee.I.amount);
satoshisToWei(amount, LP_DEXFEE(swap->I.alicerealsat));
uint8arrayToHex(secretKey, swap->persistent_privkey.bytes, 32);
LP_etomic_pubkeystr_to_addr(INSTANTDEX_PUBKEY, dexaddr);
if (strcmp(swap->I.alicestr,"ETH") == 0 ) {
return(sendEth(dexaddr, amount, secretKey, 1));
return(sendEth(dexaddr, amount, secretKey, 1, 0, 0, 1));
} else {
return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1));
struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
return(sendErc20(swap->I.alicetomic, dexaddr, amount, secretKey, 1, 0, 0, 1, alicecoin->decimals));
}
}
@ -68,19 +73,21 @@ uint8_t LP_etomic_verify_alice_fee(struct basilisk_swap *swap)
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);
if (txValue != LP_DEXFEE(swap->I.alicerealsat)) {
printf("Alice fee %s amount %" PRIu64 " is not equal to expected %" PRId64 "\n", swap->otherfee.I.ethTxid, txValue, LP_DEXFEE(swap->I.alicerealsat));
return(0);
}
return(1);
} else {
struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
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, dexaddr, weiAmount, data.input));
satoshisToWei(weiAmount, LP_DEXFEE(swap->I.alicerealsat));
return(verifyAliceErc20FeeData(swap->I.alicetomic, dexaddr, weiAmount, data.input, alicecoin->decimals));
}
}
@ -100,28 +107,31 @@ char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
strcpy(txData.from, swap->I.etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT);
satoshisToWei(txData.amount, swap->I.alicesatoshis);
satoshisToWei(txData.amount, swap->I.alicerealsat);
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return(aliceSendsEthPayment(input,txData));
}
else
{
struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
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);
satoshisToWei(input20.amount, swap->I.alicerealsat);
input20.decimals = alicecoin->decimals;
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) {
uint64_t allowance = getErc20Allowance(swap->I.etomicdest, ETOMIC_ALICECONTRACT, swap->I.alicetomic, alicecoin->decimals);
if (allowance < swap->I.alicerealsat) {
printf("Alice token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.alicetomic);
@ -161,8 +171,8 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
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);
if (paymentAmount != swap->I.alicerealsat) {
printf("Alice payment amount %" PRIu64 " does not match expected %" PRIu64 "\n", paymentAmount, swap->I.alicerealsat);
return(0);
}
memset(&input,0,sizeof(input));
@ -173,13 +183,16 @@ uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
return(verifyAliceEthPaymentData(input, data.input));
} else {
struct iguana_info *alicecoin = LP_coinfind(swap->I.alicestr);
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);
satoshisToWei(input20.amount, swap->I.alicerealsat);
input20.decimals = alicecoin->decimals;
return(verifyAliceErc20PaymentData(input20, data.input));
}
@ -201,13 +214,18 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input));
struct iguana_info *ecoin;
struct iguana_info *ecoin, *alice_coin;
bits256 privkey;
ecoin = LP_coinfind("ETOMIC");
alice_coin = LP_coinfind(swap->dest);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.dealId, swap->txids[BASILISK_ALICEPAYMENT].bytes, 32);
satoshisToWei(input.amount, swap->destamount);
if (alicePaymentStatus(input.dealId + 2) != ALICE_PAYMENT_SENT) {
printf("Alice payment smart contract status check failed, can't spend\n");
return NULL;
}
satoshisToWei(input.amount, swap->alicerealsat);
if (swap->alicetomic[0] != 0) {
strcpy(input.tokenAddress, swap->alicetomic);
@ -223,6 +241,8 @@ char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
}
uint8arrayToHex(input.bobSecret, invertedSecret.bytes, 32);
input.decimals = alice_coin->decimals;
strcpy(txData.from, swap->etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT);
strcpy(txData.amount, "0");
@ -253,7 +273,12 @@ char *LP_etomicbob_spends_alice_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->destamount);
if (alicePaymentStatus(input.dealId + 2) != ALICE_PAYMENT_SENT) {
printf("Alice payment smart contract status check failed, can't spend\n");
return NULL;
}
satoshisToWei(input.amount, swap->alicerealsat);
if (swap->alicetomic[0] != 0) {
strcpy(input.tokenAddress, swap->alicetomic);
@ -268,6 +293,8 @@ char *LP_etomicbob_spends_alice_payment(struct LP_swap_remember *swap)
}
uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32);
uint8arrayToHex(input.bobHash, swap->secretBn, 20);
struct iguana_info *alice_coin = LP_coinfind(swap->dest);
input.decimals = alice_coin->decimals;
strcpy(txData.from, swap->etomicsrc);
strcpy(txData.to, ETOMIC_ALICECONTRACT);
@ -292,24 +319,27 @@ char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap)
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
satoshisToWei(txData.amount, swap->bobdeposit.I.amount);
satoshisToWei(txData.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return bobSendsEthDeposit(input, txData);
} else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
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);
satoshisToWei(input20.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobdeposit.I.locktime;
input20.decimals = bobcoin->decimals;
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) {
uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic, bobcoin->decimals);
if (allowance < LP_DEPOSITSATOSHIS(swap->I.bobrealsat)) {
printf("Bob token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic);
@ -351,8 +381,8 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
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);
if (depositAmount != LP_DEPOSITSATOSHIS(swap->I.bobrealsat)) {
printf("Bob deposit %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, depositAmount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
return(0);
}
uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
@ -362,12 +392,15 @@ uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
return verifyBobEthDepositData(input, data.input);
} else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
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);
satoshisToWei(input20.amount, LP_DEPOSITSATOSHIS(swap->I.bobrealsat));
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobdeposit.I.locktime;
input20.decimals = bobcoin->decimals;
return verifyBobErc20DepositData(input20, data.input);
}
@ -384,9 +417,10 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input));
struct iguana_info *ecoin;
struct iguana_info *ecoin, *bobcoin;
bits256 privkey;
ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
EthTxReceipt receipt = getEthTxReceipt(swap->bobDepositEthTx);
@ -395,6 +429,11 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
return NULL;
}
uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32);
if (bobDepositStatus(input.depositId + 2) != BOB_DEPOSIT_SENT) {
printf("Bob deposit smart contract status check failed, can't claim\n");
return NULL;
}
strcpy(input.aliceAddress, swap->etomicdest);
bits256 invertedSecret;
@ -409,7 +448,8 @@ char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
} else {
strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000");
}
satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]);
satoshisToWei(input.amount, LP_DEPOSITSATOSHIS(swap->bobrealsat));
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -435,24 +475,27 @@ char *LP_etomicbob_sends_payment(struct basilisk_swap *swap)
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
satoshisToWei(txData.amount, swap->bobpayment.I.amount);
satoshisToWei(txData.amount, swap->I.bobrealsat);
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return bobSendsEthPayment(input, txData);
} else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
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);
satoshisToWei(input20.amount, swap->I.bobrealsat);
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobpayment.I.locktime;
input20.decimals = bobcoin->decimals;
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) {
uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, ETOMIC_BOBCONTRACT, swap->I.bobtomic, bobcoin->decimals);
if (allowance < swap->I.bobrealsat) {
printf("Bob token allowance is too low, setting new allowance\n");
ApproveErc20Input approveErc20Input;
strcpy(approveErc20Input.tokenAddress, swap->I.bobtomic);
@ -493,8 +536,8 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId)
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);
if (paymentAmount != swap->I.bobrealsat) {
printf("Bob payment %s amount %" PRIu64 " != expected %" PRIu64 "\n", txId, paymentAmount, swap->I.bobrealsat);
return(0);
}
uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
@ -504,12 +547,15 @@ uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId)
return verifyBobEthPaymentData(input, data.input);
} else {
struct iguana_info *bobcoin = LP_coinfind(swap->I.bobstr);
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);
satoshisToWei(input20.amount, swap->I.bobrealsat);
strcpy(input20.tokenAddress, swap->I.bobtomic);
input20.lockTime = swap->bobpayment.I.locktime;
input20.decimals = bobcoin->decimals;
return verifyBobErc20PaymentData(input20, data.input);
}
@ -526,9 +572,10 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input));
struct iguana_info *ecoin;
struct iguana_info *ecoin, *bobcoin;
bits256 privkey;
ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
EthTxReceipt receipt = getEthTxReceipt(swap->bobPaymentEthTx);
@ -537,6 +584,10 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
return NULL;
}
uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32);
if (bobPaymentStatus(input.paymentId + 2) != BOB_PAYMENT_SENT) {
printf("Bob payment smart contract status check failed, can't spend\n");
return NULL;
}
strcpy(input.aliceAddress, swap->etomicdest);
uint8arrayToHex(input.aliceHash, swap->secretAm, 20);
@ -545,7 +596,8 @@ char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
} else {
strcpy(input.tokenAddress, "0x0000000000000000000000000000000000000000");
}
satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]);
satoshisToWei(input.amount, swap->bobrealsat);
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -570,13 +622,18 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
printf("Bob payment %s receipt status failed, can't spend\n", swap->bobPaymentEthTx);
return NULL;
}
struct iguana_info *ecoin;
struct iguana_info *ecoin, *bobcoin;
bits256 privkey;
ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.paymentId, swap->txids[BASILISK_BOBPAYMENT].bytes, 32);
satoshisToWei(input.amount, swap->values[BASILISK_BOBPAYMENT]);
if (bobPaymentStatus(input.paymentId + 2) != BOB_PAYMENT_SENT) {
printf("Bob payment smart contract status check failed, can't spend\n");
return NULL;
}
satoshisToWei(input.amount, swap->bobrealsat);
if (swap->bobtomic[0] != 0) {
strcpy(input.tokenAddress, swap->bobtomic);
@ -591,6 +648,7 @@ char *LP_etomicalice_spends_bob_payment(struct LP_swap_remember *swap)
invertedSecret.bytes[i] = swap->privAm.bytes[31 - i];
}
uint8arrayToHex(input.aliceSecret, invertedSecret.bytes, 32);
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicdest);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -616,13 +674,19 @@ char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap)
return NULL;
}
struct iguana_info *ecoin;
struct iguana_info *ecoin, *bobcoin;
bits256 privkey;
ecoin = LP_coinfind("ETOMIC");
bobcoin = LP_coinfind(swap->src);
privkey = LP_privkey(ecoin->symbol, ecoin->smartaddr, ecoin->taddr);
uint8arrayToHex(input.depositId, swap->txids[BASILISK_BOBDEPOSIT].bytes, 32);
satoshisToWei(input.amount, swap->values[BASILISK_BOBDEPOSIT]);
if (bobDepositStatus(input.depositId + 2) != BOB_DEPOSIT_SENT) {
printf("Bob deposit smart contract status check failed, can't claim\n");
return NULL;
}
satoshisToWei(input.amount, LP_DEPOSITSATOSHIS(swap->bobrealsat));
if (swap->bobtomic[0] != 0) {
strcpy(input.tokenAddress, swap->bobtomic);
@ -632,6 +696,7 @@ char *LP_etomicalice_claims_bob_deposit(struct LP_swap_remember *swap)
strcpy(input.bobAddress, swap->etomicsrc);
uint8arrayToHex(input.bobHash, swap->secretBn, 20);
input.decimals = bobcoin->decimals;
strcpy(txData.from, swap->etomicdest);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
@ -718,6 +783,6 @@ uint64_t LP_etomic_get_balance(struct iguana_info *coin, char *coinaddr)
if (strcmp(coin->symbol, "ETH") == 0) {
return getEthBalance(coinaddr);
} else {
return getErc20BalanceSatoshi(coinaddr, coin->etomic);
return getErc20BalanceSatoshi(coinaddr, coin->etomic, coin->decimals);
}
}

6
iguana/exchanges/LP_include.h

@ -241,7 +241,7 @@ struct basilisk_swapinfo
bits256 myhash,otherhash,orderhash;
uint32_t statebits,otherstatebits,started,expiration,finished,dead,reftime,putduration,callduration;
int32_t bobconfirms,aliceconfirms,iambob,reclaimed,bobspent,alicespent,pad,aliceistrusted,bobistrusted,otheristrusted,otherstrust,alicemaxconfirms,bobmaxconfirms;
int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee;
int64_t alicesatoshis,bobsatoshis,bobinsurance,aliceinsurance,Atxfee,Btxfee,alicerealsat,bobrealsat;
bits256 myprivs[2],mypubs[2],otherpubs[2],pubA0,pubA1,pubB0,pubB1,privAm,pubAm,privBn,pubBn;
uint32_t crcs_mypub[2],crcs_mychoosei[2],crcs_myprivs[2],crcs_mypriv[2];
@ -273,7 +273,7 @@ static char *txnames[] = { "alicespend", "bobspend", "bobpayment", "alicepayment
struct LP_swap_remember
{
bits256 pubA0,pubB0,pubB1,privAm,privBn,paymentspent,Apaymentspent,depositspent,myprivs[2],txids[sizeof(txnames)/sizeof(*txnames)];
uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid;
uint64_t Atxfee,Btxfee,srcamount,destamount,aliceid,alicerealsat,bobrealsat;
int64_t values[sizeof(txnames)/sizeof(*txnames)];
uint32_t finishtime,tradeid,requestid,quoteid,plocktime,dlocktime,expiration,state,otherstate;
int32_t iambob,finishedflag,origfinishedflag,Predeemlen,Dredeemlen,sentflags[sizeof(txnames)/sizeof(*txnames)];
@ -312,7 +312,7 @@ struct iguana_info
double price_kmd,force,perc,goal,goalperc,relvolume,rate;
void *electrum; void *ctx;
uint64_t maxamount,kmd_equiv,balanceA,balanceB,valuesumA,valuesumB;
uint8_t pubkey33[33],zcash;
uint8_t pubkey33[33],zcash,decimals;
int32_t privkeydepth;
void *curl_handle; portable_mutex_t curl_mutex;
bits256 cachedtxid,notarizationtxid; uint8_t *cachedtxiddata; int32_t cachedtxidlen;

16
iguana/exchanges/LP_nativeDEX.c

@ -30,6 +30,9 @@
// there is an issue about waiting for notarization for a swap that never starts (expiration ok)
#include <stdio.h>
#ifndef MM_VERSION
#define MM_VERSION "UNKNOWN"
#endif
long LP_cjson_allocated,LP_cjson_total,LP_cjson_count;
@ -117,7 +120,7 @@ struct LP_globals
{
//struct LP_utxoinfo *LP_utxoinfos[2],*LP_utxoinfos2[2];
bits256 LP_mypub25519,LP_privkey,LP_mypriv25519,LP_passhash;
uint64_t LP_skipstatus[10000];
uint64_t LP_skipstatus[10000], LP_required_etomic_balance;
uint16_t netid;
uint8_t LP_myrmd160[20],LP_pubsecp[33];
uint32_t LP_sessionid,counter;
@ -1393,8 +1396,7 @@ extern int32_t bitcoind_RPC_inittime;
void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybusport,char *passphrase,int32_t amclient,char *userhome,cJSON *argjson)
{
char *myipaddr=0,version[64]; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx();
sprintf(version,"Marketmaker %s.%s %s rsize.%ld",LP_MAJOR_VERSION,LP_MINOR_VERSION,LP_BUILD_NUMBER,sizeof(struct basilisk_request));
char *myipaddr=0; long filesize,n; int32_t valid,timeout; struct LP_peerinfo *mypeer=0; char pushaddr[128],subaddr[128],bindaddr[128],*coins_str=0; cJSON *coinsjson=0; void *ctx = bitcoin_ctx();
bitcoind_RPC_inittime = 1;
if ( LP_MAXPRICEINFOS > 256 )
{
@ -1402,7 +1404,7 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
exit(-1);
}
LP_showwif = juint(argjson,"wif");
printf("showwif.%d %s %u\n",LP_showwif,version,calc_crc32(0,version,(int32_t)strlen(version)));
printf("showwif.%d version: %s %u\n",LP_showwif,MM_VERSION,calc_crc32(0,MM_VERSION,(int32_t)strlen(MM_VERSION)));
if ( passphrase == 0 || passphrase[0] == 0 )
{
printf("jeezy says we cant use the nullstring as passphrase and I agree\n");
@ -1476,10 +1478,10 @@ void LPinit(uint16_t myport,uint16_t mypullport,uint16_t mypubport,uint16_t mybu
myipaddr = clonestr("127.0.0.1");
#ifndef _WIN32
#ifndef FROM_JS
if ( system("curl -s4 checkip.amazonaws.com > myipaddr") == 0 )
char ipfname[64];
strcpy(ipfname,"myipaddr");
if ( access( ipfname, F_OK ) != -1 || system("curl -s4 checkip.amazonaws.com > myipaddr") == 0 )
{
char ipfname[64];
strcpy(ipfname,"myipaddr");
if ( (myipaddr= OS_filestr(&filesize,ipfname)) != 0 && myipaddr[0] != 0 )
{
n = strlen(myipaddr);

4
iguana/exchanges/LP_portfolio.c

@ -95,14 +95,12 @@ 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) {
if (coin->etomic[0] != 0 && coin->inactive == 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 )

6
iguana/exchanges/LP_remember.c

@ -80,6 +80,9 @@ void basilisk_dontforget(struct basilisk_swap *swap,struct basilisk_rawtx *rawtx
fprintf(fp,",\"alicePaymentEthTx\":\"%s\"", swap->alicepayment.I.ethTxid);
}
fprintf(fp,",\"aliceRealSat\":\"%" PRId64 "\"", swap->I.alicerealsat);
fprintf(fp,",\"bobRealSat\":\"%" PRId64 "\"", swap->I.bobrealsat);
fprintf(fp,",\"alicecoin\":\"%s\"",swap->I.alicestr);
if ( swap->I.alicetomic[0] != 0 )
fprintf(fp,",\"alicetomic\":\"%s\"",swap->I.alicetomic);
@ -921,6 +924,9 @@ int32_t LP_swap_load(struct LP_swap_remember *rswap,int32_t forceflag)
strcpy(rswap->alicetomic, jstr(txobj,"alicetomic"));
}
rswap->bobrealsat = jint(txobj, "bobRealSat");
rswap->alicerealsat = jint(txobj, "aliceRealSat");
rswap->txids[i] = txid;
if ( jstr(txobj,"Apayment") != 0 )
safecopy(rswap->alicepaymentaddr,jstr(txobj,"Apayment"),sizeof(rswap->alicepaymentaddr));

5
iguana/exchanges/LP_rpc.c

@ -137,6 +137,11 @@ int32_t LP_getheight(int32_t *notarizedp,struct iguana_info *coin)
uint64_t LP_RTsmartbalance(struct iguana_info *coin)
{
#ifndef NOTETOMIC
if (coin->etomic[0] != 0) {
return LP_etomic_get_balance(coin, coin->smartaddr);
}
#endif
cJSON *array,*item; char buf[512],*retstr; int32_t i,n; uint64_t valuesum,value; bits256 zero;
valuesum = 0;
memset(zero.bytes,0,sizeof(zero));

10
iguana/exchanges/LP_signatures.c

@ -442,6 +442,16 @@ char *LP_pricepings(void *ctx,char *myipaddr,int32_t pubsock,char *base,char *re
jaddstr(reqjson,"pubsecp",pubsecpstr);
if ( (kmd= LP_coinfind("KMD")) != 0 && (ap= LP_address(kmd,kmd->smartaddr)) != 0 && ap->instantdex_credits != 0 )
jaddnum(reqjson,"credits",dstr(ap->instantdex_credits));
#ifndef NOTETOMIC
if (basecoin->etomic[0] != 0) {
uint64_t etomic_coin_balance = LP_etomic_get_balance(basecoin, basecoin->smartaddr);
jaddstr(reqjson,"utxocoin","ETH_OR_ERC20");
jaddnum(reqjson,"bal",dstr(etomic_coin_balance));
jaddnum(reqjson,"min",dstr(etomic_coin_balance));
jaddnum(reqjson,"max",dstr(etomic_coin_balance));
jaddnum(reqjson,"n",1);
} else
#endif
if ( (numutxos= LP_address_minmax(1,&median,&minsize,&maxsize,basecoin,basecoin->smartaddr)) != 0 )
{
//printf("send %s numutxos.%d median %.8f min %.8f max %.8f\n",base,numutxos,dstr(median),dstr(minsize),dstr(maxsize));

33
iguana/exchanges/LP_swap.c

@ -854,7 +854,16 @@ void LP_bobloop(void *_swap)
expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT;
bobwaittimeout = LP_calc_waittimeout(bobstr);
alicewaittimeout = LP_calc_waittimeout(alicestr);
if ( swap != 0 )
#ifndef NOTETOMIC
if (swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0) {
uint64_t eth_balance = getEthBalance(swap->I.etomicsrc);
if (eth_balance < 500000) {
err = -5000, printf("Bob ETH balance too low, aborting swap!\n");
}
}
#endif
if ( swap != 0 && err == 0)
{
if ( LP_waitsend("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
err = -2000, printf("error waitsend pubkeys\n");
@ -948,7 +957,17 @@ void LP_aliceloop(void *_swap)
expiration = (uint32_t)time(NULL) + LP_SWAPSTEP_TIMEOUT;
bobwaittimeout = LP_calc_waittimeout(bobstr);
alicewaittimeout = LP_calc_waittimeout(alicestr);
if ( swap != 0 )
#ifndef NOTETOMIC
if (swap->I.bobtomic[0] != 0 || swap->I.alicetomic[0] != 0) {
uint64_t eth_balance = getEthBalance(swap->I.etomicdest);
if (eth_balance < 500000) {
err = -5001, printf("Alice ETH balance too low, aborting swap!\n");
}
}
#endif
if ( swap != 0 && err == 0)
{
printf("start swap iamalice pair.%d\n",swap->N.pair);
if ( LP_sendwait("pubkeys",120,swap->N.pair,swap,data,maxlen,LP_pubkeys_verify,LP_pubkeys_data) < 0 )
@ -1179,6 +1198,16 @@ struct basilisk_swap *bitcoin_swapinit(bits256 privkey,uint8_t *pubkey33,bits256
free(swap);
return(0);
}
#ifndef NOTETOMIC
if (strcmp(alicestr, "ETOMIC") == 0) {
swap->I.alicerealsat = swap->I.alicesatoshis;
swap->I.alicesatoshis = 100000000;
}
if (strcmp(bobstr, "ETOMIC") == 0) {
swap->I.bobrealsat = swap->I.bobsatoshis;
swap->I.bobsatoshis = 100000000;
}
#endif
if ( (swap->I.bobinsurance= (swap->I.bobsatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE )
swap->I.bobinsurance = LP_MIN_TXFEE;
if ( (swap->I.aliceinsurance= (swap->I.alicesatoshis / INSTANTDEX_INSURANCEDIV)) < LP_MIN_TXFEE )

96
iguana/exchanges/LP_transaction.c

@ -2046,31 +2046,107 @@ char *LP_movecoinbases(char *symbol)
#ifndef NOTETOMIC
char *LP_eth_tx_fee(struct iguana_info *coin, char *dest_addr, char *amount, int64_t gas, int64_t gas_price)
{
bits256 privkey;
cJSON *retjson = cJSON_CreateObject();
int64_t actual_gas_price = 0, actual_gas = 0;
char privkey_str[70];
if (gas_price > 0) {
actual_gas_price = gas_price;
} else {
actual_gas_price = getGasPriceFromStation(0);
if (actual_gas_price == 0) {
return (clonestr("{\"error\":\"Couldn't get gas price from station!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas_price", actual_gas_price);
if (gas > 0) {
actual_gas = gas;
} else if (strcmp(coin->symbol, "ETH") == 0) {
actual_gas = 21000;
} else {
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
actual_gas = estimate_erc20_gas(coin->etomic, dest_addr, amount, privkey_str, coin->decimals);
if (actual_gas == 0) {
return (clonestr("{\"error\":\"Couldn't estimate erc20 transfer gas usage!\"}"));
}
}
cJSON_AddNumberToObject(retjson, "gas", actual_gas);
double_t eth_fee = (actual_gas_price * actual_gas) / 1000000000.0;
cJSON_AddNumberToObject(retjson, "eth_fee", eth_fee);
return(jprint(retjson,1));
}
char *LP_eth_withdraw(struct iguana_info *coin,cJSON *argjson)
{
cJSON *retjson = cJSON_CreateObject();
cJSON *gas_json = cJSON_GetObjectItem(argjson, "gas");
cJSON *gas_price_json = cJSON_GetObjectItem(argjson, "gas_price");
char *dest_addr, *tx_id, privkey_str[70], amount_str[100];
int64_t amount;
int64_t amount = 0, gas = 0, gas_price = 0, broadcast = 0;
bits256 privkey;
dest_addr = jstr(argjson, "to");
if (dest_addr == NULL) {
return(clonestr("{\"error\":\"param 'to' is required!\"}"));
}
amount = jdouble(argjson, "amount") * 100000000;
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
if (amount == 0) {
return(clonestr("{\"error\":\"'amount' is not set or equal to zero!\"}"));
}
if (gas_json != NULL && is_cJSON_Number(gas_json)) {
gas = gas_json->valueint;
if (gas < 21000) {
return (clonestr("{\"error\":\"'gas' can't be lower than 21000!\"}"));
}
}
if (gas_price_json != NULL && is_cJSON_Number(gas_price_json)) {
gas_price = gas_price_json->valueint;
if (gas_price < 1) {
return (clonestr("{\"error\":\"'gas_price' can't be lower than 1!\"}"));
}
}
broadcast = jint(argjson, "broadcast");
satoshisToWei(amount_str, amount);
if (strcmp(coin->symbol, "ETH") == 0) {
tx_id = sendEth(dest_addr, amount_str, privkey_str, 0);
if (broadcast == 1) {
privkey = LP_privkey(coin->symbol, coin->smartaddr, coin->taddr);
uint8arrayToHex(privkey_str, privkey.bytes, 32);
if (strcmp(coin->symbol, "ETH") == 0) {
tx_id = sendEth(dest_addr, amount_str, privkey_str, 0, gas, gas_price, 0);
} else {
tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0, gas, gas_price, 0, coin->decimals);
}
if (tx_id != NULL) {
jaddstr(retjson, "tx_id", tx_id);
free(tx_id);
} else {
jaddstr(retjson, "error", "Error sending transaction");
}
return (jprint(retjson, 1));
} else {
tx_id = sendErc20(coin->etomic, dest_addr, amount_str, privkey_str, 0);
return LP_eth_tx_fee(coin, dest_addr, amount_str, gas, gas_price);
}
jaddstr(retjson, "tx_id", tx_id);
return(jprint(retjson,1));
}
char *LP_eth_gas_price()
{
cJSON *retjson = cJSON_CreateObject();
uint64_t gas_price = getGasPriceFromStation(0);
if (gas_price > 0) {
cJSON_AddNumberToObject(retjson, "gas_price", gas_price);
} else {
cJSON_AddStringToObject(retjson, "error", "Could not get gas price from station!");
}
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;

88
iguana/exchanges/etomicswap/etomiccurl.c

@ -1,7 +1,6 @@
#include "etomiccurl.h"
#include <curl/curl.h>
static char *ethRpcUrl = ETOMIC_URL;
pthread_mutex_t sendTxMutex = PTHREAD_MUTEX_INITIALIZER;
struct string {
@ -36,10 +35,9 @@ size_t writefunc(void *ptr, size_t size, size_t nmemb, struct string *s)
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");
printf("ETH RPC response parse failed: %s!\n", requestResult);
return NULL;
}
cJSON *tmp = cJSON_GetObjectItem(json, "result");
@ -56,7 +54,7 @@ cJSON *parseEthRpcResponse(char *requestResult)
return result;
}
char* sendRequest(char* request)
char* sendRequest(char *request, char *url)
{
CURL *curl;
CURLcode res;
@ -72,13 +70,15 @@ char* sendRequest(char* request)
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &s);
curl_easy_setopt(curl, CURLOPT_URL, ethRpcUrl);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request);
/* 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));
curl_easy_cleanup(curl);
return NULL;
}
/* always cleanup */
@ -98,7 +98,7 @@ cJSON *sendRpcRequest(char *method, cJSON *params)
cJSON_AddItemToObject(request, "params", cJSON_Duplicate(params, 1));
cJSON_AddNumberToObject(request, "id", 1);
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string);
char* requestResult = sendRequest(string, ETOMIC_URL);
free(string);
cJSON_Delete(request);
cJSON *result = parseEthRpcResponse(requestResult);
@ -151,8 +151,8 @@ char* sendRawTx(char* rawTx)
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!
// we should lock this mutex and unlock it only when transaction was already sent or failed.
// make sure that sendRawTx or unlock_send_tx_mutex is called after getting a nonce!
if (pthread_mutex_lock(&sendTxMutex) != 0) {
printf("Nonce mutex lock failed\n");
};
@ -186,7 +186,7 @@ char* getEthBalanceRequest(char* address)
return balance;
}
char* ethCall(char* to, const char* data)
char *ethCall(char *to, const char *data)
{
cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject();
@ -196,7 +196,7 @@ char* ethCall(char* to, const char* data)
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON *resultJson = sendRpcRequest("eth_call", params);
cJSON_Delete(params);
char* result = NULL;
char *result = NULL;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (char *) malloc(strlen(resultJson->valuestring) + 1);
strcpy(result, resultJson->valuestring);
@ -205,6 +205,26 @@ char* ethCall(char* to, const char* data)
return result;
}
uint64_t estimateGas(char *from, char *to, const char *data)
{
cJSON *params = cJSON_CreateArray();
cJSON *txObject = cJSON_CreateObject();
cJSON_AddStringToObject(txObject, "from", from);
cJSON_AddStringToObject(txObject, "to", to);
cJSON_AddStringToObject(txObject, "data", data);
cJSON_AddItemToArray(params, txObject);
cJSON_AddItemToArray(params, cJSON_CreateString("latest"));
cJSON *resultJson = sendRpcRequest("eth_estimateGas", params);
cJSON_Delete(params);
uint64_t result = 0;
if (resultJson != NULL && is_cJSON_String(resultJson) && resultJson->valuestring != NULL) {
result = (uint64_t)strtoul(resultJson->valuestring, NULL, 0);
result = (result / 100) * 120; // add 20% because real gas usage might differ from estimate
}
cJSON_Delete(resultJson);
return result;
}
EthTxReceipt getEthTxReceipt(char *txId)
{
EthTxReceipt result;
@ -265,7 +285,7 @@ EthTxData getEthTxData(char *txId)
return result;
}
uint64_t getGasPriceFromStation()
uint64_t getGasPriceFromStation(uint8_t defaultOnErr)
{
CURL *curl;
CURLcode res;
@ -283,6 +303,12 @@ uint64_t getGasPriceFromStation()
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);
uint64_t result;
if (defaultOnErr == 1) {
result = DEFAULT_GAS_PRICE;
} else {
result = 0;
}
/* Check for errors */
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
@ -292,9 +318,9 @@ uint64_t getGasPriceFromStation()
/* always cleanup */
curl_easy_cleanup(curl);
cJSON *resultJson = cJSON_Parse(s.ptr);
uint64_t result = DEFAULT_GAS_PRICE;
free(s.ptr);
if (resultJson == NULL) {
printf("Could not parse gas station response!\n");
return result;
}
@ -342,3 +368,41 @@ int32_t waitForConfirmation(char *txId)
return((int32_t)receipt.confirmations);
}
void unlock_send_tx_mutex()
{
pthread_mutex_unlock(&sendTxMutex);
}
uint8_t get_etomic_from_faucet(char *eth_addr, char *etomic_addr)
{
char* string;
cJSON *request = cJSON_CreateObject();
cJSON_AddStringToObject(request, "ethAddress", eth_addr);
cJSON_AddStringToObject(request, "etomicAddress", etomic_addr);
string = cJSON_PrintUnformatted(request);
char* requestResult = sendRequest(string, FAUCET_URL);
free(string);
cJSON_Delete(request);
if (requestResult == NULL) {
return 0;
}
cJSON *json = cJSON_Parse(requestResult);
if (json == NULL) {
printf("ETOMIC faucet response parse failed!\n");
return 0;
}
cJSON *error = cJSON_GetObjectItem(json, "error");
uint8_t result = 0;
if (error != NULL && !is_cJSON_Null(error)) {
char *errorString = cJSON_PrintUnformatted(error);
printf("Got ETOMIC faucet error: %s\n", errorString);
free(errorString);
} else {
result = 1;
}
cJSON_Delete(json);
return result;
}

9
iguana/exchanges/etomicswap/etomiccurl.h

@ -16,9 +16,11 @@ extern "C"{
#define DEFAULT_GAS_PRICE 100
#else
#define ETOMIC_URL "http://195.201.0.6:8555"
#define DEFAULT_GAS_PRICE 4
#define DEFAULT_GAS_PRICE 10
#endif
#define FAUCET_URL "http://195.201.116.176:8000/getEtomic"
typedef struct
{
uint64_t blockNumber;
@ -39,13 +41,16 @@ typedef struct
char* sendRawTx(char* rawTx);
char* sendRawTxWaitConfirm(char* rawTx);
char* ethCall(char* to, const char* data);
uint64_t estimateGas(char *from, char *to, const char *data);
int64_t getNonce(char* address);
char* getEthBalanceRequest(char* address);
EthTxReceipt getEthTxReceipt(char *txId);
EthTxData getEthTxData(char *txId);
uint64_t getEthBlockNumber();
uint64_t getGasPriceFromStation();
uint64_t getGasPriceFromStation(uint8_t defaultOnErr);
int32_t waitForConfirmation(char *txId);
void unlock_send_tx_mutex();
uint8_t get_etomic_from_faucet(char *eth_addr, char *etomic_addr);
#ifdef __cplusplus
}

270
iguana/exchanges/etomicswap/etomiclib.cpp

@ -27,18 +27,18 @@ TransactionSkeleton txDataToSkeleton(BasicTxData txData)
tx.to = jsToAddress(txData.to);
tx.value = jsToU256(txData.amount);
tx.gas = 200000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.gasPrice = getGasPriceFromStation(1) * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(txData.from);
return tx;
}
char *signTx(TransactionSkeleton& tx, char* secret)
{
Secret& secretKey = *(new Secret(secret));
auto baseTx = new TransactionBase(tx, secretKey);
RLPStream& rlpStream = *(new RLPStream());
baseTx->streamRLP(rlpStream);
std::stringstream& ss = *(new std::stringstream);
Secret secretKey(secret);
TransactionBase baseTx(tx, secretKey);
RLPStream rlpStream;
baseTx.streamRLP(rlpStream);
std::stringstream ss;
ss << rlpStream.out();
return stringStreamToChar(ss);
}
@ -50,7 +50,7 @@ char *approveErc20(ApproveErc20Input input)
tx.to = jsToAddress(input.tokenAddress);
tx.value = 0;
tx.gas = 300000;
tx.gasPrice = getGasPriceFromStation() * boost::multiprecision::pow(u256(10), 9);
tx.gasPrice = getGasPriceFromStation(1) * boost::multiprecision::pow(u256(10), 9);
tx.nonce = getNonce(input.owner);
std::stringstream ss;
ss << "0x095ea7b3"
@ -101,7 +101,12 @@ uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data)
std::stringstream aliceSendsErc20PaymentData(AliceSendsErc20PaymentInput input)
{
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
u256 amount = jsToU256(input.amount);
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
@ -148,12 +153,20 @@ char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxDat
std::stringstream ss;
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0x8b9a167a"
<< toHex(jsToBytes(input.dealId))
<< toHex(toBigEndian(amount))
@ -179,12 +192,20 @@ char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData
std::stringstream ss;
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
}
ss << "0x392ec66b"
<< toHex(jsToBytes(input.dealId))
<< toHex(toBigEndian(amount))
@ -241,7 +262,13 @@ uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data)
std::stringstream bobSendsErc20DepositData(BobSendsErc20DepositInput input)
{
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
u256 amount = jsToU256(input.amount);
u256 lockTime = input.lockTime;
if (decimals < 18) {
@ -289,7 +316,13 @@ char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData)
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
@ -316,7 +349,13 @@ char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
@ -374,9 +413,15 @@ uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data)
std::stringstream bobSendsErc20PaymentData(BobSendsErc20PaymentInput input)
{
uint8_t decimals = getErc20Decimals(input.tokenAddress);
u256 amount = jsToU256(input.amount);
u256 lockTime = input.lockTime;
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
@ -422,7 +467,13 @@ char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
@ -450,7 +501,13 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData
u256 amount = jsToU256(input.amount);
dev::Address tokenAddress = jsToAddress(input.tokenAddress);
if (tokenAddress != ZeroAddress) {
uint8_t decimals = getErc20Decimals(input.tokenAddress);
uint8_t decimals;
if (input.decimals > 0) {
decimals = input.decimals;
} else {
decimals = getErc20Decimals(input.tokenAddress);
}
if (decimals < 18) {
amount /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
@ -472,24 +529,24 @@ char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData
char* privKey2Addr(char* privKey)
{
Secret& secretKey = *(new Secret(privKey));
std::stringstream& ss = *(new std::stringstream);
Secret secretKey(privKey);
std::stringstream ss;
ss << "0x" << toAddress(secretKey);
return stringStreamToChar(ss);
};
char* pubKey2Addr(char* pubKey)
{
Public& publicKey = *(new Public(pubKey));
std::stringstream& ss = *(new std::stringstream);
Public publicKey(pubKey);
std::stringstream ss;
ss << "0x" << toAddress(publicKey);
return stringStreamToChar(ss);
};
char* getPubKeyFromPriv(char* privKey)
{
Public publicKey = toPublic(*(new Secret(privKey)));
std::stringstream& ss = *(new std::stringstream);
Public publicKey = toPublic(Secret(privKey));
std::stringstream ss;
ss << "0x" << publicKey;
return stringStreamToChar(ss);
}
@ -497,29 +554,42 @@ char* getPubKeyFromPriv(char* privKey)
uint64_t getEthBalance(char* address)
{
char* hexBalance = getEthBalanceRequest(address);
// convert wei to satoshi
u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10);
free(hexBalance);
return static_cast<uint64_t>(balance);
if (hexBalance != NULL) {
// convert wei to satoshi
u256 balance = jsToU256(hexBalance) / boost::multiprecision::pow(u256(10), 10);
free(hexBalance);
return static_cast<uint64_t>(balance);
} else {
return 0;
}
}
uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress)
uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress, uint8_t setDecimals)
{
std::stringstream ss;
ss << "0x70a08231"
<< "000000000000000000000000"
<< toHex(jsToAddress(address));
std::stringstream& resultStream = *(new std::stringstream);
char* hexBalance = ethCall(tokenAddress, ss.str().c_str());
// convert wei to satoshi
uint8_t decimals = getErc20Decimals(tokenAddress);
u256 balance = jsToU256(hexBalance);
if (decimals < 18) {
balance *= boost::multiprecision::pow(u256(10), 18 - decimals);
uint8_t decimals;
if (hexBalance != NULL) {
if (setDecimals > 0) {
decimals = setDecimals;
} else {
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);
} else {
return 0;
}
balance /= boost::multiprecision::pow(u256(10), 10);
free(hexBalance);
return static_cast<uint64_t>(balance);
}
char *getErc20BalanceHexWei(char *address, char *tokenAddress)
@ -532,7 +602,7 @@ char *getErc20BalanceHexWei(char *address, char *tokenAddress)
return hexBalance;
}
uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress)
uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress, uint8_t set_decimals)
{
std::stringstream ss;
ss << "0xdd62ed3e"
@ -541,7 +611,12 @@ uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress)
<< "000000000000000000000000"
<< toHex(jsToAddress(spender));
char* hexAllowance = ethCall(tokenAddress, ss.str().c_str());
uint8_t decimals = getErc20Decimals(tokenAddress);
uint8_t decimals;
if (set_decimals > 0) {
decimals = set_decimals;
} else {
decimals = getErc20Decimals(tokenAddress);
}
u256 allowance = jsToU256(hexAllowance);
if (decimals < 18) {
allowance *= boost::multiprecision::pow(u256(10), 18 - decimals);
@ -582,17 +657,30 @@ uint64_t weiToSatoshi(char *wei)
return static_cast<uint64_t>(satoshi);
}
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm)
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm, int64_t gas, int64_t gasPrice, uint8_t defaultGasOnErr)
{
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);
if (gas > 0) {
tx.gas = gas;
} else {
tx.gas = 21000;
}
if (gasPrice > 0) {
tx.gasPrice = gasPrice * boost::multiprecision::pow(u256(10), 9);
} else {
tx.gasPrice = getGasPriceFromStation(defaultGasOnErr) * boost::multiprecision::pow(u256(10), 9);
if (tx.gasPrice == 0 && !defaultGasOnErr) {
printf("Could not get gas price from station!\n");
unlock_send_tx_mutex();
return NULL;
}
}
char *rawTx = signTx(tx, privKey);
if (waitConfirm == 0) {
@ -604,10 +692,15 @@ char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm)
return result;
}
std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount)
std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amount, uint8_t setDecimals)
{
u256 amountWei = jsToU256(amount);
uint8_t decimals = getErc20Decimals(tokenAddress);
uint8_t decimals;
if (setDecimals > 0) {
decimals = setDecimals;
} else {
decimals = getErc20Decimals(tokenAddress);
}
if (decimals < 18) {
amountWei /= boost::multiprecision::pow(u256(10), 18 - decimals);
}
@ -620,19 +713,64 @@ std::stringstream getErc20TransferData(char *tokenAddress, char *to, char *amoun
return ss;
}
char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8_t waitConfirm)
uint64_t estimate_erc20_gas(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t decimals
)
{
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals);
char *from = privKey2Addr(privKey);
uint64_t result = estimateGas(from, tokenAddress, ss.str().c_str());
free(from);
return result;
}
char *sendErc20(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t waitConfirm,
int64_t gas,
int64_t gasPrice,
uint8_t defaultGasOnErr,
uint8_t decimals
)
{
TransactionSkeleton tx;
char *from = privKey2Addr(privKey), *result;
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals);
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);
if (gas > 0) {
tx.gas = gas;
} else {
uint64_t gasEstimation = estimateGas(from, tokenAddress, ss.str().c_str());
if (gasEstimation > 0) {
tx.gas = gasEstimation;
} else {
tx.gas = 150000;
}
}
free(from);
if (gasPrice > 0) {
tx.gasPrice = gasPrice * boost::multiprecision::pow(u256(10), 9);
} else {
tx.gasPrice = getGasPriceFromStation(defaultGasOnErr) * boost::multiprecision::pow(u256(10), 9);
if (tx.gasPrice == 0 && !defaultGasOnErr) {
printf("Could not get gas price from station!\n");
unlock_send_tx_mutex();
return NULL;
}
}
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount);
tx.data = jsToBytes(ss.str());
char *rawTx = signTx(tx, privKey);
@ -645,12 +783,48 @@ char *sendErc20(char *tokenAddress, char *to, char *amount, char *privKey, uint8
return result;
}
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data)
uint8_t verifyAliceErc20FeeData(char *tokenAddress, char *to, char *amount, char *data, uint8_t decimals)
{
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount);
std::stringstream ss = getErc20TransferData(tokenAddress, to, amount, decimals);
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;
}
uint8_t alicePaymentStatus(char *paymentId)
{
char buffer[100];
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, "0x81cd872a");
strcat(buffer, paymentId);
char *hexStatus = ethCall(ETOMIC_ALICECONTRACT, buffer);
auto status = (uint8_t) strtol(hexStatus + 66, NULL, 0);
free(hexStatus);
return status;
}
uint8_t bobDepositStatus(char *depositId)
{
char buffer[100];
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, "0x3d4dff7b");
strcat(buffer, depositId);
char *hexStatus = ethCall(ETOMIC_BOBCONTRACT, buffer);
auto status = (uint8_t) strtol(hexStatus + 130, NULL, 0);
free(hexStatus);
return status;
}
uint8_t bobPaymentStatus(char *paymentId)
{
char buffer[100];
memset(buffer, 0, sizeof(buffer));
strcpy(buffer, "0x0716326d");
strcat(buffer, paymentId);
char *hexStatus = ethCall(ETOMIC_BOBCONTRACT, buffer);
auto status = (uint8_t) strtol(hexStatus + 130, NULL, 0);
free(hexStatus);
return status;
}

43
iguana/exchanges/etomicswap/etomiclib.h

@ -38,6 +38,7 @@ typedef struct {
char bobAddress[65];
char aliceHash[65];
char bobHash[65];
uint8_t decimals;
} AliceSendsErc20PaymentInput;
typedef struct {
@ -47,6 +48,7 @@ typedef struct {
char bobAddress[65];
char aliceHash[65];
char bobSecret[70];
uint8_t decimals;
} AliceReclaimsAlicePaymentInput;
typedef struct {
@ -56,6 +58,7 @@ typedef struct {
char aliceAddress[65];
char aliceSecret[70];
char bobHash[65];
uint8_t decimals;
} BobSpendsAlicePaymentInput;
typedef struct {
@ -72,6 +75,7 @@ typedef struct {
char aliceAddress[65];
char bobHash[65];
uint64_t lockTime;
uint8_t decimals;
} BobSendsErc20DepositInput;
typedef struct {
@ -80,6 +84,7 @@ typedef struct {
char tokenAddress[65];
char aliceAddress[65];
char bobSecret[70];
uint8_t decimals;
} BobRefundsDepositInput;
typedef struct {
@ -88,6 +93,7 @@ typedef struct {
char tokenAddress[65];
char bobAddress[65];
char bobHash[65];
uint8_t decimals;
} AliceClaimsBobDepositInput;
typedef struct {
@ -104,6 +110,7 @@ typedef struct {
char aliceAddress[65];
char aliceHash[65];
uint64_t lockTime;
uint8_t decimals;
} BobSendsErc20PaymentInput;
typedef struct {
@ -112,6 +119,7 @@ typedef struct {
char tokenAddress[65];
char aliceAddress[65];
char aliceHash[65];
uint8_t decimals;
} BobReclaimsBobPaymentInput;
typedef struct {
@ -120,6 +128,7 @@ typedef struct {
char tokenAddress[65];
char aliceSecret[70];
char bobAddress[65];
uint8_t decimals;
} AliceSpendsBobPaymentInput;
typedef struct {
@ -165,23 +174,45 @@ char* getPubKeyFromPriv(char* privKey);
// returns satoshis, not wei!
uint64_t getEthBalance(char* address);
uint64_t getErc20BalanceSatoshi(char* address, char tokenAddress[65]);
uint64_t getErc20BalanceSatoshi(char *address, char *tokenAddress, uint8_t setDecimals);
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);
uint64_t getErc20Allowance(char *owner, char *spender, char *tokenAddress, uint8_t set_decimals);
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);
char *sendEth(char *to, char *amount, char *privKey, uint8_t waitConfirm, int64_t gas, int64_t gasPrice, uint8_t defaultGasOnErr);
char *sendErc20(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t waitConfirm,
int64_t gas,
int64_t gasPrice,
uint8_t defaultGasOnErr,
uint8_t decimals
);
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data, uint8_t decimals);
uint8_t alicePaymentStatus(char *paymentId);
uint8_t bobDepositStatus(char *depositId);
uint8_t bobPaymentStatus(char *paymentId);
uint64_t estimate_erc20_gas(
char *tokenAddress,
char *to,
char *amount,
char *privKey,
uint8_t decimals
);
uint8_t verifyAliceErc20FeeData(char* tokenAddress, char *to, char *amount, char *data);
// Your prototype or Definition
#ifdef __cplusplus
}
#endif

1
iguana/exchanges/mm.c

@ -164,6 +164,7 @@ int main(int argc, const char * argv[])
{
char dirname[512]; double incr; cJSON *retjson;
OS_init();
printf("BarterDEX Marketmaker %s \n",MM_VERSION);
if ( strstr(argv[0],"btc2kmd") != 0 && argv[1] != 0 )
{
bits256 privkey,checkkey; uint8_t tmptype; char kmdwif[64],str[65],str2[65],*retstr;

60
marketmaker_build_depends.cmd

@ -36,54 +36,66 @@ exit
rem MSBuild /help
echo.
echo Decker will automatically download and build all needed *.dll and *.lib for you ;)
timeout /t 5 /nobreak
mkdir marketmaker_depends
mkdir x64\Release
rem --- pthreads ---
:compile_pthreads
if not exist marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib (
cd marketmaker_depends
git clone https://github.com/DeckerSU/pthread-win32
cd pthread-win32
MSBuild pthread.2015.sln /t:Rebuild /p:Configuration=Release /p:Platform=Win32
MSBuild pthread.2015.sln /t:Rebuild /p:Configuration=Release /p:Platform=x64
cd ../..
)
copy marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib OSlibs\win\x64\pthread_lib.lib
rem --- nanomsg ---
:compile_nanomsg
cd marketmaker_depends
git clone https://github.com/nanomsg/nanomsg
cd nanomsg
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" ..
cmake --build . --config Release --target nanomsg
cd ../../..
if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.lib (
if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.exp (
if not exist marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll (
cd marketmaker_depends
git clone https://github.com/nanomsg/nanomsg
cd nanomsg
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" ..
cmake --build . --config Release --target nanomsg
cd ../../..
)
)
)
copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.lib OSlibs\win\x64\release\nanomsg.lib
copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.exp OSlibs\win\x64\release\nanomsg.exp
copy marketmaker_depends\nanomsg\build_msvc_2015_win64\Release\nanomsg.dll x64\Release\nanomsg.dll
rem --- curl ---
:compile_curl
cd marketmaker_depends
git clone https://github.com/curl/curl
cd curl
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_USE_WINSSL:BOOL=ON ..
cmake --build . --config Release --target libcurl
if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib (
if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.exp (
if not exist marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll (
cd marketmaker_depends
git clone https://github.com/curl/curl
cd curl
mkdir build_msvc_2015_win32
mkdir build_msvc_2015_win64
cd build_msvc_2015_win64
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_USE_WINSSL:BOOL=ON ..
cmake --build . --config Release --target libcurl
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON -DCURL_STATIC_CRT=ON
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB:BOOL=ON -DCURL_STATIC_CRT:BOOL=ON -DHTTP_ONLY:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=RELEASE ..
rem cmake --build . --config Release
rem cmake --build . --config Release --target libcurl
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB=ON -DCURL_DISABLE_LDAP=ON -DCURL_STATIC_CRT=ON
rem cmake .. -G"Visual Studio 14 2015 Win64" -DCURL_STATICLIB:BOOL=ON -DCURL_STATIC_CRT:BOOL=ON -DHTTP_ONLY:BOOL=ON -DCMAKE_BUILD_TYPE:STRING=RELEASE ..
rem cmake --build . --config Release
rem cmake --build . --config Release --target libcurl
cd ../../..
cd ../../..
)
)
)
copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib OSlibs\win\x64\release\libcurl.lib
copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.exp OSlibs\win\x64\release\libcurl.exp
copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl.dll x64\Release\libcurl.dll

7
marketmaker_build_etomic.cmd

@ -7,16 +7,13 @@ copy marketmaker_depends\curl\build_msvc_2015_win64\lib\Release\libcurl_imp.lib
copy marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread_lib.lib marketmaker_depends\pthread-win32\bin\x64_MSVC2015.Release\pthread.lib
echo [#2] Prepare build etomic needed things ...
git submodule init
git submodule update --init --recursive
cd cpp-ethereum
rem git submodule init
rem git submodule update --init
call scripts\install_deps.bat
call scripts\install_deps.bat
cd ..
mkdir build_win64_release
cd build_win64_release
cmake .. -G "Visual Studio 14 2015 Win64"
cmake .. -G "Visual Studio 14 2015 Win64" -DMM_VERSION="%APPVEYOR_BUILD_VERSION%"
rem Steps before build:
rem

12
start_BEER_OTHER_trade.sh

@ -0,0 +1,12 @@
#!/bin/bash
docker-compose exec -T clientnode ./setpassphrase
sleep 5
docker-compose exec -T clientnode ./enable
sleep 5
docker-compose exec -T seednode ./setpassphrase
sleep 5
docker-compose exec -T seednode ./enable
sleep 5
docker-compose exec -T seednode ./sell_BEER_OTHER $1
sleep 5
docker-compose exec -T clientnode ./buy_BEER_OTHER $1

12
start_BEER_OTHER_trade_inverted.sh

@ -0,0 +1,12 @@
#!/bin/bash
docker-compose exec -T clientnode ./setpassphrase
sleep 5
docker-compose exec -T clientnode ./enable
sleep 5
docker-compose exec -T seednode ./setpassphrase
sleep 5
docker-compose exec -T seednode ./enable
sleep 5
docker-compose exec -T clientnode ./buy_BEER_OTHER $1
sleep 5
docker-compose exec -T seednode ./sell_BEER_OTHER $1
Loading…
Cancel
Save