Browse Source

Add ETH tx validations. Add automatic ERC20 approve.

patch-3
Artem Pikulin 7 years ago
parent
commit
fe42ebff03
  1. 220
      iguana/exchanges/LP_etomic.c
  2. 12
      iguana/exchanges/LP_transaction.c
  3. 20
      iguana/exchanges/etomicswap/bob.c
  4. 160
      iguana/exchanges/etomicswap/etomiclib.cpp
  5. 41
      iguana/exchanges/etomicswap/etomiclib.h

220
iguana/exchanges/LP_etomic.c

@ -25,6 +25,30 @@
#include "etomicswap/etomiccurl.h" #include "etomicswap/etomiccurl.h"
#include <inttypes.h> #include <inttypes.h>
int32_t LP_etomic_wait_for_confirmation(char *txId)
{
EthTxReceipt receipt;
EthTxData txData;
do {
sleep(15);
printf("waiting for ETH txId to be confirmed: %s\n", txId);
receipt = getEthTxReceipt(txId);
if (receipt.confirmations < 1) {
txData = getEthTxData(txId);
if (txData.exists == 0) {
return(-1);
}
}
} while (receipt.confirmations < 1);
if (strcmp(receipt.status, "0x1") != 0) {
printf("ETH txid %s receipt status failed\n", txId);
return(-1);
}
return(receipt.confirmations);
}
char *LP_etomicalice_send_payment(struct basilisk_swap *swap) char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
{ {
AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData; AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData;
@ -60,10 +84,71 @@ char *LP_etomicalice_send_payment(struct basilisk_swap *swap)
strcpy(txData.to, ETOMIC_ALICECONTRACT); strcpy(txData.to, ETOMIC_ALICECONTRACT);
strcpy(txData.amount, "0"); strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
uint64_t allowance = getErc20Allowance(swap->I.etomicsrc, 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.etomicsrc);
strcpy(approveErc20Input.spender, ETOMIC_ALICECONTRACT);
// hard code for now
strcpy(approveErc20Input.amount, "20000000000000000000");
strcpy(approveErc20Input.secret, txData.secretKey);
char *allowTxId = approveErc20(approveErc20Input);
LP_etomic_wait_for_confirmation(allowTxId);
free(allowTxId);
}
return(aliceSendsErc20Payment(input20,txData)); return(aliceSendsErc20Payment(input20,txData));
} }
} }
uint8_t LP_etomic_verify_alice_payment(struct basilisk_swap *swap, char *txId)
{
EthTxData data = getEthTxData(txId);
if (data.exists == 0 || strcmp(data.to, ETOMIC_ALICECONTRACT) != 0 || strcmp(data.from, swap->I.etomicdest) != 0) {
return 0;
}
AliceSendsEthPaymentInput input; AliceSendsErc20PaymentInput input20; BasicTxData txData;
// set input and txData fields from the swap data structure
memset(&txData,0,sizeof(txData));
if ( strcmp(swap->I.alicestr,"ETH") == 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);
strcpy(txData.from, swap->I.etomicdest);
strcpy(txData.to, ETOMIC_ALICECONTRACT);
satoshisToWei(txData.amount, swap->I.alicesatoshis);
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return(verifyAliceEthPaymentData(input, data.input));
}
else
{
memset(&input20,0,sizeof(input20));
strcpy(input20.bobAddress, swap->I.etomicdest);
uint8arrayToHex(input20.bobHash, swap->I.secretBn, 20);
uint8arrayToHex(input20.aliceHash, swap->I.secretAm, 20);
uint8arrayToHex(input20.dealId, swap->alicepayment.utxotxid.bytes, 32);
strcpy(input20.tokenAddress, swap->I.alicetomic);
satoshisToWei(input20.amount, swap->I.alicesatoshis);
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_ALICECONTRACT);
strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return(verifyAliceErc20PaymentData(input20, data.input));
}
}
char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap) char *LP_etomicalice_reclaims_payment(struct LP_swap_remember *swap)
{ {
AliceReclaimsAlicePaymentInput input; AliceReclaimsAlicePaymentInput input;
@ -166,10 +251,65 @@ char *LP_etomicbob_sends_deposit(struct basilisk_swap *swap)
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0"); strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); 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);
// hard code for now
strcpy(approveErc20Input.amount, "20000000000000000000");
strcpy(approveErc20Input.secret, txData.secretKey);
char *allowTxId = approveErc20(approveErc20Input);
LP_etomic_wait_for_confirmation(allowTxId);
free(allowTxId);
}
return bobSendsErc20Deposit(input20, txData); return bobSendsErc20Deposit(input20, txData);
} }
} }
uint8_t LP_etomic_verify_bob_deposit(struct basilisk_swap *swap, char *txId)
{
EthTxData data = getEthTxData(txId);
if (data.exists == 0 || strcmp(data.to, ETOMIC_BOBCONTRACT) != 0 || strcmp(data.from, swap->I.etomicsrc) != 0) {
return 0;
}
BobSendsEthDepositInput input;
BobSendsErc20DepositInput input20;
BasicTxData txData;
memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input));
memset(&input20,0,sizeof(input20));
if ( strcmp(swap->I.bobstr,"ETH") == 0 ) {
uint8arrayToHex(input.depositId, swap->bobdeposit.I.actualtxid.bytes, 32);
strcpy(input.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input.bobHash, swap->I.secretBn, 20);
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
satoshisToWei(txData.amount, swap->bobdeposit.I.amount);
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
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);
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return verifyBobErc20DepositData(input20, data.input);
}
}
char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap) char *LP_etomicbob_refunds_deposit(struct LP_swap_remember *swap)
{ {
BobRefundsDepositInput input; BobRefundsDepositInput input;
@ -238,10 +378,66 @@ char *LP_etomicbob_sends_payment(struct basilisk_swap *swap)
strcpy(txData.to, ETOMIC_BOBCONTRACT); strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0"); strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32); 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);
// hard code for now
strcpy(approveErc20Input.amount, "20000000000000000000");
strcpy(approveErc20Input.secret, txData.secretKey);
char *allowTxId = approveErc20(approveErc20Input);
LP_etomic_wait_for_confirmation(allowTxId);
free(allowTxId);
}
return bobSendsErc20Payment(input20, txData); return bobSendsErc20Payment(input20, txData);
} }
} }
uint8_t LP_etomic_verify_bob_payment(struct basilisk_swap *swap, char *txId)
{
EthTxData data = getEthTxData(txId);
if (data.exists == 0 || strcmp(data.to, ETOMIC_BOBCONTRACT) != 0 || strcmp(data.from, swap->I.etomicsrc) != 0) {
return 0;
}
BobSendsEthPaymentInput input;
BobSendsErc20PaymentInput input20;
BasicTxData txData;
memset(&txData,0,sizeof(txData));
memset(&input,0,sizeof(input));
memset(&input20,0,sizeof(input20));
if ( strcmp(swap->I.bobstr,"ETH") == 0 ) {
uint8arrayToHex(input.paymentId, swap->bobpayment.I.actualtxid.bytes, 32);
strcpy(input.aliceAddress, swap->I.etomicdest);
uint8arrayToHex(input.aliceHash, swap->I.secretAm, 20);
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
satoshisToWei(txData.amount, swap->bobpayment.I.amount);
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
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);
strcpy(txData.from, swap->I.etomicsrc);
strcpy(txData.to, ETOMIC_BOBCONTRACT);
strcpy(txData.amount, "0");
uint8arrayToHex(txData.secretKey, swap->persistent_privkey.bytes, 32);
return verifyBobErc20PaymentData(input20, data.input);
}
}
char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap) char *LP_etomicbob_reclaims_payment(struct LP_swap_remember *swap)
{ {
BobReclaimsBobPaymentInput input; BobReclaimsBobPaymentInput input;
@ -405,26 +601,10 @@ int32_t LP_etomic_pub2addr(char *coinaddr,uint8_t pub64[64])
return(-1); return(-1);
} }
int32_t LP_etomic_wait_for_confirmation(char *txId) uint8_t LP_etomic_is_empty_tx_id(char *txId)
{ {
EthTxReceipt receipt; if (strcmp(txId, EMPTY_ETH_TX_ID) == 0) {
EthTxData txData; return 1;
do {
sleep(15);
printf("waiting for ETH txId to be confirmed: %s\n", txId);
receipt = getEthTxReceipt(txId);
if (receipt.confirmations < 1) {
txData = getEthTxData(txId);
if (txData.exists == 0) {
return(-1);
} }
} return 0;
} while (receipt.confirmations < 1);
if (strcmp(receipt.status, "0x1") != 0) {
printf("ETH txid %s receipt status failed\n", txId);
return(-1);
}
return(receipt.confirmations);
} }

12
iguana/exchanges/LP_transaction.c

@ -2206,7 +2206,7 @@ int32_t LP_verify_bobdeposit(struct basilisk_swap *swap,uint8_t *data,int32_t da
//basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration); //basilisk_txlog(swap,&swap->aliceclaim,swap->I.putduration+swap->I.callduration);
#ifndef NOTETOMIC #ifndef NOTETOMIC
if (swap->bobdeposit.I.ethTxid[0] != 0) { if (swap->bobdeposit.I.ethTxid[0] != 0) {
if (LP_etomic_wait_for_confirmation(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); return(-1);
} }
} }
@ -2235,8 +2235,8 @@ int32_t LP_verify_alicepayment(struct basilisk_swap *swap,uint8_t *data,int32_t
swap->aliceunconf = 1; swap->aliceunconf = 1;
basilisk_dontforget_update(swap,&swap->alicepayment); basilisk_dontforget_update(swap,&swap->alicepayment);
#ifndef NOTETOMIC #ifndef NOTETOMIC
if (swap->alicepayment.I.ethTxid[0] != 0) { if (swap->alicepayment.I.ethTxid[0] != 0 && LP_etomic_is_empty_tx_id(swap->alicepayment.I.ethTxid) == 0) {
if (LP_etomic_wait_for_confirmation(swap->alicepayment.I.ethTxid) < 0) { if (LP_etomic_wait_for_confirmation(swap->alicepayment.I.ethTxid) < 0 || LP_etomic_verify_alice_payment(swap, swap->alicepayment.I.ethTxid) == 0) {
return(-1); return(-1);
} }
} }
@ -2294,9 +2294,9 @@ int32_t LP_verify_bobpayment(struct basilisk_swap *swap,uint8_t *data,int32_t da
bitcoin_address(coin->symbol,swap->alicespend.I.destaddr,coin->taddr,coin->pubtype,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])); //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 #ifndef NOTETOMIC
if (swap->bobpayment.I.ethTxid[0] != 0) { 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) { if (LP_etomic_wait_for_confirmation(swap->bobpayment.I.ethTxid) < 0 || LP_etomic_verify_bob_payment(swap, swap->bobpayment.I.ethTxid) == 0) {
return (-1); return(-1);
} }
} }
#endif #endif

20
iguana/exchanges/etomicswap/bob.c

@ -220,12 +220,14 @@ int main(int argc, char** argv)
} }
break; break;
case BOB_APPROVES_ERC20: case BOB_APPROVES_ERC20:
result = approveErc20( printf("approving erc20\n");
"10000000000000000000", ApproveErc20Input input8;
"0xA7EF3f65714AE266414C9E58bB4bAa4E6FB82B41", strcpy(input8.amount, "20000000000000000000");
getenv("BOB_PK") strcpy(input8.spender, bobContractAddress);
strcpy(input8.owner, bobAddress);
); strcpy(input8.tokenAddress, tokenAddress);
strcpy(input8.secret, getenv("BOB_PK"));
result = approveErc20(input8);
if (result != NULL) { if (result != NULL) {
printf("%s\n", result); printf("%s\n", result);
free(result); free(result);
@ -270,5 +272,11 @@ int main(int argc, char** argv)
satoshisToWei(weiBuffer, satoshis); satoshisToWei(weiBuffer, satoshis);
printf("wei: %s\n", weiBuffer); 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);
return 0; return 0;
} }

160
iguana/exchanges/etomicswap/etomiclib.cpp

@ -12,7 +12,7 @@
using namespace dev; using namespace dev;
using namespace dev::eth; using namespace dev::eth;
char* stringStreamToChar(std::stringstream& ss) char *stringStreamToChar(std::stringstream& ss)
{ {
const std::string tmp = ss.str(); const std::string tmp = ss.str();
auto result = (char*)malloc(strlen(tmp.c_str()) + 1); auto result = (char*)malloc(strlen(tmp.c_str()) + 1);
@ -32,7 +32,7 @@ TransactionSkeleton txDataToSkeleton(BasicTxData txData)
return tx; return tx;
} }
char* signTx(TransactionSkeleton& tx, char* secret) char *signTx(TransactionSkeleton& tx, char* secret)
{ {
Secret& secretKey = *(new Secret(secret)); Secret& secretKey = *(new Secret(secret));
auto baseTx = new TransactionBase(tx, secretKey); auto baseTx = new TransactionBase(tx, secretKey);
@ -43,30 +43,29 @@ char* signTx(TransactionSkeleton& tx, char* secret)
return stringStreamToChar(ss); return stringStreamToChar(ss);
} }
char* approveErc20(char* amount, char* from, char* secret) char *approveErc20(ApproveErc20Input input)
{ {
TransactionSkeleton tx; TransactionSkeleton tx;
tx.from = jsToAddress(from); tx.from = jsToAddress(input.owner);
tx.to = jsToAddress("0xc0eb7AeD740E1796992A08962c15661bDEB58003"); tx.to = jsToAddress(input.tokenAddress);
tx.value = 0; // exp10<18>(); tx.value = 0;
tx.gas = 300000; tx.gas = 300000;
tx.gasPrice = ETOMIC_GASMULT * exp10<9>(); tx.gasPrice = ETOMIC_GASMULT * exp10<9>();
tx.nonce = getNonce(from); tx.nonce = getNonce(input.owner);
std::stringstream ss; std::stringstream ss;
ss << "0x095ea7b3" ss << "0x095ea7b3"
<< "000000000000000000000000" << "000000000000000000000000"
<< toHex(jsToAddress("0xe1D4236C5774D35Dc47dcc2E5E0CcFc463A3289c")) << toHex(jsToAddress(input.spender))
<< toHex(toBigEndian(jsToU256(amount))); << toHex(toBigEndian(jsToU256(input.amount)));
tx.data = jsToBytes(ss.str()); tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, secret); char* rawTx = signTx(tx, input.secret);
char* result = sendRawTx(rawTx); char* result = sendRawTx(rawTx);
free(rawTx); free(rawTx);
return result; return result;
} }
char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData) std::stringstream aliceSendsEthPaymentData(AliceSendsEthPaymentInput input)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss; std::stringstream ss;
ss << "0x47c7b6e2" ss << "0x47c7b6e2"
<< toHex(jsToBytes(input.dealId)) << toHex(jsToBytes(input.dealId))
@ -76,6 +75,13 @@ char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData)
<< "000000000000000000000000" << "000000000000000000000000"
<< toHex(jsToBytes(input.bobHash)) << toHex(jsToBytes(input.bobHash))
<< "000000000000000000000000"; << "000000000000000000000000";
return ss;
}
char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = aliceSendsEthPaymentData(input);
tx.data = jsToBytes(ss.str()); tx.data = jsToBytes(ss.str());
char *rawTx = signTx(tx, txData.secretKey); char *rawTx = signTx(tx, txData.secretKey);
char *result = sendRawTx(rawTx); char *result = sendRawTx(rawTx);
@ -83,9 +89,17 @@ char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData)
return result; return result;
} }
char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData) uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data)
{
std::stringstream ss = aliceSendsEthPaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
return 0;
}
return 1;
}
std::stringstream aliceSendsErc20PaymentData(AliceSendsErc20PaymentInput input)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss; std::stringstream ss;
ss << "0x184db3bf" ss << "0x184db3bf"
<< toHex(jsToBytes(input.dealId)) << toHex(jsToBytes(input.dealId))
@ -98,6 +112,13 @@ char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txDa
<< "000000000000000000000000" << "000000000000000000000000"
<< "000000000000000000000000" << "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress)); << 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()); tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey); char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx); char* result = sendRawTx(rawTx);
@ -105,6 +126,15 @@ char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txDa
return result; return result;
} }
uint8_t verifyAliceErc20PaymentData(AliceSendsErc20PaymentInput input, char *data)
{
std::stringstream ss = aliceSendsErc20PaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
return 0;
}
return 1;
}
char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData) char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData); TransactionSkeleton tx = txDataToSkeleton(txData);
@ -151,9 +181,8 @@ char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData
return result; return result;
} }
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData) std::stringstream bobSendsEthDepositData(BobSendsEthDepositInput input)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss; std::stringstream ss;
ss << "0xc2c5143f" ss << "0xc2c5143f"
<< toHex(jsToBytes(input.depositId)) << toHex(jsToBytes(input.depositId))
@ -161,6 +190,13 @@ char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData)
<< toHex(jsToAddress(input.aliceAddress)) << toHex(jsToAddress(input.aliceAddress))
<< toHex(jsToBytes(input.bobHash)) << toHex(jsToBytes(input.bobHash))
<< "000000000000000000000000"; << "000000000000000000000000";
return ss;
}
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsEthDepositData(input);
tx.data = jsToBytes(ss.str()); tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey); char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx); char* result = sendRawTx(rawTx);
@ -168,9 +204,17 @@ char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData)
return result; return result;
} }
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData) uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data)
{
std::stringstream ss = bobSendsEthDepositData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
return 0;
}
return 1;
}
std::stringstream bobSendsErc20DepositData(BobSendsErc20DepositInput input)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss; std::stringstream ss;
ss << "0xce8bbe4b" ss << "0xce8bbe4b"
<< toHex(jsToBytes(input.depositId)) << toHex(jsToBytes(input.depositId))
@ -181,6 +225,13 @@ char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData)
<< "000000000000000000000000" << "000000000000000000000000"
<< "000000000000000000000000" << "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress)); << toHex(jsToAddress(input.tokenAddress));
return ss;
}
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsErc20DepositData(input);
tx.data = jsToBytes(ss.str()); tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey); char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx); char* result = sendRawTx(rawTx);
@ -188,6 +239,15 @@ char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData)
return result; return result;
} }
uint8_t verifyBobErc20DepositData(BobSendsErc20DepositInput input, char *data)
{
std::stringstream ss = bobSendsErc20DepositData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
return 0;
}
return 1;
}
char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData) char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData); TransactionSkeleton tx = txDataToSkeleton(txData);
@ -231,9 +291,8 @@ char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData
return result; return result;
} }
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData) std::stringstream bobSendsEthPaymentData(BobSendsEthPaymentInput input)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss; std::stringstream ss;
ss << "0xcf36fe8e" ss << "0xcf36fe8e"
<< toHex(jsToBytes(input.paymentId)) << toHex(jsToBytes(input.paymentId))
@ -241,6 +300,13 @@ char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData)
<< toHex(jsToAddress(input.aliceAddress)) << toHex(jsToAddress(input.aliceAddress))
<< toHex(jsToBytes(input.aliceHash)) << toHex(jsToBytes(input.aliceHash))
<< "000000000000000000000000"; << "000000000000000000000000";
return ss;
}
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsEthPaymentData(input);
tx.data = jsToBytes(ss.str()); tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey); char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx); char* result = sendRawTx(rawTx);
@ -248,9 +314,17 @@ char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData)
return result; return result;
} }
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData) uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data)
{
std::stringstream ss = bobSendsEthPaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
return 0;
}
return 1;
}
std::stringstream bobSendsErc20PaymentData(BobSendsErc20PaymentInput input)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss; std::stringstream ss;
ss << "0x34f64dfd" ss << "0x34f64dfd"
<< toHex(jsToBytes(input.paymentId)) << toHex(jsToBytes(input.paymentId))
@ -261,6 +335,13 @@ char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData)
<< "000000000000000000000000" << "000000000000000000000000"
<< "000000000000000000000000" << "000000000000000000000000"
<< toHex(jsToAddress(input.tokenAddress)); << toHex(jsToAddress(input.tokenAddress));
return ss;
}
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData)
{
TransactionSkeleton tx = txDataToSkeleton(txData);
std::stringstream ss = bobSendsErc20PaymentData(input);
tx.data = jsToBytes(ss.str()); tx.data = jsToBytes(ss.str());
char* rawTx = signTx(tx, txData.secretKey); char* rawTx = signTx(tx, txData.secretKey);
char* result = sendRawTx(rawTx); char* result = sendRawTx(rawTx);
@ -268,6 +349,15 @@ char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData)
return result; return result;
} }
uint8_t verifyBobErc20PaymentData(BobSendsErc20PaymentInput input, char *data)
{
std::stringstream ss = bobSendsErc20PaymentData(input);
if (strcmp(ss.str().c_str(), data) != 0) {
return 0;
}
return 1;
}
char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData) char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData)
{ {
TransactionSkeleton tx = txDataToSkeleton(txData); TransactionSkeleton tx = txDataToSkeleton(txData);
@ -344,7 +434,7 @@ uint64_t getEthBalance(char* address)
return static_cast<uint64_t>(balance); return static_cast<uint64_t>(balance);
} }
uint64_t getErc20Balance(char* address, char* tokenAddress) uint64_t getErc20Balance(char *address, char *tokenAddress)
{ {
std::stringstream ss; std::stringstream ss;
ss << "0x70a08231" ss << "0x70a08231"
@ -358,6 +448,30 @@ uint64_t getErc20Balance(char* address, char* tokenAddress)
return static_cast<uint64_t>(balance); return static_cast<uint64_t>(balance);
} }
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());
// convert wei to satoshi
u256 allowance = jsToU256(hexAllowance) / exp10<10>();
free(hexAllowance);
return static_cast<uint64_t>(allowance);
}
uint8_t getErc20Decimals(char *tokenAddress)
{
char* hexDecimals = ethCall(tokenAddress, "0x313ce567");
// convert wei to satoshi
auto decimals = (uint8_t) strtol(hexDecimals, NULL, 0);
free(hexDecimals);
return decimals;
}
void uint8arrayToHex(char *dest, uint8_t *input, int len) void uint8arrayToHex(char *dest, uint8_t *input, int len)
{ {
strcpy(dest, "0x"); strcpy(dest, "0x");

41
iguana/exchanges/etomicswap/etomiclib.h

@ -9,8 +9,8 @@ extern "C" {
#define ETOMIC_TESTNET #define ETOMIC_TESTNET
#ifdef ETOMIC_TESTNET #ifdef ETOMIC_TESTNET
#define ETOMIC_ALICECONTRACT "0xe1D4236C5774D35Dc47dcc2E5E0CcFc463A3289c" #define ETOMIC_ALICECONTRACT "0xe1d4236c5774d35dc47dcc2e5e0ccfc463a3289c"
#define ETOMIC_BOBCONTRACT "0x9387Fd3a016bB0205e4e131Dde886B9d2BC000A2" #define ETOMIC_BOBCONTRACT "0x9387fd3a016bb0205e4e131dde886b9d2bc000a2"
#define ETOMIC_GASMULT 100 #define ETOMIC_GASMULT 100
#else #else
#define ETOMIC_ALICECONTRACT "0x9bC5418CEdED51dB08467fc4b62F32C5D9EBdA55" #define ETOMIC_ALICECONTRACT "0x9bC5418CEdED51dB08467fc4b62F32C5D9EBdA55"
@ -18,7 +18,7 @@ extern "C" {
#define ETOMIC_GASMULT 4 #define ETOMIC_GASMULT 4
#endif #endif
#define ETOMIC_SATOSHICAT "0000000000" #define EMPTY_ETH_TX_ID "0x0000000000000000000000000000000000000000000000000000000000000000"
typedef struct { typedef struct {
char from[65]; char from[65];
@ -125,24 +125,57 @@ typedef struct {
char bobCanClaimAfter[100]; char bobCanClaimAfter[100];
} AliceSpendsBobPaymentInput; } 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); char* aliceSendsEthPayment(AliceSendsEthPaymentInput input, BasicTxData txData);
uint8_t verifyAliceEthPaymentData(AliceSendsEthPaymentInput input, char *data);
char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData); char* aliceSendsErc20Payment(AliceSendsErc20PaymentInput input, BasicTxData txData);
uint8_t verifyAliceErc20PaymentData(AliceSendsErc20PaymentInput input, char *data);
char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData); char* aliceReclaimsAlicePayment(AliceReclaimsAlicePaymentInput input, BasicTxData txData);
char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData); char* bobSpendsAlicePayment(BobSpendsAlicePaymentInput input, BasicTxData txData);
char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData); char* bobSendsEthDeposit(BobSendsEthDepositInput input, BasicTxData txData);
uint8_t verifyBobEthDepositData(BobSendsEthDepositInput input, char *data);
char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData); char* bobSendsErc20Deposit(BobSendsErc20DepositInput input, BasicTxData txData);
uint8_t verifyBobErc20DepositData(BobSendsErc20DepositInput input, char *data);
char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData); char* bobRefundsDeposit(BobRefundsDepositInput input, BasicTxData txData);
char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData); char* aliceClaimsBobDeposit(AliceClaimsBobDepositInput input, BasicTxData txData);
char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData); char* bobSendsEthPayment(BobSendsEthPaymentInput input, BasicTxData txData);
uint8_t verifyBobEthPaymentData(BobSendsEthPaymentInput input, char *data);
char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData); char* bobSendsErc20Payment(BobSendsErc20PaymentInput input, BasicTxData txData);
uint8_t verifyBobErc20PaymentData(BobSendsErc20PaymentInput input, char *data);
char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData); char* bobReclaimsBobPayment(BobReclaimsBobPaymentInput input, BasicTxData txData);
char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData); char* aliceSpendsBobPayment(AliceSpendsBobPaymentInput input, BasicTxData txData);
char* privKey2Addr(char* privKey); char* privKey2Addr(char* privKey);
char* pubKey2Addr(char* pubKey); char* pubKey2Addr(char* pubKey);
char* getPubKeyFromPriv(char* privKey); char* getPubKeyFromPriv(char* privKey);
// returns satoshis, not wei!
uint64_t getEthBalance(char* address); uint64_t getEthBalance(char* address);
// returns satoshis, not wei!
uint64_t getErc20Balance(char* address, char tokenAddress[65]); uint64_t getErc20Balance(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 uint8arrayToHex(char *dest, uint8_t *input, int len);
void satoshisToWei(char *dest, uint64_t input); void satoshisToWei(char *dest, uint64_t input);
// Your prototype or Definition // Your prototype or Definition

Loading…
Cancel
Save